blob: 86b12ebff79ec312b2c84801277e00b961b138a4 [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
zw.wang581aab12025-05-28 19:43:53 +080018#include "gsw_gnss_interface.h"
19
20#define MBTK_GNSS_IND_LOCATION (1) // 1
21#define MBTK_GNSS_IND_NMEA (1 << 1) // 2
22#define QSER_GNSS_TIMEOUT 5
b.liu68a94c92025-05-24 12:53:41 +080023
24#ifndef LOG_ERR_LEVEL
25#define LOG_ERR_LEVEL 3 /* error conditions */
26#endif
27#ifndef LOG_WARN_LEVEL
28#define LOG_WARN_LEVEL 4 /* warning conditions */
29#endif
30#ifndef LOG_INFO_LEVEL
31#define LOG_INFO_LEVEL 6 /* informational */
32#endif
33#ifndef LOG_DEBUG_LEVEL
34#define LOG_DEBUG_LEVEL 7 /* debug-level messages */
35#endif
36#ifndef LOG_VERBOSE_LEVEL
37#define LOG_VERBOSE_LEVEL 8
38#endif
39
l.yang6a42e4d2025-05-28 01:04:20 -070040#define GSW_GNSS "[HAL][GSW_GNSS]"
41
42
b.liu68a94c92025-05-24 12:53:41 +080043#define LOGV(fmt, args ...) \
44 do{ \
45 char *file_ptr_1001 = __FILE__; \
46 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
47 char line_1001[10] = {0}; \
48 sprintf(line_1001, "%d", __LINE__); \
49 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
50 if(*ptr_1001 == '/') \
51 break; \
52 ptr_1001--; \
53 } \
l.yang6a42e4d2025-05-28 01:04:20 -070054 fun_ptr_log(LOG_VERBOSE_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080055 } while(0)
56
57#define LOGI(fmt, args...) \
58 do{ \
59 char *file_ptr_1001 = __FILE__; \
60 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
61 char line_1001[10] = {0}; \
62 sprintf(line_1001, "%d", __LINE__); \
63 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
64 if(*ptr_1001 == '/') \
65 break; \
66 ptr_1001--; \
67 } \
l.yang6a42e4d2025-05-28 01:04:20 -070068 fun_ptr_log(LOG_INFO_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080069 } while(0)
70
71#define LOGD(fmt, args...) \
72 do{ \
73 char *file_ptr_1001 = __FILE__; \
74 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
75 char line_1001[10] = {0}; \
76 sprintf(line_1001, "%d", __LINE__); \
77 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
78 if(*ptr_1001 == '/') \
79 break; \
80 ptr_1001--; \
81 } \
l.yang6a42e4d2025-05-28 01:04:20 -070082 fun_ptr_log(LOG_DEBUG_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080083 } while(0)
84
85#define LOGW(fmt, args...) \
86 do{ \
87 char *file_ptr_1001 = __FILE__; \
88 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
89 char line_1001[10] = {0}; \
90 sprintf(line_1001, "%d", __LINE__); \
91 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
92 if(*ptr_1001 == '/') \
93 break; \
94 ptr_1001--; \
95 } \
l.yang6a42e4d2025-05-28 01:04:20 -070096 fun_ptr_log(LOG_WARN_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +080097 } while(0)
98
99#define LOGE(fmt, args...) \
100 do{ \
101 char *file_ptr_1001 = __FILE__; \
102 char *ptr_1001 = file_ptr_1001 + strlen(file_ptr_1001) - 1; \
103 char line_1001[10] = {0}; \
104 sprintf(line_1001, "%d", __LINE__); \
105 while(ptr_1001 >= file_ptr_1001 && *ptr_1001){ \
106 if(*ptr_1001 == '/') \
107 break; \
108 ptr_1001--; \
109 } \
l.yang6a42e4d2025-05-28 01:04:20 -0700110 fun_ptr_log(LOG_ERR_LEVEL, "%s#%s: "GSW_GNSS"" fmt, ptr_1001 + 1, line_1001, ##args); \
b.liu68a94c92025-05-24 12:53:41 +0800111 } while(0)
b.liu68a94c92025-05-24 12:53:41 +0800112
113#define MOPEN_GNSS_NMEA_MAX_LENGTH 255 /** NMEA string maximum length. */
114static gsw_gnss_cb *gsw_cb = NULL;
115static bool inited = false;
116static bool strated = false;
117
118typedef void (*mbtk_gnss_callback_func)(uint32_t ind_type, const void* data, uint32_t data_len);
119typedef void (*mbtk_log)(int level, const char *format,...);
120static mbtk_log fun_ptr_log = NULL;
121
122int (*mbtk_gnss_init)(mbtk_gnss_callback_func cb);
123int (*mbtk_gnss_deinit)();
124
125int (*mbtk_gnss_ind_set)(uint32_t ,int);
126int (*mbtk_gnss_open)(int, int);
127int (*mbtk_gnss_close)(int);
128int (*mbtk_gnss_setting)(const char *setting_cmd, int);
129
130int (*mbtk_gnss_eph_download)(int);
131int (*mbtk_gnss_eph_inject)(int);
132
133int gnss_freq = -1;
134GSW_GNSS_MODE_CONFIGURATION gnss_startmode = -1;
zw.wang581aab12025-05-28 19:43:53 +0800135GSW_CONF_SWITCH gnss_switch_op = -1;
b.liu68a94c92025-05-24 12:53:41 +0800136void *dlHandle_gnss;
137char *lynqLib_gnss = "/lib/libmbtk_lib.so";
138
139typedef enum
140{
141 E_MT_LOC_MSG_ID_LOCATION_INFO = 1, /**< pv_data = & mopen_location_info_t */
142 E_MT_LOC_MSG_ID_NMEA_INFO = 3, /**< pv_data = & mopen_gnss_nmea_info_t */
143} e_msg_id_t;
144
145typedef struct
146{
147 int64_t timestamp; /**< System Timestamp, marked for when got the nmea data */
148 int length; /**< NMEA string length. */
149 char nmea[MOPEN_GNSS_NMEA_MAX_LENGTH + 1]; /**< NMEA string.*/
150}mopen_gnss_nmea_info_t; /* Message */
151
152typedef struct
153{
154 uint32_t size; /**< Set to the size of mcm_gps_location_t. */
155 int flags; /**< Contains GPS location flags bits. */
156 int position_source; /**< Provider indicator for HYBRID or GPS. */ //功能暂未实现,可不用添加进结构体
157 double latitude; /**< Latitude in degrees. */
158 double longitude; /**< Longitude in degrees. */
159 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
160 float speed; /**< Speed in meters per second. */
161 float bearing; /**< Heading in degrees. */ //功能暂未实现,可不用添加进结构体
162 float accuracy; /**< Expected accuracy in meters. */ //功能暂未实现,可不用添加进结构体
163 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
164 int32_t is_indoor; /**< Location is indoors. */ //功能暂未实现,可不用添加进结构体
165 float floor_number; /**< Indicates the floor number. */
166}mopen_location_info_t;//功能暂未实现,可不用添加进结构体
167
168
169typedef struct {
170 uint32_t flags;
171 double latitude; /**< Latitude in degrees. */
172 double longitude; /**< Longitude in degrees. */
173 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
174 float speed; /**< Speed in meters per second. */
175 float bearing; /**< Heading in degrees. */
176 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
177} mbtk_gnss_location_info_t;
178
zw.wang581aab12025-05-28 19:43:53 +0800179typedef struct{
180 GSW_GNSS_MODE_CONFIGURATION start_mode;
181 gnss_freq_type freq;
182 gsw_gnss_cb callback;
183}gsw_gnss_init_configure_t;
184
b.liu68a94c92025-05-24 12:53:41 +0800185typedef enum{
186 MODE_GPS = 1, /**< GPS only */
187 MODE_BEIDOU, /**< BEIDOU only*/
188 MODE_GPS_BEIDOU, /**< GPS+BEIDOU */
189 MODE_GLONASS, /**< GLONASS only */
190 MODE_GPS_GLONASS, /**< GPS+GLONASS */
191 MODE_GLONASS_BEIDOU, /**< GLONASS+BEIDOU */ /* The type does not support this type */
192 MODE_GPS_GLONASS_BEIDOU, /**< GPS+GLONASS+BEIDOU */ /* The type does not support this type */
193 MODE_GALILEO, /**< GALILEO only */
194 MODE_GPS_GALILEO, /**< GPS+GALILEO */
195 MODE_BEIDOU_GALILEO, /**< BEIDOU+GALILEO */
196 MODE_GPS_BEIDOU_GALILEO, /**< GPS+BEIDOU+GALILEO */
197 MODE_GLONASS_GALILEO, /**< GLONASS+GALILEO */
198 MODE_GPS_GLONASS_GALILEO, /**< GPS+GLONASS+GALILEO */
199 MODE_BEIDOU_GLONASS_GALILEO, /**< BEIDOU+GLONASS+GALILEO */ /* The type does not support this type */
200 MODE_END = -1, /**< init value */
201}GSW_GNSS_MODE_CONFIGURATION_HD;
202
zw.wangbe05b922025-07-14 18:37:51 +0800203typedef enum{
204 NO_DEVICE = 0,
205 HD8122,
206 HD8040D,
207}GSW_DEVICE;
b.liu68a94c92025-05-24 12:53:41 +0800208
zw.wangbe05b922025-07-14 18:37:51 +0800209typedef struct {
210 int fd;
211 GSW_DEVICE got_hd8;
212} rx_ctx;
213
214static GSW_DEVICE gsw_device = NO_DEVICE;
b.liu68a94c92025-05-24 12:53:41 +0800215GSW_GNSS_MODE_CONFIGURATION_HD map_gnss_mode(GSW_GNSS_MODE_CONFIGURATION mode)
216{
217 switch (mode)
218 {
219 case GSW_MODE_GPS_GLONASS:
220 return MODE_GPS_GLONASS;
221 case GSW_MODE_GPS_BEIDOU:
222 return MODE_GPS_BEIDOU;
223 case GSW_MODE_GPS_GLONASS_BEIDOU:
224 return MODE_END;
225 case GSW_MODE_GPS:
226 return MODE_GPS;
227 case GSW_MODE_BEIDOU:
228 return MODE_BEIDOU;
229 case GSW_MODE_GLONASS:
230 return MODE_GLONASS;
231 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO:
232 return MODE_END;
233 case GSW_MODE_GPS_GALILEO:
234 return MODE_GPS_GALILEO;
235 case GSW_MODE_GPS_GLONASS_GALILEO:
236 return MODE_GPS_GLONASS_GALILEO;
237 case GSW_MODE_GPS_GALILEO_ONLY:
238 return MODE_GALILEO;
239 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
240 return MODE_END;
241 case GSW_MODE_GNSS_END:
242 return MODE_END;
243 default:
244 return MODE_END;
245 }
246}
247
zw.wangbe05b922025-07-14 18:37:51 +0800248static void *rx_thread(void *arg)
249{
250 rx_ctx *c = (rx_ctx *)arg;
251 char buf[128];
252 ssize_t n;
253 time_t end = time(NULL) + 1; /* 1 秒超时 */
254
255 while (time(NULL) < end) {
256 n = read(c->fd, buf, sizeof(buf));
257 if (n > 0 && memmem(buf, n, "HD8040D", 7)) {
258 c->got_hd8 = 2;
259 break;
260 }
261 else if (n > 0 && memmem(buf, n, "HD812", 5)) {
262 c->got_hd8 = 1;
263 break;
264 }
265 }
266 return NULL;
267}
268
269static int send_and_wait(int fd)
270{
271 int ret;
272 pthread_t tid;
273 rx_ctx ctx = { .fd = fd, .got_hd8 = NO_DEVICE };
274
275 pthread_create(&tid, NULL, rx_thread, &ctx);
276
277 unsigned char tx[8] = {0xF1,0xD9,0x0A,0x04,0x00,0x00,0x0E,0x34};
278 ret = write(fd, tx, sizeof(tx));
279 if(ret < 0)
280 {
281 LOGE("[GSW_gnss] send_and_wait write fail.ret = [%d]", ret);
282 }
283 pthread_join(tid, NULL);
284 return ctx.got_hd8;
285}
286
287static int get_gnss_device_version(void)
288{
289 int fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY);
290 if (fd < 0) { perror("open"); return 1; }
291 gsw_device = send_and_wait(fd);
292 close(fd);
293 return gsw_device;
294}
295
b.liu68a94c92025-05-24 12:53:41 +0800296int mbtk_gnss_set_VTG()
297{
298 int ret;
zw.wang57f3a9f2025-07-10 14:26:52 +0800299 ret = system("/usr/sbin/gnss_gpio.sh VTG > /dev/null 2>&1");
b.liu68a94c92025-05-24 12:53:41 +0800300 if(ret != 0)
301 {
zw.wang57f3a9f2025-07-10 14:26:52 +0800302 LOGE("[GSW_gnss] mbtk_gnss_set_VTG on fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700303 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800304 }
305 return GSW_HAL_SUCCESS;
306}
307
zw.wangbe05b922025-07-14 18:37:51 +0800308static int HD8040D_gsw_gnss_set_freq(int freq)
309{
310 int ret;
311 char cmd[64] = {0};
312 switch (freq)
313 {
314 case 1:
315 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "1HZ");
316 break;
317 case 5:
318 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "5HZ");
319 break;
320 case 10:
321 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "10HZ");
322 break;
323 default:
324 return GSW_HAL_NORMAL_FAIL;
325 break;
326 }
327 ret = system(cmd);
328 if(ret != 0)
329 {
330 LOGE("[GSW_gnss] gnss_gpio.sh GSW_HD8040D mode fail.ret = [%d]", ret);
331 return GSW_HAL_NORMAL_FAIL;
332 }
333 return ret;
334}
b.liu68a94c92025-05-24 12:53:41 +0800335/**
336 * @brief SDK interface to set gnss sampling frequency, support 1Hz、2Hz、5Hz
337 * @param [in] freq
338 * @retval 0: success
339 * @retval other: fail
340 */
341int gsw_gnss_set_freq(int freq)
342{
zw.wangbc534c02025-06-26 09:31:44 +0800343 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700344 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800345
b.liu68a94c92025-05-24 12:53:41 +0800346 int ret;
347 if (!strated)
348 {
349 gnss_freq = freq;
350 return GSW_HAL_SUCCESS;
351 }
zw.wangbe05b922025-07-14 18:37:51 +0800352 if(gsw_device == NO_DEVICE)
353 {
354 ret = get_gnss_device_version();
355 LOGD("[GSW_gnss] get_gnss_device_version ret = [%d]", ret);
356 }
357 if(gsw_device == HD8040D)
358 {
359 ret = HD8040D_gsw_gnss_set_freq(freq);
360 return ret;
361 }
b.liu68a94c92025-05-24 12:53:41 +0800362 char param_buf[32] = {0};
363 snprintf(param_buf, 32, "$FREQCFG,%d", freq);
364 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
365 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
366 if(ret != 0)
367 {
368 LOGE("[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700369 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800370 }
371 return GSW_HAL_SUCCESS;
372}
373
zw.wangbe05b922025-07-14 18:37:51 +0800374static int32_t HD8040D_gsw_gnss_set_start_mode(GSW_GNSS_MODE_CONFIGURATION start_mode)
375{
376 int ret;
377 char cmd[64] = {0};
378 switch (start_mode)
379 {
380 case GSW_MODE_GPS_GLONASS:
381 return GSW_HAL_NORMAL_FAIL;
382 break;
383 case GSW_MODE_GPS_BEIDOU:
384 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GPS_BD_DUAL");
385 break;
386 case GSW_MODE_GPS_GLONASS_BEIDOU:
387 return GSW_HAL_NORMAL_FAIL;
388 break;
389 case GSW_MODE_GPS:
390 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GPS_L1L5");
391 break;
392 case GSW_MODE_BEIDOU:
393 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_BD_B1I_B1C_B2A");
394 break;
395 case GSW_MODE_GLONASS:
396 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GALILEO_E1_E5A");
397 break;
398 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO:
399 return GSW_HAL_NORMAL_FAIL;
400 break;
401 case GSW_MODE_GPS_GALILEO:
402 return GSW_HAL_NORMAL_FAIL;
403 break;
404 case GSW_MODE_GPS_GLONASS_GALILEO:
405 return GSW_HAL_NORMAL_FAIL;
406 break;
407 case GSW_MODE_GPS_GALILEO_ONLY:
408 return GSW_HAL_NORMAL_FAIL;
409 break;
410 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
411 return GSW_HAL_NORMAL_FAIL;
412 break;
413 case GSW_MODE_GNSS_END:
414 return GSW_HAL_NORMAL_FAIL;
415 break;
416 default:
417 return GSW_HAL_NORMAL_FAIL;
418 break;
419 }
420 ret = system(cmd);
421 if(ret != 0)
422 {
423 LOGE("[GSW_gnss] gnss_gpio.sh GSW_HD8040D mode fail.ret = [%d]", ret);
424 return GSW_HAL_NORMAL_FAIL;
425 }
426 return ret;
427}
428
b.liu68a94c92025-05-24 12:53:41 +0800429/**
430 * @brief SDK interface to set gnss start mode,specific mode refreence GSW_HAL_GNSS_MODE_CONFIGURATION
431 * @param [in] start_mode
432 * @retval 0: success
433 * @retval other: fail
434 */
hong.liud2417072025-06-27 07:10:37 -0700435int32_t gsw_gnss_set_start_mode(GSW_GNSS_MODE_CONFIGURATION start_mode)
b.liu68a94c92025-05-24 12:53:41 +0800436{
zw.wangbc534c02025-06-26 09:31:44 +0800437 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700438 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800439 int ret;
440 if (!strated)
441 {
442 gnss_startmode = start_mode;
443 return GSW_HAL_SUCCESS;
444 }
zw.wangbe05b922025-07-14 18:37:51 +0800445 if(gsw_device == NO_DEVICE)
446 {
447 ret = get_gnss_device_version();
448 LOGD("[GSW_gnss] get_gnss_device_version ret = [%d]", ret);
449 }
450 if(gsw_device == HD8040D)
451 {
452 ret = HD8040D_gsw_gnss_set_start_mode(start_mode);
453 return ret;
454 }
b.liu68a94c92025-05-24 12:53:41 +0800455 char param_buf[32] = {0};
456 snprintf(param_buf, 32, "$SYSCFG,%d", map_gnss_mode(start_mode));
457 if(map_gnss_mode(start_mode) == -1)
458 {
459 LOGE("[qser_gnss] mbtk_gnss_start_mode con't support");
hong.liud2417072025-06-27 07:10:37 -0700460 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800461 }
462 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
463 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
464 if(ret != 0)
465 {
466 LOGE("[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700467 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800468 }
469 return GSW_HAL_SUCCESS;
470}
471
472/**
473 * @brief SDK interface to set EPO switch if open or close
474 * @param [in] switch_op
475 * @retval 0: success
476 * @retval other: fail
477 */
hong.liud2417072025-06-27 07:10:37 -0700478int32_t gsw_gnss_epo_switch(GSW_CONF_SWITCH switch_op)
b.liu68a94c92025-05-24 12:53:41 +0800479{
zw.wangbc534c02025-06-26 09:31:44 +0800480 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700481 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800482 int ret;
483 if (!strated)
484 {
485 gnss_switch_op = switch_op;
486 return GSW_HAL_SUCCESS;
487 }
488
489 if(switch_op)
490 {
491 mbtk_gnss_eph_download=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_download");
492 ret = mbtk_gnss_eph_download(QSER_GNSS_TIMEOUT);
493 if(ret != 0)
494 {
495 LOGE("[qser_gnss] mbtk_gnss_eph_download fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700496 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800497 }
498 mbtk_gnss_eph_inject=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_inject");
499 ret = mbtk_gnss_eph_inject(QSER_GNSS_TIMEOUT);
500 if(ret != 0)
501 {
502 LOGE("[qser_gnss] mbtk_gnss_eph_inject fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700503 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800504 }
505 }
506 return GSW_HAL_SUCCESS;
507}
508
509static void gnss_callback(uint32_t ind_type, const void* data, uint32_t data_len)
510{
511 if(data == NULL || data_len <= 0)
512 {
513 LOGE("[GSW_gnss] data is NULL.");
514 return;
515 }
516
517 if(gsw_cb == NULL)
518 {
519 //LOGE("[qser_gnss] qser_gnss_callback is NULL.");
520 return;
521 }
522
zw.wanga5250d62025-06-13 16:01:34 +0800523 if(ind_type == MBTK_GNSS_IND_LOCATION && gsw_cb->gsw_location_cb != NULL) {
b.liu68a94c92025-05-24 12:53:41 +0800524 if(data_len != sizeof(mbtk_gnss_location_info_t))
525 {
526 LOGE("[GSW_gnss] data size error");
527 return;
528 }
529 GSW_GNSS_LOCATION_EXT_T gsw_location;
hong.liud2417072025-06-27 07:10:37 -0700530 GSW_GNSS_LOCATION_T gsw_location_t = {0};
b.liu68a94c92025-05-24 12:53:41 +0800531 mbtk_gnss_location_info_t *locl_info = (mbtk_gnss_location_info_t *)data;
532 gsw_location_t.altitude = locl_info->altitude;
533 gsw_location_t.latitude = locl_info->latitude;
534 gsw_location_t.longitude = locl_info->longitude;
535 gsw_location_t.speed = locl_info->speed;
536 gsw_location_t.bearing = locl_info->bearing;
537 gsw_location_t.timestamp = locl_info->timestamp;
zw.wanga5250d62025-06-13 16:01:34 +0800538 gsw_location_t.flags = locl_info->flags;
b.liu68a94c92025-05-24 12:53:41 +0800539 gsw_location.legacyLocation = gsw_location_t;
540 gsw_cb->gsw_location_cb(&gsw_location);
zw.wanga5250d62025-06-13 16:01:34 +0800541 } else if(ind_type == MBTK_GNSS_IND_NMEA && gsw_cb->gsw_nmea_cb != NULL) {
b.liu68a94c92025-05-24 12:53:41 +0800542 mopen_gnss_nmea_info_t qser_nmea = {0};
543 memset(&qser_nmea, 0x0, sizeof(mopen_gnss_nmea_info_t));
544 qser_nmea.length = data_len;
545 memcpy(qser_nmea.nmea, (char *)data, data_len);
546 //qser_nmea.timestamp = qser_get_gnss_time_sec(data, data_len);
547 gsw_cb->gsw_nmea_cb(data,data_len);
548 } else {
549 LOGD("Unknown IND : %d\n", ind_type);
550 }
551}
552
hong.liud2417072025-06-27 07:10:37 -0700553int32_t gsw_gnss_init(void)
b.liu68a94c92025-05-24 12:53:41 +0800554{
lichengzhanga7089172025-07-01 20:41:46 +0800555 int ret;
b.liu68a94c92025-05-24 12:53:41 +0800556 if(!inited)
557 {
lichengzhanga7089172025-07-01 20:41:46 +0800558 ret = system("serial_atcmd AT*IMLCONFIG=13");
559 if(ret != 0)
560 {
561 LOGE("serial_atcmd fail\n");
562 return GSW_HAL_NORMAL_FAIL;
563 }
zw.wang1907e8f2025-07-01 16:26:39 +0800564 if(dlHandle_gnss == NULL)
565 dlHandle_gnss = dlopen(lynqLib_gnss, RTLD_NOW);
566 if(fun_ptr_log == NULL)
567 fun_ptr_log = (mbtk_log)dlsym(dlHandle_gnss, "mbtk_log");
b.liu68a94c92025-05-24 12:53:41 +0800568 if(fun_ptr_log == NULL || dlHandle_gnss == NULL)
569 {
hong.liud2417072025-06-27 07:10:37 -0700570 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800571 }
572 mbtk_gnss_init=(int(*)(mbtk_gnss_callback_func))dlsym(dlHandle_gnss, "mbtk_gnss_init");
573 ret = mbtk_gnss_init(gnss_callback);
574 if(ret == 0)
575 {
576 mbtk_gnss_ind_set=(int(*)(uint32_t ,int))dlsym(dlHandle_gnss, "mbtk_gnss_ind_set");
zw.wanga5250d62025-06-13 16:01:34 +0800577 ret = mbtk_gnss_ind_set(MBTK_GNSS_IND_NMEA |MBTK_GNSS_IND_LOCATION, QSER_GNSS_TIMEOUT);
b.liu68a94c92025-05-24 12:53:41 +0800578 if(ret == 0)
579 {
580 inited = true;
581 }
582 else
583 {
584 LOGE("[GSW_gnss] init mbtk_gnss_ind_set() fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700585 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800586 }
587 }
588 else
589 {
590 LOGE("[GSW_gnss] mbtk_gnss_init() fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700591 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800592 }
593 }
594
595 return GSW_HAL_SUCCESS;
596}
597
598/**
599 * @brief SDK interface to registered callback function
600 * @param [in] callback
601 * @retval 0: success
602 * @retval other: fail
603 */
hong.liud2417072025-06-27 07:10:37 -0700604int32_t gsw_gnss_reg_cb_group(gsw_gnss_cb callback)
b.liu68a94c92025-05-24 12:53:41 +0800605{
zw.wangbc534c02025-06-26 09:31:44 +0800606 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700607 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800608 if(callback.gsw_location_cb == NULL && callback.gsw_nmea_cb == NULL)
609 {
610 LOGE("[GSW_gnss] handler_ptr is NULL.");
hong.liud2417072025-06-27 07:10:37 -0700611 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800612 }
613 if (gsw_cb == NULL)
614 {
615 gsw_cb = (gsw_gnss_cb *)malloc(sizeof(gsw_gnss_cb));
616 if (gsw_cb == NULL)
617 {
618 LOGE("[GSW_gnss] Memory allocation failed.");
hong.liud2417072025-06-27 07:10:37 -0700619 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800620 }
621 }
622 gsw_cb->gsw_location_cb = callback.gsw_location_cb;
623 gsw_cb->gsw_nmea_cb = callback.gsw_nmea_cb;
624 return GSW_HAL_SUCCESS;
625}
626/**
627 * @brief SDK interface to start gnss
628 * @param
629 * @retval 0: success
630 * @retval other: fail
631 */
hong.liud2417072025-06-27 07:10:37 -0700632int32_t gsw_gnss_start(void)
b.liu68a94c92025-05-24 12:53:41 +0800633{
634 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800635 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700636 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800637 ret = system("/usr/sbin/gnss_gpio.sh on > /dev/null 2>&1");
638 if(ret != 0)
639 {
640 LOGE("[GSW_gnss] gnss_gpio.sh on fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700641 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800642 }
zw.wang57f3a9f2025-07-10 14:26:52 +0800643 // 记录mbtk_gnss_open前的时间戳
644 struct timespec start_time;
645 if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0) {
646 LOGE("[GSW_gnss] Failed to get start time");
647 return GSW_HAL_NORMAL_FAIL;
648 }
649
b.liu68a94c92025-05-24 12:53:41 +0800650 mbtk_gnss_open=(int(*)(int,int))dlsym(dlHandle_gnss, "mbtk_gnss_open");
651 ret = mbtk_gnss_open(255, QSER_GNSS_TIMEOUT);
652 if(ret != 0)
653 {
654 LOGE("[GSW_gnss] mbtk_gnss_open is error.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700655 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800656 }
zw.wang89c18242025-06-24 19:07:10 +0800657
b.liu68a94c92025-05-24 12:53:41 +0800658 strated = true;
zw.wang7aa34062025-06-27 17:54:55 +0800659 /*
b.liu68a94c92025-05-24 12:53:41 +0800660 if (gnss_freq > 0)
661 gsw_gnss_set_freq(gnss_freq);
662 if (gnss_startmode >= 0)
663 gsw_gnss_set_start_mode(gnss_startmode);
664 if (gnss_switch_op > 0)
665 gsw_gnss_epo_switch(gnss_switch_op);
zw.wang7aa34062025-06-27 17:54:55 +0800666 */
zw.wang57f3a9f2025-07-10 14:26:52 +0800667
668 // 记录mbtk_gnss_set_VTG前的时间戳并计算等待时间
669 struct timespec end_time;
670 if (clock_gettime(CLOCK_MONOTONIC, &end_time) != 0) {
671 LOGE("[GSW_gnss] Failed to get end time");
672 return GSW_HAL_NORMAL_FAIL;
673 }
674 long start_ms = start_time.tv_sec * 1000 + start_time.tv_nsec / 1000000;
675 long end_ms = end_time.tv_sec * 1000 + end_time.tv_nsec / 1000000;
676 long diff_ms = end_ms - start_ms;
677 if (diff_ms < 700) {
678 long wait_ms = 700 - diff_ms;
679 usleep(wait_ms * 1000); // 转换为微秒等待
680 }
681
b.liu68a94c92025-05-24 12:53:41 +0800682 mbtk_gnss_set_VTG();
683
684 return GSW_HAL_SUCCESS;
685}
686
zw.wang57f3a9f2025-07-10 14:26:52 +0800687
b.liu68a94c92025-05-24 12:53:41 +0800688/**
689 * @brief SDK interface to stop gnss
690 * @param
691 * @retval 0: success
692 * @retval other: fail
693 */
hong.liud2417072025-06-27 07:10:37 -0700694int32_t gsw_gnss_stop(void)
b.liu68a94c92025-05-24 12:53:41 +0800695{
696 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800697 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700698 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800699 mbtk_gnss_close=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_close");
700 ret = mbtk_gnss_close(QSER_GNSS_TIMEOUT);
701 if(ret != 0)
702 {
703 LOGE("[GSW_gnss] mbtk_gnss_close is error.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700704 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800705 }
zw.wangbc534c02025-06-26 09:31:44 +0800706 ret = system("/usr/sbin/gnss_gpio.sh off > /dev/null 2>&1");
707 if(ret != 0)
708 {
709 LOGE("[GSW_gnss] gnss_gpio.sh off fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700710 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800711 }
b.liu68a94c92025-05-24 12:53:41 +0800712 strated = false;
713 return GSW_HAL_SUCCESS;
714}
715
716/**
717 * @brief SDK interface to de initialization gnss
718 * @param
719 * @retval 0: success
720 * @retval other: fail
721 */
hong.liud2417072025-06-27 07:10:37 -0700722int32_t gsw_gnss_deinit(void)
b.liu68a94c92025-05-24 12:53:41 +0800723{
724 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800725 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700726 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800727 if(inited)
728 {
lichengzhanga7089172025-07-01 20:41:46 +0800729 ret = system("serial_atcmd AT*IMLCONFIG=12");
730 if(ret != 0)
731 {
732 LOGE("serial_atcmd fail\n");
733 return GSW_HAL_NORMAL_FAIL;
734 }
b.liu68a94c92025-05-24 12:53:41 +0800735 mbtk_gnss_deinit=(int(*)())dlsym(dlHandle_gnss, "mbtk_gnss_deinit");
736 ret = mbtk_gnss_deinit();
737 if(ret == 0)
738 {
739 inited = false;
740 }
741 else
742 {
zw.wang1907e8f2025-07-01 16:26:39 +0800743 LOGE("[GSW_gnss] mbtk_gnss_deinit() fail.ret = [%d]", ret);
744 /*
b.liu68a94c92025-05-24 12:53:41 +0800745 dlclose(dlHandle_gnss);
746 dlHandle_gnss = NULL;
zw.wang1907e8f2025-07-01 16:26:39 +0800747 */
hong.liud2417072025-06-27 07:10:37 -0700748 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800749 }
750 }
751
zw.wang1907e8f2025-07-01 16:26:39 +0800752 /*
b.liu68a94c92025-05-24 12:53:41 +0800753 dlclose(dlHandle_gnss);
754 dlHandle_gnss = NULL;
zw.wang1907e8f2025-07-01 16:26:39 +0800755 */
b.liu68a94c92025-05-24 12:53:41 +0800756 gnss_freq = -1;
757 gnss_startmode = -1;
758 gnss_switch_op = -1;
759 return GSW_HAL_SUCCESS;
760}
761
zw.wang75e98ea2025-05-29 17:57:38 +0800762int gsw_gnss_add_lib(void)
763{
764 return GSW_HAL_SUCCESS;
765}
b.liu68a94c92025-05-24 12:53:41 +0800766
767/**
768 * @brief SDK interface to enable XTRA switch
769 * @param [in] state
770 * @retval 0: success
771 * @retval other: fail
772 */
hong.liud2417072025-06-27 07:10:37 -0700773int32_t gsw_gnss_xtra_is_enable(gsw_xtra_state_e state)
b.liu68a94c92025-05-24 12:53:41 +0800774{
775 return GSW_HAL_SUCCESS;
776}
777
778/**
779 * @brief SDK interface to delete aiding data,delete aiding data for cold start(1-H,2-W,3-C)
780 * @param [in] switch_op
781 * @retval 0: success
782 * @retval other: fail
783 */
hong.liud2417072025-06-27 07:10:37 -0700784int32_t gsw_gnss_delete_aiding_data(unsigned int flags) /*1-don`t delete == hot_start ; 2-delete EPH == warm start ; 3-delete all == cold start*/
b.liu68a94c92025-05-24 12:53:41 +0800785{
zw.wangbc534c02025-06-26 09:31:44 +0800786 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700787 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800788 int ret;
789 char param_buf[32] = {0};
790 snprintf(param_buf, 32, "$RESET,%u", flags);
791 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
792 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
793 if(ret != 0)
794 {
795 LOGE("[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700796 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800797 }
798 return GSW_HAL_SUCCESS;
799}
800
801/**
802 * @brief init and configure gps
803 * @param [in] init_configure
804 * @retval 0: success
805 * @retval other: fail
806 */
hong.liud2417072025-06-27 07:10:37 -0700807int32_t gsw_gnss_init_configure_gps(gsw_gnss_init_configure_t init_configure)
b.liu68a94c92025-05-24 12:53:41 +0800808{
809 return GSW_HAL_SUCCESS;
810}
hong.liud2417072025-06-27 07:10:37 -0700811
812int gsw_gnss_get_tail_nmea_type(char *tail_type, int len)
813{
814 if(NULL == tail_type){
815 LOGE("get_tail_nmea_type fail, tail_type is NULL");
816 return GSW_HAL_ERROR_GNSS_FAIL;
817 }
818
819 if(len >= 3){
820 strcpy(tail_type, "RMC");
821 return GSW_HAL_GNSS_SUCCESS;
822 }else{
823 LOGE("get_tail_nmea_type fail, len[%d] is too short", len);
824 return GSW_HAL_ERROR_GNSS_FAIL;
825 }
826}