blob: 5b7f45556eab30135ca368ed944873d7d2a9abd1 [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>
rx.xieee9ec322025-08-22 05:43:14 -070017#include <ctype.h>
b.liu68a94c92025-05-24 12:53:41 +080018
zw.wang581aab12025-05-28 19:43:53 +080019#include "gsw_gnss_interface.h"
20
21#define MBTK_GNSS_IND_LOCATION (1) // 1
22#define MBTK_GNSS_IND_NMEA (1 << 1) // 2
23#define QSER_GNSS_TIMEOUT 5
b.liu68a94c92025-05-24 12:53:41 +080024
zw.wangbd342b92025-07-21 11:24:16 +080025#include "gsw_log_interface.h"
l.yang6a42e4d2025-05-28 01:04:20 -070026#define GSW_GNSS "[HAL][GSW_GNSS]"
27
b.liu68a94c92025-05-24 12:53:41 +080028#define MOPEN_GNSS_NMEA_MAX_LENGTH 255 /** NMEA string maximum length. */
29static gsw_gnss_cb *gsw_cb = NULL;
30static bool inited = false;
31static bool strated = false;
32
33typedef void (*mbtk_gnss_callback_func)(uint32_t ind_type, const void* data, uint32_t data_len);
b.liu68a94c92025-05-24 12:53:41 +080034
35int (*mbtk_gnss_init)(mbtk_gnss_callback_func cb);
36int (*mbtk_gnss_deinit)();
37
38int (*mbtk_gnss_ind_set)(uint32_t ,int);
39int (*mbtk_gnss_open)(int, int);
40int (*mbtk_gnss_close)(int);
41int (*mbtk_gnss_setting)(const char *setting_cmd, int);
42
43int (*mbtk_gnss_eph_download)(int);
44int (*mbtk_gnss_eph_inject)(int);
rx.xie85d47ac2025-08-08 05:16:29 -070045int (*mbtk_gnss_dl_ptr)(const char *, int);
b.liu68a94c92025-05-24 12:53:41 +080046
47int gnss_freq = -1;
48GSW_GNSS_MODE_CONFIGURATION gnss_startmode = -1;
zw.wang581aab12025-05-28 19:43:53 +080049GSW_CONF_SWITCH gnss_switch_op = -1;
b.liu68a94c92025-05-24 12:53:41 +080050void *dlHandle_gnss;
51char *lynqLib_gnss = "/lib/libmbtk_lib.so";
52
53typedef enum
54{
55 E_MT_LOC_MSG_ID_LOCATION_INFO = 1, /**< pv_data = & mopen_location_info_t */
56 E_MT_LOC_MSG_ID_NMEA_INFO = 3, /**< pv_data = & mopen_gnss_nmea_info_t */
57} e_msg_id_t;
58
59typedef struct
60{
61 int64_t timestamp; /**< System Timestamp, marked for when got the nmea data */
62 int length; /**< NMEA string length. */
63 char nmea[MOPEN_GNSS_NMEA_MAX_LENGTH + 1]; /**< NMEA string.*/
64}mopen_gnss_nmea_info_t; /* Message */
65
66typedef struct
67{
68 uint32_t size; /**< Set to the size of mcm_gps_location_t. */
69 int flags; /**< Contains GPS location flags bits. */
70 int position_source; /**< Provider indicator for HYBRID or GPS. */ //功能暂未实现,可不用添加进结构体
71 double latitude; /**< Latitude in degrees. */
72 double longitude; /**< Longitude in degrees. */
73 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
74 float speed; /**< Speed in meters per second. */
75 float bearing; /**< Heading in degrees. */ //功能暂未实现,可不用添加进结构体
76 float accuracy; /**< Expected accuracy in meters. */ //功能暂未实现,可不用添加进结构体
77 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
78 int32_t is_indoor; /**< Location is indoors. */ //功能暂未实现,可不用添加进结构体
79 float floor_number; /**< Indicates the floor number. */
80}mopen_location_info_t;//功能暂未实现,可不用添加进结构体
81
82
83typedef struct {
84 uint32_t flags;
85 double latitude; /**< Latitude in degrees. */
86 double longitude; /**< Longitude in degrees. */
87 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
88 float speed; /**< Speed in meters per second. */
89 float bearing; /**< Heading in degrees. */
90 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
91} mbtk_gnss_location_info_t;
92
zw.wang581aab12025-05-28 19:43:53 +080093typedef struct{
94 GSW_GNSS_MODE_CONFIGURATION start_mode;
95 gnss_freq_type freq;
96 gsw_gnss_cb callback;
97}gsw_gnss_init_configure_t;
98
b.liu68a94c92025-05-24 12:53:41 +080099typedef enum{
100 MODE_GPS = 1, /**< GPS only */
101 MODE_BEIDOU, /**< BEIDOU only*/
102 MODE_GPS_BEIDOU, /**< GPS+BEIDOU */
103 MODE_GLONASS, /**< GLONASS only */
104 MODE_GPS_GLONASS, /**< GPS+GLONASS */
105 MODE_GLONASS_BEIDOU, /**< GLONASS+BEIDOU */ /* The type does not support this type */
106 MODE_GPS_GLONASS_BEIDOU, /**< GPS+GLONASS+BEIDOU */ /* The type does not support this type */
107 MODE_GALILEO, /**< GALILEO only */
108 MODE_GPS_GALILEO, /**< GPS+GALILEO */
109 MODE_BEIDOU_GALILEO, /**< BEIDOU+GALILEO */
110 MODE_GPS_BEIDOU_GALILEO, /**< GPS+BEIDOU+GALILEO */
111 MODE_GLONASS_GALILEO, /**< GLONASS+GALILEO */
112 MODE_GPS_GLONASS_GALILEO, /**< GPS+GLONASS+GALILEO */
113 MODE_BEIDOU_GLONASS_GALILEO, /**< BEIDOU+GLONASS+GALILEO */ /* The type does not support this type */
114 MODE_END = -1, /**< init value */
115}GSW_GNSS_MODE_CONFIGURATION_HD;
116
zw.wangbe05b922025-07-14 18:37:51 +0800117typedef enum{
118 NO_DEVICE = 0,
119 HD8122,
120 HD8040D,
121}GSW_DEVICE;
b.liu68a94c92025-05-24 12:53:41 +0800122
zw.wangbe05b922025-07-14 18:37:51 +0800123typedef struct {
124 int fd;
125 GSW_DEVICE got_hd8;
126} rx_ctx;
127
rx.xieee9ec322025-08-22 05:43:14 -0700128typedef struct {
129 int fd;
130 char *buf_8040_1;
131 char *buf_8040_2;
132 char *buf_8040;
133} rx_ctx_8040;
134
zw.wangbe05b922025-07-14 18:37:51 +0800135static GSW_DEVICE gsw_device = NO_DEVICE;
b.liu68a94c92025-05-24 12:53:41 +0800136GSW_GNSS_MODE_CONFIGURATION_HD map_gnss_mode(GSW_GNSS_MODE_CONFIGURATION mode)
137{
138 switch (mode)
139 {
140 case GSW_MODE_GPS_GLONASS:
141 return MODE_GPS_GLONASS;
142 case GSW_MODE_GPS_BEIDOU:
143 return MODE_GPS_BEIDOU;
144 case GSW_MODE_GPS_GLONASS_BEIDOU:
145 return MODE_END;
146 case GSW_MODE_GPS:
147 return MODE_GPS;
148 case GSW_MODE_BEIDOU:
149 return MODE_BEIDOU;
150 case GSW_MODE_GLONASS:
151 return MODE_GLONASS;
152 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO:
153 return MODE_END;
154 case GSW_MODE_GPS_GALILEO:
155 return MODE_GPS_GALILEO;
156 case GSW_MODE_GPS_GLONASS_GALILEO:
157 return MODE_GPS_GLONASS_GALILEO;
158 case GSW_MODE_GPS_GALILEO_ONLY:
159 return MODE_GALILEO;
160 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
161 return MODE_END;
162 case GSW_MODE_GNSS_END:
163 return MODE_END;
164 default:
165 return MODE_END;
166 }
167}
168
rx.xieee9ec322025-08-22 05:43:14 -0700169static void *rx_thread_8040(void *arg)
170{
171 rx_ctx_8040 *c = (rx_ctx_8040 *)arg;
172 char buf[128];
173 ssize_t n;
174 time_t end = time(NULL) + 1;//1s
175
176 while (time(NULL) < end) {
177 n = read(c->fd, buf, sizeof(buf));
178 if (n > 0 && memmem(buf, n, "HD8040D", 7))
179 {
180 int start_index = 6;
181
182 int part1_start = start_index;
183 int part1_end = 19;
184 int part1_len = part1_end - part1_start + 1;
185
186 int part2_start = 22;
187 int part2_end = 37;
188 int part2_len = part2_end - part2_start + 1;
189
190 if (c->buf_8040_1 != NULL)
191 {
192 free(c->buf_8040_1);
193 c->buf_8040_1 = NULL;
194 }
195
196 c->buf_8040_1 = (char *)malloc(part1_len + 1);
197 if (c->buf_8040_1 != NULL)
198 {
199 memcpy(c->buf_8040_1, buf + part1_start, part1_len);
200 c->buf_8040_1[part1_len] = '\0';
201 }
202
203 if (c->buf_8040_2 != NULL)
204 {
205 free(c->buf_8040_2);
206 c->buf_8040_2 = NULL;
207 }
208
209 c->buf_8040_2 = (char *)malloc(part2_len + 1);
210 if (c->buf_8040_2 != NULL)
211 {
212 memcpy(c->buf_8040_2, buf + part2_start, part2_len);
213 c->buf_8040_2[part2_len] = '\0';
214 }
215
216 if (c->buf_8040_1 != NULL && c->buf_8040_2 != NULL)
217 {
218 if (c->buf_8040 != NULL)
219 {
220 free(c->buf_8040);
221 c->buf_8040 = NULL;
222 }
223
224 int total_len = strlen(c->buf_8040_1) + strlen(c->buf_8040_2) + 1;
225 c->buf_8040 = (char *)malloc(total_len);
226 if (c->buf_8040 != NULL)
227 {
228 strcpy(c->buf_8040, c->buf_8040_1);
229 strcat(c->buf_8040, c->buf_8040_2);
230 }
231 }
232 else
233 {
234 LOGE(GSW_GNSS, "Failed to extract version parts");
235 }
236 break;
237 }
238 }
239 return NULL;
240}
241
zw.wangbe05b922025-07-14 18:37:51 +0800242static void *rx_thread(void *arg)
243{
244 rx_ctx *c = (rx_ctx *)arg;
245 char buf[128];
246 ssize_t n;
247 time_t end = time(NULL) + 1; /* 1 秒超时 */
zw.wangbe05b922025-07-14 18:37:51 +0800248 while (time(NULL) < end) {
249 n = read(c->fd, buf, sizeof(buf));
250 if (n > 0 && memmem(buf, n, "HD8040D", 7)) {
251 c->got_hd8 = 2;
252 break;
253 }
254 else if (n > 0 && memmem(buf, n, "HD812", 5)) {
255 c->got_hd8 = 1;
256 break;
257 }
258 }
rx.xieee9ec322025-08-22 05:43:14 -0700259
zw.wangbe05b922025-07-14 18:37:51 +0800260 return NULL;
261}
262
263static int send_and_wait(int fd)
264{
265 int ret;
266 pthread_t tid;
267 rx_ctx ctx = { .fd = fd, .got_hd8 = NO_DEVICE };
268
269 pthread_create(&tid, NULL, rx_thread, &ctx);
270
271 unsigned char tx[8] = {0xF1,0xD9,0x0A,0x04,0x00,0x00,0x0E,0x34};
272 ret = write(fd, tx, sizeof(tx));
273 if(ret < 0)
274 {
zw.wangbd342b92025-07-21 11:24:16 +0800275 LOGE(GSW_GNSS,"[GSW_gnss] send_and_wait write fail.ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800276 }
277 pthread_join(tid, NULL);
278 return ctx.got_hd8;
279}
280
281static int get_gnss_device_version(void)
282{
283 int fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY);
284 if (fd < 0) { perror("open"); return 1; }
285 gsw_device = send_and_wait(fd);
286 close(fd);
287 return gsw_device;
288}
289
rx.xieee9ec322025-08-22 05:43:14 -0700290
b.liu68a94c92025-05-24 12:53:41 +0800291int mbtk_gnss_set_VTG()
292{
293 int ret;
zw.wang57f3a9f2025-07-10 14:26:52 +0800294 ret = system("/usr/sbin/gnss_gpio.sh VTG > /dev/null 2>&1");
b.liu68a94c92025-05-24 12:53:41 +0800295 if(ret != 0)
296 {
zw.wangbd342b92025-07-21 11:24:16 +0800297 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_set_VTG on fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700298 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800299 }
300 return GSW_HAL_SUCCESS;
301}
302
zw.wangbe05b922025-07-14 18:37:51 +0800303static int HD8040D_gsw_gnss_set_freq(int freq)
304{
305 int ret;
306 char cmd[64] = {0};
307 switch (freq)
308 {
309 case 1:
310 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "1HZ");
311 break;
312 case 5:
313 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "5HZ");
314 break;
315 case 10:
316 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "10HZ");
317 break;
318 default:
319 return GSW_HAL_NORMAL_FAIL;
320 break;
321 }
322 ret = system(cmd);
323 if(ret != 0)
324 {
zw.wangbd342b92025-07-21 11:24:16 +0800325 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh GSW_HD8040D mode fail.ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800326 return GSW_HAL_NORMAL_FAIL;
327 }
328 return ret;
329}
b.liu68a94c92025-05-24 12:53:41 +0800330/**
331 * @brief SDK interface to set gnss sampling frequency, support 1Hz、2Hz、5Hz
332 * @param [in] freq
333 * @retval 0: success
334 * @retval other: fail
335 */
336int gsw_gnss_set_freq(int freq)
337{
zw.wangbc534c02025-06-26 09:31:44 +0800338 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700339 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800340
b.liu68a94c92025-05-24 12:53:41 +0800341 int ret;
342 if (!strated)
343 {
344 gnss_freq = freq;
345 return GSW_HAL_SUCCESS;
346 }
zw.wangbe05b922025-07-14 18:37:51 +0800347 if(gsw_device == NO_DEVICE)
348 {
349 ret = get_gnss_device_version();
zw.wangbd342b92025-07-21 11:24:16 +0800350 LOGD(GSW_GNSS,"[GSW_gnss] get_gnss_device_version ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800351 }
352 if(gsw_device == HD8040D)
353 {
354 ret = HD8040D_gsw_gnss_set_freq(freq);
355 return ret;
356 }
b.liu68a94c92025-05-24 12:53:41 +0800357 char param_buf[32] = {0};
358 snprintf(param_buf, 32, "$FREQCFG,%d", freq);
359 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
360 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
361 if(ret != 0)
362 {
zw.wangbd342b92025-07-21 11:24:16 +0800363 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700364 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800365 }
366 return GSW_HAL_SUCCESS;
367}
368
zw.wangbe05b922025-07-14 18:37:51 +0800369static int32_t HD8040D_gsw_gnss_set_start_mode(GSW_GNSS_MODE_CONFIGURATION start_mode)
370{
371 int ret;
372 char cmd[64] = {0};
373 switch (start_mode)
374 {
375 case GSW_MODE_GPS_GLONASS:
376 return GSW_HAL_NORMAL_FAIL;
377 break;
378 case GSW_MODE_GPS_BEIDOU:
379 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GPS_BD_DUAL");
380 break;
381 case GSW_MODE_GPS_GLONASS_BEIDOU:
382 return GSW_HAL_NORMAL_FAIL;
383 break;
384 case GSW_MODE_GPS:
385 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GPS_L1L5");
386 break;
387 case GSW_MODE_BEIDOU:
388 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_BD_B1I_B1C_B2A");
389 break;
390 case GSW_MODE_GLONASS:
391 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GALILEO_E1_E5A");
392 break;
393 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO:
394 return GSW_HAL_NORMAL_FAIL;
395 break;
396 case GSW_MODE_GPS_GALILEO:
397 return GSW_HAL_NORMAL_FAIL;
398 break;
399 case GSW_MODE_GPS_GLONASS_GALILEO:
400 return GSW_HAL_NORMAL_FAIL;
401 break;
402 case GSW_MODE_GPS_GALILEO_ONLY:
403 return GSW_HAL_NORMAL_FAIL;
404 break;
405 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
406 return GSW_HAL_NORMAL_FAIL;
407 break;
408 case GSW_MODE_GNSS_END:
409 return GSW_HAL_NORMAL_FAIL;
410 break;
411 default:
412 return GSW_HAL_NORMAL_FAIL;
413 break;
414 }
415 ret = system(cmd);
416 if(ret != 0)
417 {
zw.wangbd342b92025-07-21 11:24:16 +0800418 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh GSW_HD8040D mode fail.ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800419 return GSW_HAL_NORMAL_FAIL;
420 }
421 return ret;
422}
423
b.liu68a94c92025-05-24 12:53:41 +0800424/**
425 * @brief SDK interface to set gnss start mode,specific mode refreence GSW_HAL_GNSS_MODE_CONFIGURATION
426 * @param [in] start_mode
427 * @retval 0: success
428 * @retval other: fail
429 */
hong.liud2417072025-06-27 07:10:37 -0700430int32_t gsw_gnss_set_start_mode(GSW_GNSS_MODE_CONFIGURATION start_mode)
b.liu68a94c92025-05-24 12:53:41 +0800431{
zw.wangbc534c02025-06-26 09:31:44 +0800432 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700433 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800434 int ret;
435 if (!strated)
436 {
437 gnss_startmode = start_mode;
438 return GSW_HAL_SUCCESS;
439 }
zw.wangbe05b922025-07-14 18:37:51 +0800440 if(gsw_device == NO_DEVICE)
441 {
442 ret = get_gnss_device_version();
zw.wangbd342b92025-07-21 11:24:16 +0800443 LOGD(GSW_GNSS,"[GSW_gnss] get_gnss_device_version ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800444 }
445 if(gsw_device == HD8040D)
446 {
447 ret = HD8040D_gsw_gnss_set_start_mode(start_mode);
448 return ret;
449 }
b.liu68a94c92025-05-24 12:53:41 +0800450 char param_buf[32] = {0};
451 snprintf(param_buf, 32, "$SYSCFG,%d", map_gnss_mode(start_mode));
452 if(map_gnss_mode(start_mode) == -1)
453 {
zw.wangbd342b92025-07-21 11:24:16 +0800454 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_start_mode con't support");
hong.liud2417072025-06-27 07:10:37 -0700455 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800456 }
457 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
458 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
459 if(ret != 0)
460 {
zw.wangbd342b92025-07-21 11:24:16 +0800461 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700462 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800463 }
464 return GSW_HAL_SUCCESS;
465}
466
467/**
468 * @brief SDK interface to set EPO switch if open or close
469 * @param [in] switch_op
470 * @retval 0: success
471 * @retval other: fail
472 */
hong.liud2417072025-06-27 07:10:37 -0700473int32_t gsw_gnss_epo_switch(GSW_CONF_SWITCH switch_op)
b.liu68a94c92025-05-24 12:53:41 +0800474{
zw.wangbc534c02025-06-26 09:31:44 +0800475 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700476 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800477 int ret;
478 if (!strated)
479 {
480 gnss_switch_op = switch_op;
481 return GSW_HAL_SUCCESS;
482 }
483
484 if(switch_op)
485 {
486 mbtk_gnss_eph_download=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_download");
487 ret = mbtk_gnss_eph_download(QSER_GNSS_TIMEOUT);
488 if(ret != 0)
489 {
zw.wangbd342b92025-07-21 11:24:16 +0800490 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_eph_download fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700491 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800492 }
493 mbtk_gnss_eph_inject=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_inject");
494 ret = mbtk_gnss_eph_inject(QSER_GNSS_TIMEOUT);
495 if(ret != 0)
496 {
zw.wangbd342b92025-07-21 11:24:16 +0800497 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_eph_inject fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700498 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800499 }
500 }
501 return GSW_HAL_SUCCESS;
502}
503
504static void gnss_callback(uint32_t ind_type, const void* data, uint32_t data_len)
505{
506 if(data == NULL || data_len <= 0)
507 {
zw.wangbd342b92025-07-21 11:24:16 +0800508 LOGE(GSW_GNSS,"[GSW_gnss] data is NULL.");
b.liu68a94c92025-05-24 12:53:41 +0800509 return;
510 }
511
512 if(gsw_cb == NULL)
513 {
zw.wangbd342b92025-07-21 11:24:16 +0800514 //LOGE(GSW_GNSS,"[qser_gnss] qser_gnss_callback is NULL.");
b.liu68a94c92025-05-24 12:53:41 +0800515 return;
516 }
517
zw.wanga5250d62025-06-13 16:01:34 +0800518 if(ind_type == MBTK_GNSS_IND_LOCATION && gsw_cb->gsw_location_cb != NULL) {
b.liu68a94c92025-05-24 12:53:41 +0800519 if(data_len != sizeof(mbtk_gnss_location_info_t))
520 {
zw.wangbd342b92025-07-21 11:24:16 +0800521 LOGE(GSW_GNSS,"[GSW_gnss] data size error");
b.liu68a94c92025-05-24 12:53:41 +0800522 return;
523 }
524 GSW_GNSS_LOCATION_EXT_T gsw_location;
hong.liud2417072025-06-27 07:10:37 -0700525 GSW_GNSS_LOCATION_T gsw_location_t = {0};
b.liu68a94c92025-05-24 12:53:41 +0800526 mbtk_gnss_location_info_t *locl_info = (mbtk_gnss_location_info_t *)data;
527 gsw_location_t.altitude = locl_info->altitude;
528 gsw_location_t.latitude = locl_info->latitude;
529 gsw_location_t.longitude = locl_info->longitude;
530 gsw_location_t.speed = locl_info->speed;
531 gsw_location_t.bearing = locl_info->bearing;
532 gsw_location_t.timestamp = locl_info->timestamp;
zw.wanga5250d62025-06-13 16:01:34 +0800533 gsw_location_t.flags = locl_info->flags;
b.liu68a94c92025-05-24 12:53:41 +0800534 gsw_location.legacyLocation = gsw_location_t;
535 gsw_cb->gsw_location_cb(&gsw_location);
zw.wanga5250d62025-06-13 16:01:34 +0800536 } else if(ind_type == MBTK_GNSS_IND_NMEA && gsw_cb->gsw_nmea_cb != NULL) {
b.liu68a94c92025-05-24 12:53:41 +0800537 mopen_gnss_nmea_info_t qser_nmea = {0};
538 memset(&qser_nmea, 0x0, sizeof(mopen_gnss_nmea_info_t));
539 qser_nmea.length = data_len;
540 memcpy(qser_nmea.nmea, (char *)data, data_len);
541 //qser_nmea.timestamp = qser_get_gnss_time_sec(data, data_len);
542 gsw_cb->gsw_nmea_cb(data,data_len);
543 } else {
zw.wangbd342b92025-07-21 11:24:16 +0800544 LOGD(GSW_GNSS,"Unknown IND : %d\n", ind_type);
b.liu68a94c92025-05-24 12:53:41 +0800545 }
546}
547
hong.liud2417072025-06-27 07:10:37 -0700548int32_t gsw_gnss_init(void)
b.liu68a94c92025-05-24 12:53:41 +0800549{
lichengzhanga7089172025-07-01 20:41:46 +0800550 int ret;
b.liu68a94c92025-05-24 12:53:41 +0800551 if(!inited)
552 {
lichengzhanga7089172025-07-01 20:41:46 +0800553 ret = system("serial_atcmd AT*IMLCONFIG=13");
554 if(ret != 0)
555 {
zw.wangbd342b92025-07-21 11:24:16 +0800556 LOGE(GSW_GNSS,"serial_atcmd fail\n");
lichengzhanga7089172025-07-01 20:41:46 +0800557 return GSW_HAL_NORMAL_FAIL;
558 }
zw.wang1907e8f2025-07-01 16:26:39 +0800559 if(dlHandle_gnss == NULL)
zw.wangbd342b92025-07-21 11:24:16 +0800560 dlHandle_gnss = dlopen(lynqLib_gnss, RTLD_NOW);;
561 if(dlHandle_gnss == NULL)
b.liu68a94c92025-05-24 12:53:41 +0800562 {
hong.liud2417072025-06-27 07:10:37 -0700563 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800564 }
565 mbtk_gnss_init=(int(*)(mbtk_gnss_callback_func))dlsym(dlHandle_gnss, "mbtk_gnss_init");
566 ret = mbtk_gnss_init(gnss_callback);
567 if(ret == 0)
568 {
569 mbtk_gnss_ind_set=(int(*)(uint32_t ,int))dlsym(dlHandle_gnss, "mbtk_gnss_ind_set");
zw.wanga5250d62025-06-13 16:01:34 +0800570 ret = mbtk_gnss_ind_set(MBTK_GNSS_IND_NMEA |MBTK_GNSS_IND_LOCATION, QSER_GNSS_TIMEOUT);
b.liu68a94c92025-05-24 12:53:41 +0800571 if(ret == 0)
572 {
573 inited = true;
574 }
575 else
576 {
zw.wangbd342b92025-07-21 11:24:16 +0800577 LOGE(GSW_GNSS,"[GSW_gnss] init mbtk_gnss_ind_set() fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700578 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800579 }
580 }
581 else
582 {
zw.wangbd342b92025-07-21 11:24:16 +0800583 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_init() fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700584 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800585 }
586 }
587
588 return GSW_HAL_SUCCESS;
589}
590
591/**
592 * @brief SDK interface to registered callback function
593 * @param [in] callback
594 * @retval 0: success
595 * @retval other: fail
596 */
hong.liud2417072025-06-27 07:10:37 -0700597int32_t gsw_gnss_reg_cb_group(gsw_gnss_cb callback)
b.liu68a94c92025-05-24 12:53:41 +0800598{
zw.wangbc534c02025-06-26 09:31:44 +0800599 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700600 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800601 if(callback.gsw_location_cb == NULL && callback.gsw_nmea_cb == NULL)
602 {
zw.wangbd342b92025-07-21 11:24:16 +0800603 LOGE(GSW_GNSS,"[GSW_gnss] handler_ptr is NULL.");
hong.liud2417072025-06-27 07:10:37 -0700604 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800605 }
606 if (gsw_cb == NULL)
607 {
608 gsw_cb = (gsw_gnss_cb *)malloc(sizeof(gsw_gnss_cb));
609 if (gsw_cb == NULL)
610 {
zw.wangbd342b92025-07-21 11:24:16 +0800611 LOGE(GSW_GNSS,"[GSW_gnss] Memory allocation failed.");
hong.liud2417072025-06-27 07:10:37 -0700612 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800613 }
614 }
615 gsw_cb->gsw_location_cb = callback.gsw_location_cb;
616 gsw_cb->gsw_nmea_cb = callback.gsw_nmea_cb;
617 return GSW_HAL_SUCCESS;
618}
619/**
620 * @brief SDK interface to start gnss
621 * @param
622 * @retval 0: success
623 * @retval other: fail
624 */
hong.liud2417072025-06-27 07:10:37 -0700625int32_t gsw_gnss_start(void)
b.liu68a94c92025-05-24 12:53:41 +0800626{
627 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800628 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700629 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800630 ret = system("/usr/sbin/gnss_gpio.sh on > /dev/null 2>&1");
631 if(ret != 0)
632 {
zw.wangbd342b92025-07-21 11:24:16 +0800633 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh on fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700634 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800635 }
zw.wang57f3a9f2025-07-10 14:26:52 +0800636 // 记录mbtk_gnss_open前的时间戳
637 struct timespec start_time;
638 if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0) {
zw.wangbd342b92025-07-21 11:24:16 +0800639 LOGE(GSW_GNSS,"[GSW_gnss] Failed to get start time");
zw.wang57f3a9f2025-07-10 14:26:52 +0800640 return GSW_HAL_NORMAL_FAIL;
641 }
642
b.liu68a94c92025-05-24 12:53:41 +0800643 mbtk_gnss_open=(int(*)(int,int))dlsym(dlHandle_gnss, "mbtk_gnss_open");
644 ret = mbtk_gnss_open(255, QSER_GNSS_TIMEOUT);
645 if(ret != 0)
646 {
zw.wangbd342b92025-07-21 11:24:16 +0800647 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_open is error.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700648 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800649 }
zw.wang89c18242025-06-24 19:07:10 +0800650
b.liu68a94c92025-05-24 12:53:41 +0800651 strated = true;
zw.wang7aa34062025-06-27 17:54:55 +0800652 /*
b.liu68a94c92025-05-24 12:53:41 +0800653 if (gnss_freq > 0)
654 gsw_gnss_set_freq(gnss_freq);
655 if (gnss_startmode >= 0)
656 gsw_gnss_set_start_mode(gnss_startmode);
657 if (gnss_switch_op > 0)
658 gsw_gnss_epo_switch(gnss_switch_op);
zw.wang7aa34062025-06-27 17:54:55 +0800659 */
zw.wang57f3a9f2025-07-10 14:26:52 +0800660
661 // 记录mbtk_gnss_set_VTG前的时间戳并计算等待时间
662 struct timespec end_time;
663 if (clock_gettime(CLOCK_MONOTONIC, &end_time) != 0) {
zw.wangbd342b92025-07-21 11:24:16 +0800664 LOGE(GSW_GNSS,"[GSW_gnss] Failed to get end time");
zw.wang57f3a9f2025-07-10 14:26:52 +0800665 return GSW_HAL_NORMAL_FAIL;
666 }
667 long start_ms = start_time.tv_sec * 1000 + start_time.tv_nsec / 1000000;
668 long end_ms = end_time.tv_sec * 1000 + end_time.tv_nsec / 1000000;
669 long diff_ms = end_ms - start_ms;
670 if (diff_ms < 700) {
671 long wait_ms = 700 - diff_ms;
672 usleep(wait_ms * 1000); // 转换为微秒等待
673 }
674
b.liu68a94c92025-05-24 12:53:41 +0800675 mbtk_gnss_set_VTG();
676
677 return GSW_HAL_SUCCESS;
678}
679
zw.wang57f3a9f2025-07-10 14:26:52 +0800680
b.liu68a94c92025-05-24 12:53:41 +0800681/**
682 * @brief SDK interface to stop gnss
683 * @param
684 * @retval 0: success
685 * @retval other: fail
686 */
hong.liud2417072025-06-27 07:10:37 -0700687int32_t gsw_gnss_stop(void)
b.liu68a94c92025-05-24 12:53:41 +0800688{
689 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800690 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700691 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800692 mbtk_gnss_close=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_close");
693 ret = mbtk_gnss_close(QSER_GNSS_TIMEOUT);
694 if(ret != 0)
695 {
zw.wangbd342b92025-07-21 11:24:16 +0800696 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_close is error.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700697 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800698 }
zw.wangbc534c02025-06-26 09:31:44 +0800699 ret = system("/usr/sbin/gnss_gpio.sh off > /dev/null 2>&1");
700 if(ret != 0)
701 {
zw.wangbd342b92025-07-21 11:24:16 +0800702 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh off fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700703 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800704 }
b.liu68a94c92025-05-24 12:53:41 +0800705 strated = false;
706 return GSW_HAL_SUCCESS;
707}
708
709/**
710 * @brief SDK interface to de initialization gnss
711 * @param
712 * @retval 0: success
713 * @retval other: fail
714 */
hong.liud2417072025-06-27 07:10:37 -0700715int32_t gsw_gnss_deinit(void)
b.liu68a94c92025-05-24 12:53:41 +0800716{
717 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800718 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700719 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800720 if(inited)
721 {
lichengzhanga7089172025-07-01 20:41:46 +0800722 ret = system("serial_atcmd AT*IMLCONFIG=12");
723 if(ret != 0)
724 {
zw.wangbd342b92025-07-21 11:24:16 +0800725 LOGE(GSW_GNSS,"serial_atcmd fail\n");
lichengzhanga7089172025-07-01 20:41:46 +0800726 return GSW_HAL_NORMAL_FAIL;
727 }
b.liu68a94c92025-05-24 12:53:41 +0800728 mbtk_gnss_deinit=(int(*)())dlsym(dlHandle_gnss, "mbtk_gnss_deinit");
729 ret = mbtk_gnss_deinit();
730 if(ret == 0)
731 {
732 inited = false;
733 }
734 else
735 {
zw.wangbd342b92025-07-21 11:24:16 +0800736 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_deinit() fail.ret = [%d]", ret);
zw.wang1907e8f2025-07-01 16:26:39 +0800737 /*
b.liu68a94c92025-05-24 12:53:41 +0800738 dlclose(dlHandle_gnss);
739 dlHandle_gnss = NULL;
zw.wang1907e8f2025-07-01 16:26:39 +0800740 */
hong.liud2417072025-06-27 07:10:37 -0700741 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800742 }
743 }
744
zw.wang1907e8f2025-07-01 16:26:39 +0800745 /*
b.liu68a94c92025-05-24 12:53:41 +0800746 dlclose(dlHandle_gnss);
747 dlHandle_gnss = NULL;
zw.wang1907e8f2025-07-01 16:26:39 +0800748 */
b.liu68a94c92025-05-24 12:53:41 +0800749 gnss_freq = -1;
750 gnss_startmode = -1;
751 gnss_switch_op = -1;
752 return GSW_HAL_SUCCESS;
753}
754
zw.wang75e98ea2025-05-29 17:57:38 +0800755int gsw_gnss_add_lib(void)
756{
757 return GSW_HAL_SUCCESS;
758}
b.liu68a94c92025-05-24 12:53:41 +0800759
760/**
761 * @brief SDK interface to enable XTRA switch
762 * @param [in] state
763 * @retval 0: success
764 * @retval other: fail
765 */
hong.liud2417072025-06-27 07:10:37 -0700766int32_t gsw_gnss_xtra_is_enable(gsw_xtra_state_e state)
b.liu68a94c92025-05-24 12:53:41 +0800767{
768 return GSW_HAL_SUCCESS;
769}
770
771/**
772 * @brief SDK interface to delete aiding data,delete aiding data for cold start(1-H,2-W,3-C)
773 * @param [in] switch_op
774 * @retval 0: success
775 * @retval other: fail
776 */
hong.liud2417072025-06-27 07:10:37 -0700777int32_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 +0800778{
zw.wangbc534c02025-06-26 09:31:44 +0800779 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700780 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800781 int ret;
782 char param_buf[32] = {0};
783 snprintf(param_buf, 32, "$RESET,%u", flags);
784 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
785 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
786 if(ret != 0)
787 {
zw.wangbd342b92025-07-21 11:24:16 +0800788 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700789 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800790 }
791 return GSW_HAL_SUCCESS;
792}
793
794/**
795 * @brief init and configure gps
796 * @param [in] init_configure
797 * @retval 0: success
798 * @retval other: fail
799 */
hong.liud2417072025-06-27 07:10:37 -0700800int32_t gsw_gnss_init_configure_gps(gsw_gnss_init_configure_t init_configure)
b.liu68a94c92025-05-24 12:53:41 +0800801{
802 return GSW_HAL_SUCCESS;
803}
hong.liud2417072025-06-27 07:10:37 -0700804
805int gsw_gnss_get_tail_nmea_type(char *tail_type, int len)
806{
807 if(NULL == tail_type){
zw.wangbd342b92025-07-21 11:24:16 +0800808 LOGE(GSW_GNSS,"get_tail_nmea_type fail, tail_type is NULL");
hong.liud2417072025-06-27 07:10:37 -0700809 return GSW_HAL_ERROR_GNSS_FAIL;
810 }
811
812 if(len >= 3){
813 strcpy(tail_type, "RMC");
814 return GSW_HAL_GNSS_SUCCESS;
815 }else{
zw.wangbd342b92025-07-21 11:24:16 +0800816 LOGE(GSW_GNSS,"get_tail_nmea_type fail, len[%d] is too short", len);
hong.liud2417072025-06-27 07:10:37 -0700817 return GSW_HAL_ERROR_GNSS_FAIL;
818 }
819}
rx.xie85d47ac2025-08-08 05:16:29 -0700820
rx.xie85d47ac2025-08-08 05:16:29 -0700821/**
822* @brief Start install gnss software
823* @param [in] char* file_path
824* @param [out] NULL
825* @retval GSW_HAL_SUCCESS\GSW_HAL_FAIL
826*/
827int gsw_update_gnss_start(const char *fw_path)
828{
rx.xieee9ec322025-08-22 05:43:14 -0700829 if (fw_path == NULL)
rx.xie85d47ac2025-08-08 05:16:29 -0700830 {
rx.xieee9ec322025-08-22 05:43:14 -0700831 LOGE(GSW_GNSS, "[qser_gnss] Input fw_path is null");
rx.xie85d47ac2025-08-08 05:16:29 -0700832 return GSW_HAL_NORMAL_FAIL;
833 }
834
rx.xieee9ec322025-08-22 05:43:14 -0700835 int ret;
836 mbtk_gnss_dl_ptr = (int(*)(const char *, int))dlsym(dlHandle_gnss, "mbtk_gnss_dl");
837
838 ret = mbtk_gnss_dl_ptr(fw_path, 60);
rx.xie85d47ac2025-08-08 05:16:29 -0700839 if(ret != 0)
840 {
rx.xieee9ec322025-08-22 05:43:14 -0700841 if(ret != 4)
842 {
843 LOGE(GSW_GNSS,"[qser_gnss] Firmware download failed. ret = [%d]", ret);
844 return GSW_HAL_NORMAL_FAIL;
845 }
846 else
847 {
848 LOGW(GSW_GNSS,"[qser_gnss] Firmware download warning (ignored). ret = [%d]", ret);
849 }
rx.xie85d47ac2025-08-08 05:16:29 -0700850 }
851 return GSW_HAL_SUCCESS;
852}
853
rx.xie85d47ac2025-08-08 05:16:29 -0700854/**
855* @brief get gnss version info
856* @param [in] NULL
857* @param [out] char* version_info
858* @retval GSW_HAL_SUCCESS\GSW_HAL_FAIL
859*/
860int32_t gsw_get_gnss_version_info(char* version_info)
861{
rx.xieee9ec322025-08-22 05:43:14 -0700862 if (version_info == NULL)
rx.xie85d47ac2025-08-08 05:16:29 -0700863 {
rx.xieee9ec322025-08-22 05:43:14 -0700864 LOGE(GSW_GNSS, "version_info is NULL");
865 return GSW_HAL_ERROR_GNSS_FAIL;
rx.xie85d47ac2025-08-08 05:16:29 -0700866 }
867
rx.xieee9ec322025-08-22 05:43:14 -0700868 int fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY);
869 if (fd < 0)
rx.xie85d47ac2025-08-08 05:16:29 -0700870 {
rx.xieee9ec322025-08-22 05:43:14 -0700871 LOGE(GSW_GNSS, "Failed to open /dev/ttyS3: %s", strerror(errno));
872 return GSW_HAL_ERROR_GNSS_FAIL;
rx.xie85d47ac2025-08-08 05:16:29 -0700873 }
874
rx.xieee9ec322025-08-22 05:43:14 -0700875 rx_ctx_8040 thread_args = {
876 .fd = fd,
877 .buf_8040 = NULL
878 };
879
880 pthread_t read_thread_8040;
881 if (pthread_create(&read_thread_8040, NULL, rx_thread_8040, &thread_args) != 0)
882 {
883 LOGE(GSW_GNSS, "Failed to create read thread");
884 close(fd);
885 return GSW_HAL_ERROR_GNSS_FAIL;
886 }
887
888 unsigned char tx_cmd[] = {0xF1, 0xD9, 0x0A, 0x04, 0x00, 0x00, 0x0E, 0x34};
889 int ret = write(fd, tx_cmd, sizeof(tx_cmd));
890 if (ret != sizeof(tx_cmd))
891 {
892 LOGE(GSW_GNSS, "[GSW_gnss] send_and_wait write fail.ret = [%d]", ret);
893 pthread_cancel(read_thread_8040);
894 close(fd);
895 return GSW_HAL_ERROR_GNSS_FAIL;
896 }
897
898 pthread_join(read_thread_8040, NULL);
899 close(fd);
900 if (thread_args.buf_8040 != NULL)
901 {
902 strncpy(version_info, thread_args.buf_8040, 128);
903 version_info[127] = '\0';
904 free(thread_args.buf_8040);
905 LOGE(GSW_GNSS, "Final version info: %s", version_info);
906 return GSW_HAL_SUCCESS;
907 }
908 else
909 {
910 LOGE(GSW_GNSS, "No data received or HD8040 not found");
911 return GSW_HAL_ERROR_GNSS_FAIL;
912 }
rx.xie85d47ac2025-08-08 05:16:29 -0700913}
914
915