blob: 6f2298ba5d7a404d576f6e312688bbf92bab835b [file] [log] [blame]
b.liu68a94c92025-05-24 12:53:41 +08001#include <stdio.h>
2#include <string.h>
3#include <strings.h>
4#include <stdlib.h>
5#include <errno.h>
6#include <fcntl.h>
7#include <signal.h>
8#include <sys/types.h>
9#include <unistd.h>
10#include <pthread.h>
11#include <termios.h>
12#include <time.h>
13#include <sys/ioctl.h>
14#include <dlfcn.h>
15#include <stdint.h>
16#include <stdbool.h>
17
18#include "gsw_gnss.h"
19
20#ifndef LOG_ERR_LEVEL
21#define LOG_ERR_LEVEL 3 /* error conditions */
22#endif
23#ifndef LOG_WARN_LEVEL
24#define LOG_WARN_LEVEL 4 /* warning conditions */
25#endif
26#ifndef LOG_INFO_LEVEL
27#define LOG_INFO_LEVEL 6 /* informational */
28#endif
29#ifndef LOG_DEBUG_LEVEL
30#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
31#endif
32#ifndef LOG_VERBOSE_LEVEL
33#define LOG_VERBOSE_LEVEL 8
34#endif
35
l.yang6a42e4d2025-05-28 01:04:20 -070036#define GSW_GNSS "[HAL][GSW_GNSS]"
37
38
b.liu68a94c92025-05-24 12:53:41 +080039#define LOGV(fmt, args ...) \
40 do{ \
41 char *file_ptr_1001 = __FILE__; \
42 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
43 char line_1001[10] = {0}; \
44 sprintf(line_1001, "%d", __LINE__); \
45 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
46 if(*ptr_1001 == '/') \
47 break; \
48 ptr_1001--; \
49 } \
l.yang6a42e4d2025-05-28 01:04:20 -070050 fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080051 } while(0)
52
53#define LOGI(fmt, args...) \
54 do{ \
55 char *file_ptr_1001 = __FILE__; \
56 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
57 char line_1001[10] = {0}; \
58 sprintf(line_1001, "%d", __LINE__); \
59 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
60 if(*ptr_1001 == '/') \
61 break; \
62 ptr_1001--; \
63 } \
l.yang6a42e4d2025-05-28 01:04:20 -070064 fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080065 } while(0)
66
67#define LOGD(fmt, args...) \
68 do{ \
69 char *file_ptr_1001 = __FILE__; \
70 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
71 char line_1001[10] = {0}; \
72 sprintf(line_1001, "%d", __LINE__); \
73 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
74 if(*ptr_1001 == '/') \
75 break; \
76 ptr_1001--; \
77 } \
l.yang6a42e4d2025-05-28 01:04:20 -070078 fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080079 } while(0)
80
81#define LOGW(fmt, args...) \
82 do{ \
83 char *file_ptr_1001 = __FILE__; \
84 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
85 char line_1001[10] = {0}; \
86 sprintf(line_1001, "%d", __LINE__); \
87 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
88 if(*ptr_1001 == '/') \
89 break; \
90 ptr_1001--; \
91 } \
l.yang6a42e4d2025-05-28 01:04:20 -070092 fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080093 } while(0)
94
95#define LOGE(fmt, args...) \
96 do{ \
97 char *file_ptr_1001 = __FILE__; \
98 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
99 char line_1001[10] = {0}; \
100 sprintf(line_1001, "%d", __LINE__); \
101 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
102 if(*ptr_1001 == '/') \
103 break; \
104 ptr_1001--; \
105 } \
l.yang6a42e4d2025-05-28 01:04:20 -0700106 fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +0800107 } while(0)
108
109
110#define GSW_HAL_SUCCESS 0
111#define GSW_HAL_FAIL -1 //表示失败(通用性)
112#define GSW_HAL_MEM_INVAILD -2 //表示入参地址为NULL
113
114#define MOPEN_GNSS_NMEA_MAX_LENGTH 255 /** NMEA string maximum length. */
115static gsw_gnss_cb *gsw_cb = NULL;
116static bool inited = false;
117static bool strated = false;
118
119typedef void (*mbtk_gnss_callback_func)(uint32_t ind_type, const void* data, uint32_t data_len);
120typedef void (*mbtk_log)(int level, const char *format,...);
121static mbtk_log fun_ptr_log = NULL;
122
123int (*mbtk_gnss_init)(mbtk_gnss_callback_func cb);
124int (*mbtk_gnss_deinit)();
125
126int (*mbtk_gnss_ind_set)(uint32_t ,int);
127int (*mbtk_gnss_open)(int, int);
128int (*mbtk_gnss_close)(int);
129int (*mbtk_gnss_setting)(const char *setting_cmd, int);
130
131int (*mbtk_gnss_eph_download)(int);
132int (*mbtk_gnss_eph_inject)(int);
133
134int gnss_freq = -1;
135GSW_GNSS_MODE_CONFIGURATION gnss_startmode = -1;
136GSW_GNSS_CONF_SWITCH gnss_switch_op = -1;
137void *dlHandle_gnss;
138char *lynqLib_gnss = "/lib/libmbtk_lib.so";
139
140typedef enum
141{
142 E_MT_LOC_MSG_ID_LOCATION_INFO = 1, /**< pv_data = & mopen_location_info_t */
143 E_MT_LOC_MSG_ID_NMEA_INFO = 3, /**< pv_data = & mopen_gnss_nmea_info_t */
144} e_msg_id_t;
145
146typedef struct
147{
148 int64_t timestamp; /**< System Timestamp, marked for when got the nmea data */
149 int length; /**< NMEA string length. */
150 char nmea[MOPEN_GNSS_NMEA_MAX_LENGTH + 1]; /**< NMEA string.*/
151}mopen_gnss_nmea_info_t; /* Message */
152
153typedef struct
154{
155 uint32_t size; /**< Set to the size of mcm_gps_location_t. */
156 int flags; /**< Contains GPS location flags bits. */
157 int position_source; /**< Provider indicator for HYBRID or GPS. */ //功能暂未实现,可不用添加进结构体
158 double latitude; /**< Latitude in degrees. */
159 double longitude; /**< Longitude in degrees. */
160 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
161 float speed; /**< Speed in meters per second. */
162 float bearing; /**< Heading in degrees. */ //功能暂未实现,可不用添加进结构体
163 float accuracy; /**< Expected accuracy in meters. */ //功能暂未实现,可不用添加进结构体
164 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
165 int32_t is_indoor; /**< Location is indoors. */ //功能暂未实现,可不用添加进结构体
166 float floor_number; /**< Indicates the floor number. */
167}mopen_location_info_t;//功能暂未实现,可不用添加进结构体
168
169
170typedef struct {
171 uint32_t flags;
172 double latitude; /**< Latitude in degrees. */
173 double longitude; /**< Longitude in degrees. */
174 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
175 float speed; /**< Speed in meters per second. */
176 float bearing; /**< Heading in degrees. */
177 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
178} mbtk_gnss_location_info_t;
179
180typedef enum{
181 MODE_GPS = 1, /**< GPS only */
182 MODE_BEIDOU, /**< BEIDOU only*/
183 MODE_GPS_BEIDOU, /**< GPS+BEIDOU */
184 MODE_GLONASS, /**< GLONASS only */
185 MODE_GPS_GLONASS, /**< GPS+GLONASS */
186 MODE_GLONASS_BEIDOU, /**< GLONASS+BEIDOU */ /* The type does not support this type */
187 MODE_GPS_GLONASS_BEIDOU, /**< GPS+GLONASS+BEIDOU */ /* The type does not support this type */
188 MODE_GALILEO, /**< GALILEO only */
189 MODE_GPS_GALILEO, /**< GPS+GALILEO */
190 MODE_BEIDOU_GALILEO, /**< BEIDOU+GALILEO */
191 MODE_GPS_BEIDOU_GALILEO, /**< GPS+BEIDOU+GALILEO */
192 MODE_GLONASS_GALILEO, /**< GLONASS+GALILEO */
193 MODE_GPS_GLONASS_GALILEO, /**< GPS+GLONASS+GALILEO */
194 MODE_BEIDOU_GLONASS_GALILEO, /**< BEIDOU+GLONASS+GALILEO */ /* The type does not support this type */
195 MODE_END = -1, /**< init value */
196}GSW_GNSS_MODE_CONFIGURATION_HD;
197
198
199GSW_GNSS_MODE_CONFIGURATION_HD map_gnss_mode(GSW_GNSS_MODE_CONFIGURATION mode)
200{
201 switch (mode)
202 {
203 case GSW_MODE_GPS_GLONASS:
204 return MODE_GPS_GLONASS;
205 case GSW_MODE_GPS_BEIDOU:
206 return MODE_GPS_BEIDOU;
207 case GSW_MODE_GPS_GLONASS_BEIDOU:
208 return MODE_END;
209 case GSW_MODE_GPS:
210 return MODE_GPS;
211 case GSW_MODE_BEIDOU:
212 return MODE_BEIDOU;
213 case GSW_MODE_GLONASS:
214 return MODE_GLONASS;
215 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO:
216 return MODE_END;
217 case GSW_MODE_GPS_GALILEO:
218 return MODE_GPS_GALILEO;
219 case GSW_MODE_GPS_GLONASS_GALILEO:
220 return MODE_GPS_GLONASS_GALILEO;
221 case GSW_MODE_GPS_GALILEO_ONLY:
222 return MODE_GALILEO;
223 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
224 return MODE_END;
225 case GSW_MODE_GNSS_END:
226 return MODE_END;
227 default:
228 return MODE_END;
229 }
230}
231
232int mbtk_gnss_set_VTG()
233{
234 int ret;
235 char param_buf[32] = {0};
236 snprintf(param_buf, 32, "$MSGCFG,2,1000");
237 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
238 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
239 if(ret != 0)
240 {
241 LOGE("[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
242 return GSW_HAL_FAIL;
243 }
244 return GSW_HAL_SUCCESS;
245}
246
247/**
248 * @brief SDK interface to set gnss sampling frequency, support 1Hz、2Hz、5Hz
249 * @param [in] freq
250 * @retval 0: success
251 * @retval other: fail
252 */
253int gsw_gnss_set_freq(int freq)
254{
255 int ret;
256 if (!strated)
257 {
258 gnss_freq = freq;
259 return GSW_HAL_SUCCESS;
260 }
261 char param_buf[32] = {0};
262 snprintf(param_buf, 32, "$FREQCFG,%d", freq);
263 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
264 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
265 if(ret != 0)
266 {
267 LOGE("[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
268 return GSW_HAL_FAIL;
269 }
270 return GSW_HAL_SUCCESS;
271}
272
273/**
274 * @brief SDK interface to set gnss start mode,specific mode refreence GSW_HAL_GNSS_MODE_CONFIGURATION
275 * @param [in] start_mode
276 * @retval 0: success
277 * @retval other: fail
278 */
279int gsw_gnss_set_start_mode(GSW_GNSS_MODE_CONFIGURATION start_mode)
280{
281 int ret;
282 if (!strated)
283 {
284 gnss_startmode = start_mode;
285 return GSW_HAL_SUCCESS;
286 }
287 char param_buf[32] = {0};
288 snprintf(param_buf, 32, "$SYSCFG,%d", map_gnss_mode(start_mode));
289 if(map_gnss_mode(start_mode) == -1)
290 {
291 LOGE("[qser_gnss] mbtk_gnss_start_mode con't support");
292 return GSW_HAL_FAIL;
293 }
294 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
295 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
296 if(ret != 0)
297 {
298 LOGE("[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
299 return GSW_HAL_FAIL;
300 }
301 return GSW_HAL_SUCCESS;
302}
303
304/**
305 * @brief SDK interface to set EPO switch if open or close
306 * @param [in] switch_op
307 * @retval 0: success
308 * @retval other: fail
309 */
310int gsw_gnss_epo_switch(GSW_GNSS_CONF_SWITCH switch_op)
311{
312 int ret;
313 if (!strated)
314 {
315 gnss_switch_op = switch_op;
316 return GSW_HAL_SUCCESS;
317 }
318
319 if(switch_op)
320 {
321 mbtk_gnss_eph_download=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_download");
322 ret = mbtk_gnss_eph_download(QSER_GNSS_TIMEOUT);
323 if(ret != 0)
324 {
325 LOGE("[qser_gnss] mbtk_gnss_eph_download fail.ret = [%d]", ret);
326 return GSW_HAL_FAIL;
327 }
328 mbtk_gnss_eph_inject=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_inject");
329 ret = mbtk_gnss_eph_inject(QSER_GNSS_TIMEOUT);
330 if(ret != 0)
331 {
332 LOGE("[qser_gnss] mbtk_gnss_eph_inject fail.ret = [%d]", ret);
333 return GSW_HAL_FAIL;
334 }
335 }
336 return GSW_HAL_SUCCESS;
337}
338
339static void gnss_callback(uint32_t ind_type, const void* data, uint32_t data_len)
340{
341 if(data == NULL || data_len <= 0)
342 {
343 LOGE("[GSW_gnss] data is NULL.");
344 return;
345 }
346
347 if(gsw_cb == NULL)
348 {
349 //LOGE("[qser_gnss] qser_gnss_callback is NULL.");
350 return;
351 }
352
353 if(ind_type == MBTK_GNSS_IND_LOCATION) {
354 if(data_len != sizeof(mbtk_gnss_location_info_t))
355 {
356 LOGE("[GSW_gnss] data size error");
357 return;
358 }
359 GSW_GNSS_LOCATION_EXT_T gsw_location;
360 GSW_GNSS_LOCATION_T gsw_location_t;
361 mbtk_gnss_location_info_t *locl_info = (mbtk_gnss_location_info_t *)data;
362 gsw_location_t.altitude = locl_info->altitude;
363 gsw_location_t.latitude = locl_info->latitude;
364 gsw_location_t.longitude = locl_info->longitude;
365 gsw_location_t.speed = locl_info->speed;
366 gsw_location_t.bearing = locl_info->bearing;
367 gsw_location_t.timestamp = locl_info->timestamp;
368 gsw_location.legacyLocation = gsw_location_t;
369 gsw_cb->gsw_location_cb(&gsw_location);
370 } else if(ind_type == MBTK_GNSS_IND_NMEA) {
371 mopen_gnss_nmea_info_t qser_nmea = {0};
372 memset(&qser_nmea, 0x0, sizeof(mopen_gnss_nmea_info_t));
373 qser_nmea.length = data_len;
374 memcpy(qser_nmea.nmea, (char *)data, data_len);
375 //qser_nmea.timestamp = qser_get_gnss_time_sec(data, data_len);
376 gsw_cb->gsw_nmea_cb(data,data_len);
377 } else {
378 LOGD("Unknown IND : %d\n", ind_type);
379 }
380}
381
382int gsw_gnss_init(void)
383{
384 int ret;
385 if(!inited)
386 {
387 dlHandle_gnss = dlopen(lynqLib_gnss, RTLD_NOW);
388 fun_ptr_log = (mbtk_log)dlsym(dlHandle_gnss, "mbtk_log");
389 if(fun_ptr_log == NULL || dlHandle_gnss == NULL)
390 {
391 return GSW_HAL_FAIL;
392 }
393 mbtk_gnss_init=(int(*)(mbtk_gnss_callback_func))dlsym(dlHandle_gnss, "mbtk_gnss_init");
394 ret = mbtk_gnss_init(gnss_callback);
395 if(ret == 0)
396 {
397 mbtk_gnss_ind_set=(int(*)(uint32_t ,int))dlsym(dlHandle_gnss, "mbtk_gnss_ind_set");
398 ret = mbtk_gnss_ind_set(MBTK_GNSS_IND_NMEA, QSER_GNSS_TIMEOUT);
399 if(ret == 0)
400 {
401 inited = true;
402 }
403 else
404 {
405 LOGE("[GSW_gnss] init mbtk_gnss_ind_set() fail.ret = [%d]", ret);
406 return GSW_HAL_FAIL;
407 }
408 }
409 else
410 {
411 LOGE("[GSW_gnss] mbtk_gnss_init() fail.ret = [%d]", ret);
412 return GSW_HAL_FAIL;
413 }
414 }
415
416 return GSW_HAL_SUCCESS;
417}
418
419/**
420 * @brief SDK interface to registered callback function
421 * @param [in] callback
422 * @retval 0: success
423 * @retval other: fail
424 */
425int gsw_gnss_reg_cb_group(gsw_gnss_cb callback)
426{
427 if(callback.gsw_location_cb == NULL && callback.gsw_nmea_cb == NULL)
428 {
429 LOGE("[GSW_gnss] handler_ptr is NULL.");
430 return GSW_HAL_FAIL;
431 }
432 if (gsw_cb == NULL)
433 {
434 gsw_cb = (gsw_gnss_cb *)malloc(sizeof(gsw_gnss_cb));
435 if (gsw_cb == NULL)
436 {
437 LOGE("[GSW_gnss] Memory allocation failed.");
438 return GSW_HAL_FAIL;
439 }
440 }
441 gsw_cb->gsw_location_cb = callback.gsw_location_cb;
442 gsw_cb->gsw_nmea_cb = callback.gsw_nmea_cb;
443 return GSW_HAL_SUCCESS;
444}
445/**
446 * @brief SDK interface to start gnss
447 * @param
448 * @retval 0: success
449 * @retval other: fail
450 */
451int gsw_gnss_start(void)
452{
453 int ret;
454 mbtk_gnss_open=(int(*)(int,int))dlsym(dlHandle_gnss, "mbtk_gnss_open");
455 ret = mbtk_gnss_open(255, QSER_GNSS_TIMEOUT);
456 if(ret != 0)
457 {
458 LOGE("[GSW_gnss] mbtk_gnss_open is error.ret = [%d]", ret);
459 return GSW_HAL_FAIL;
460 }
461 strated = true;
462 if (gnss_freq > 0)
463 gsw_gnss_set_freq(gnss_freq);
464 if (gnss_startmode >= 0)
465 gsw_gnss_set_start_mode(gnss_startmode);
466 if (gnss_switch_op > 0)
467 gsw_gnss_epo_switch(gnss_switch_op);
468
469 mbtk_gnss_set_VTG();
470
471 return GSW_HAL_SUCCESS;
472}
473
474/**
475 * @brief SDK interface to stop gnss
476 * @param
477 * @retval 0: success
478 * @retval other: fail
479 */
480int gsw_gnss_stop(void)
481{
482 int ret;
483 mbtk_gnss_close=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_close");
484 ret = mbtk_gnss_close(QSER_GNSS_TIMEOUT);
485 if(ret != 0)
486 {
487 LOGE("[GSW_gnss] mbtk_gnss_close is error.ret = [%d]", ret);
488 return GSW_HAL_FAIL;
489 }
490 strated = false;
491 return GSW_HAL_SUCCESS;
492}
493
494/**
495 * @brief SDK interface to de initialization gnss
496 * @param
497 * @retval 0: success
498 * @retval other: fail
499 */
500int gsw_gnss_deinit(void)
501{
502 int ret;
503 if(inited)
504 {
505 mbtk_gnss_deinit=(int(*)())dlsym(dlHandle_gnss, "mbtk_gnss_deinit");
506 ret = mbtk_gnss_deinit();
507 if(ret == 0)
508 {
509 inited = false;
510 }
511 else
512 {
513 LOGE("[GSW_gnss] mbtk_gnss_init() fail.ret = [%d]", ret);
514 dlclose(dlHandle_gnss);
515 dlHandle_gnss = NULL;
516 return GSW_HAL_FAIL;
517 }
518 }
519
520 dlclose(dlHandle_gnss);
521 dlHandle_gnss = NULL;
522 gnss_freq = -1;
523 gnss_startmode = -1;
524 gnss_switch_op = -1;
525 return GSW_HAL_SUCCESS;
526}
527
528
529/**
530 * @brief SDK interface to enable XTRA switch
531 * @param [in] state
532 * @retval 0: success
533 * @retval other: fail
534 */
535int gsw_gnss_xtra_is_enable(gsw_xtra_state_e state)
536{
537 return GSW_HAL_SUCCESS;
538}
539
540/**
541 * @brief SDK interface to delete aiding data,delete aiding data for cold start(1-H,2-W,3-C)
542 * @param [in] switch_op
543 * @retval 0: success
544 * @retval other: fail
545 */
546int gsw_gnss_delete_aiding_data(unsigned int flags) /*1-don`t delete == hot_start ; 2-delete EPH == warm start ; 3-delete all == cold start*/
547{
548 int ret;
549 char param_buf[32] = {0};
550 snprintf(param_buf, 32, "$RESET,%u", flags);
551 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
552 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
553 if(ret != 0)
554 {
555 LOGE("[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
556 return GSW_HAL_FAIL;
557 }
558 return GSW_HAL_SUCCESS;
559}
560
561/**
562 * @brief init and configure gps
563 * @param [in] init_configure
564 * @retval 0: success
565 * @retval other: fail
566 */
567int gsw_gnss_init_configure_gps(gsw_gnss_init_configure_t init_configure)
568{
569 return GSW_HAL_SUCCESS;
570}