blob: 73b31d7b3cc5f8623f30012cc3818c8434201b66 [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
zw.wangbd342b92025-07-21 11:24:16 +080024#include "gsw_log_interface.h"
l.yang6a42e4d2025-05-28 01:04:20 -070025#define GSW_GNSS "[HAL][GSW_GNSS]"
26
b.liu68a94c92025-05-24 12:53:41 +080027#define MOPEN_GNSS_NMEA_MAX_LENGTH 255 /** NMEA string maximum length. */
28static gsw_gnss_cb *gsw_cb = NULL;
29static bool inited = false;
30static bool strated = false;
31
32typedef void (*mbtk_gnss_callback_func)(uint32_t ind_type, const void* data, uint32_t data_len);
b.liu68a94c92025-05-24 12:53:41 +080033
34int (*mbtk_gnss_init)(mbtk_gnss_callback_func cb);
35int (*mbtk_gnss_deinit)();
36
37int (*mbtk_gnss_ind_set)(uint32_t ,int);
38int (*mbtk_gnss_open)(int, int);
39int (*mbtk_gnss_close)(int);
40int (*mbtk_gnss_setting)(const char *setting_cmd, int);
41
42int (*mbtk_gnss_eph_download)(int);
43int (*mbtk_gnss_eph_inject)(int);
rx.xie85d47ac2025-08-08 05:16:29 -070044int (*mbtk_gnss_dl_ptr)(const char *, int);
b.liu68a94c92025-05-24 12:53:41 +080045
46int gnss_freq = -1;
47GSW_GNSS_MODE_CONFIGURATION gnss_startmode = -1;
zw.wang581aab12025-05-28 19:43:53 +080048GSW_CONF_SWITCH gnss_switch_op = -1;
b.liu68a94c92025-05-24 12:53:41 +080049void *dlHandle_gnss;
50char *lynqLib_gnss = "/lib/libmbtk_lib.so";
51
52typedef enum
53{
54 E_MT_LOC_MSG_ID_LOCATION_INFO = 1, /**< pv_data = & mopen_location_info_t */
55 E_MT_LOC_MSG_ID_NMEA_INFO = 3, /**< pv_data = & mopen_gnss_nmea_info_t */
56} e_msg_id_t;
57
58typedef struct
59{
60 int64_t timestamp; /**< System Timestamp, marked for when got the nmea data */
61 int length; /**< NMEA string length. */
62 char nmea[MOPEN_GNSS_NMEA_MAX_LENGTH + 1]; /**< NMEA string.*/
63}mopen_gnss_nmea_info_t; /* Message */
64
65typedef struct
66{
67 uint32_t size; /**< Set to the size of mcm_gps_location_t. */
68 int flags; /**< Contains GPS location flags bits. */
69 int position_source; /**< Provider indicator for HYBRID or GPS. */ //功能暂未实现,可不用添加进结构体
70 double latitude; /**< Latitude in degrees. */
71 double longitude; /**< Longitude in degrees. */
72 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
73 float speed; /**< Speed in meters per second. */
74 float bearing; /**< Heading in degrees. */ //功能暂未实现,可不用添加进结构体
75 float accuracy; /**< Expected accuracy in meters. */ //功能暂未实现,可不用添加进结构体
76 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
77 int32_t is_indoor; /**< Location is indoors. */ //功能暂未实现,可不用添加进结构体
78 float floor_number; /**< Indicates the floor number. */
79}mopen_location_info_t;//功能暂未实现,可不用添加进结构体
80
81
82typedef struct {
83 uint32_t flags;
84 double latitude; /**< Latitude in degrees. */
85 double longitude; /**< Longitude in degrees. */
86 double altitude; /**< Altitude in meters above the WGS 84 reference ellipsoid. */
87 float speed; /**< Speed in meters per second. */
88 float bearing; /**< Heading in degrees. */
89 int64_t timestamp; /**< Timestamp for the location fix in UTC million-second base. */
90} mbtk_gnss_location_info_t;
91
zw.wang581aab12025-05-28 19:43:53 +080092typedef struct{
93 GSW_GNSS_MODE_CONFIGURATION start_mode;
94 gnss_freq_type freq;
95 gsw_gnss_cb callback;
96}gsw_gnss_init_configure_t;
97
b.liu68a94c92025-05-24 12:53:41 +080098typedef enum{
99 MODE_GPS = 1, /**< GPS only */
100 MODE_BEIDOU, /**< BEIDOU only*/
101 MODE_GPS_BEIDOU, /**< GPS+BEIDOU */
102 MODE_GLONASS, /**< GLONASS only */
103 MODE_GPS_GLONASS, /**< GPS+GLONASS */
104 MODE_GLONASS_BEIDOU, /**< GLONASS+BEIDOU */ /* The type does not support this type */
105 MODE_GPS_GLONASS_BEIDOU, /**< GPS+GLONASS+BEIDOU */ /* The type does not support this type */
106 MODE_GALILEO, /**< GALILEO only */
107 MODE_GPS_GALILEO, /**< GPS+GALILEO */
108 MODE_BEIDOU_GALILEO, /**< BEIDOU+GALILEO */
109 MODE_GPS_BEIDOU_GALILEO, /**< GPS+BEIDOU+GALILEO */
110 MODE_GLONASS_GALILEO, /**< GLONASS+GALILEO */
111 MODE_GPS_GLONASS_GALILEO, /**< GPS+GLONASS+GALILEO */
112 MODE_BEIDOU_GLONASS_GALILEO, /**< BEIDOU+GLONASS+GALILEO */ /* The type does not support this type */
113 MODE_END = -1, /**< init value */
114}GSW_GNSS_MODE_CONFIGURATION_HD;
115
zw.wangbe05b922025-07-14 18:37:51 +0800116typedef enum{
117 NO_DEVICE = 0,
118 HD8122,
119 HD8040D,
120}GSW_DEVICE;
b.liu68a94c92025-05-24 12:53:41 +0800121
zw.wangbe05b922025-07-14 18:37:51 +0800122typedef struct {
123 int fd;
124 GSW_DEVICE got_hd8;
125} rx_ctx;
126
127static GSW_DEVICE gsw_device = NO_DEVICE;
b.liu68a94c92025-05-24 12:53:41 +0800128GSW_GNSS_MODE_CONFIGURATION_HD map_gnss_mode(GSW_GNSS_MODE_CONFIGURATION mode)
129{
130 switch (mode)
131 {
132 case GSW_MODE_GPS_GLONASS:
133 return MODE_GPS_GLONASS;
134 case GSW_MODE_GPS_BEIDOU:
135 return MODE_GPS_BEIDOU;
136 case GSW_MODE_GPS_GLONASS_BEIDOU:
137 return MODE_END;
138 case GSW_MODE_GPS:
139 return MODE_GPS;
140 case GSW_MODE_BEIDOU:
141 return MODE_BEIDOU;
142 case GSW_MODE_GLONASS:
143 return MODE_GLONASS;
144 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO:
145 return MODE_END;
146 case GSW_MODE_GPS_GALILEO:
147 return MODE_GPS_GALILEO;
148 case GSW_MODE_GPS_GLONASS_GALILEO:
149 return MODE_GPS_GLONASS_GALILEO;
150 case GSW_MODE_GPS_GALILEO_ONLY:
151 return MODE_GALILEO;
152 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
153 return MODE_END;
154 case GSW_MODE_GNSS_END:
155 return MODE_END;
156 default:
157 return MODE_END;
158 }
159}
160
zw.wangbe05b922025-07-14 18:37:51 +0800161static void *rx_thread(void *arg)
162{
163 rx_ctx *c = (rx_ctx *)arg;
164 char buf[128];
165 ssize_t n;
166 time_t end = time(NULL) + 1; /* 1 秒超时 */
167
168 while (time(NULL) < end) {
169 n = read(c->fd, buf, sizeof(buf));
170 if (n > 0 && memmem(buf, n, "HD8040D", 7)) {
171 c->got_hd8 = 2;
172 break;
173 }
174 else if (n > 0 && memmem(buf, n, "HD812", 5)) {
175 c->got_hd8 = 1;
176 break;
177 }
178 }
179 return NULL;
180}
181
182static int send_and_wait(int fd)
183{
184 int ret;
185 pthread_t tid;
186 rx_ctx ctx = { .fd = fd, .got_hd8 = NO_DEVICE };
187
188 pthread_create(&tid, NULL, rx_thread, &ctx);
189
190 unsigned char tx[8] = {0xF1,0xD9,0x0A,0x04,0x00,0x00,0x0E,0x34};
191 ret = write(fd, tx, sizeof(tx));
192 if(ret < 0)
193 {
zw.wangbd342b92025-07-21 11:24:16 +0800194 LOGE(GSW_GNSS,"[GSW_gnss] send_and_wait write fail.ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800195 }
196 pthread_join(tid, NULL);
197 return ctx.got_hd8;
198}
199
200static int get_gnss_device_version(void)
201{
202 int fd = open("/dev/ttyS3", O_RDWR | O_NOCTTY);
203 if (fd < 0) { perror("open"); return 1; }
204 gsw_device = send_and_wait(fd);
205 close(fd);
206 return gsw_device;
207}
208
b.liu68a94c92025-05-24 12:53:41 +0800209int mbtk_gnss_set_VTG()
210{
211 int ret;
zw.wang57f3a9f2025-07-10 14:26:52 +0800212 ret = system("/usr/sbin/gnss_gpio.sh VTG > /dev/null 2>&1");
b.liu68a94c92025-05-24 12:53:41 +0800213 if(ret != 0)
214 {
zw.wangbd342b92025-07-21 11:24:16 +0800215 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_set_VTG on fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700216 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800217 }
218 return GSW_HAL_SUCCESS;
219}
220
zw.wangbe05b922025-07-14 18:37:51 +0800221static int HD8040D_gsw_gnss_set_freq(int freq)
222{
223 int ret;
224 char cmd[64] = {0};
225 switch (freq)
226 {
227 case 1:
228 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "1HZ");
229 break;
230 case 5:
231 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "5HZ");
232 break;
233 case 10:
234 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "10HZ");
235 break;
236 default:
237 return GSW_HAL_NORMAL_FAIL;
238 break;
239 }
240 ret = system(cmd);
241 if(ret != 0)
242 {
zw.wangbd342b92025-07-21 11:24:16 +0800243 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh GSW_HD8040D mode fail.ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800244 return GSW_HAL_NORMAL_FAIL;
245 }
246 return ret;
247}
b.liu68a94c92025-05-24 12:53:41 +0800248/**
249 * @brief SDK interface to set gnss sampling frequency, support 1Hz、2Hz、5Hz
250 * @param [in] freq
251 * @retval 0: success
252 * @retval other: fail
253 */
254int gsw_gnss_set_freq(int freq)
255{
zw.wangbc534c02025-06-26 09:31:44 +0800256 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700257 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800258
b.liu68a94c92025-05-24 12:53:41 +0800259 int ret;
260 if (!strated)
261 {
262 gnss_freq = freq;
263 return GSW_HAL_SUCCESS;
264 }
zw.wangbe05b922025-07-14 18:37:51 +0800265 if(gsw_device == NO_DEVICE)
266 {
267 ret = get_gnss_device_version();
zw.wangbd342b92025-07-21 11:24:16 +0800268 LOGD(GSW_GNSS,"[GSW_gnss] get_gnss_device_version ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800269 }
270 if(gsw_device == HD8040D)
271 {
272 ret = HD8040D_gsw_gnss_set_freq(freq);
273 return ret;
274 }
b.liu68a94c92025-05-24 12:53:41 +0800275 char param_buf[32] = {0};
276 snprintf(param_buf, 32, "$FREQCFG,%d", freq);
277 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
278 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
279 if(ret != 0)
280 {
zw.wangbd342b92025-07-21 11:24:16 +0800281 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700282 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800283 }
284 return GSW_HAL_SUCCESS;
285}
286
zw.wangbe05b922025-07-14 18:37:51 +0800287static int32_t HD8040D_gsw_gnss_set_start_mode(GSW_GNSS_MODE_CONFIGURATION start_mode)
288{
289 int ret;
290 char cmd[64] = {0};
291 switch (start_mode)
292 {
293 case GSW_MODE_GPS_GLONASS:
294 return GSW_HAL_NORMAL_FAIL;
295 break;
296 case GSW_MODE_GPS_BEIDOU:
297 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GPS_BD_DUAL");
298 break;
299 case GSW_MODE_GPS_GLONASS_BEIDOU:
300 return GSW_HAL_NORMAL_FAIL;
301 break;
302 case GSW_MODE_GPS:
303 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GPS_L1L5");
304 break;
305 case GSW_MODE_BEIDOU:
306 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_BD_B1I_B1C_B2A");
307 break;
308 case GSW_MODE_GLONASS:
309 snprintf(cmd, sizeof(cmd), "/usr/sbin/gnss_gpio.sh %s > /dev/null 2>&1", "GSW_GALILEO_E1_E5A");
310 break;
311 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO:
312 return GSW_HAL_NORMAL_FAIL;
313 break;
314 case GSW_MODE_GPS_GALILEO:
315 return GSW_HAL_NORMAL_FAIL;
316 break;
317 case GSW_MODE_GPS_GLONASS_GALILEO:
318 return GSW_HAL_NORMAL_FAIL;
319 break;
320 case GSW_MODE_GPS_GALILEO_ONLY:
321 return GSW_HAL_NORMAL_FAIL;
322 break;
323 case GSW_MODE_GPS_GLONASS_BEIDOU_GALILEO_NAVIC:
324 return GSW_HAL_NORMAL_FAIL;
325 break;
326 case GSW_MODE_GNSS_END:
327 return GSW_HAL_NORMAL_FAIL;
328 break;
329 default:
330 return GSW_HAL_NORMAL_FAIL;
331 break;
332 }
333 ret = system(cmd);
334 if(ret != 0)
335 {
zw.wangbd342b92025-07-21 11:24:16 +0800336 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh GSW_HD8040D mode fail.ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800337 return GSW_HAL_NORMAL_FAIL;
338 }
339 return ret;
340}
341
b.liu68a94c92025-05-24 12:53:41 +0800342/**
343 * @brief SDK interface to set gnss start mode,specific mode refreence GSW_HAL_GNSS_MODE_CONFIGURATION
344 * @param [in] start_mode
345 * @retval 0: success
346 * @retval other: fail
347 */
hong.liud2417072025-06-27 07:10:37 -0700348int32_t gsw_gnss_set_start_mode(GSW_GNSS_MODE_CONFIGURATION start_mode)
b.liu68a94c92025-05-24 12:53:41 +0800349{
zw.wangbc534c02025-06-26 09:31:44 +0800350 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700351 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800352 int ret;
353 if (!strated)
354 {
355 gnss_startmode = start_mode;
356 return GSW_HAL_SUCCESS;
357 }
zw.wangbe05b922025-07-14 18:37:51 +0800358 if(gsw_device == NO_DEVICE)
359 {
360 ret = get_gnss_device_version();
zw.wangbd342b92025-07-21 11:24:16 +0800361 LOGD(GSW_GNSS,"[GSW_gnss] get_gnss_device_version ret = [%d]", ret);
zw.wangbe05b922025-07-14 18:37:51 +0800362 }
363 if(gsw_device == HD8040D)
364 {
365 ret = HD8040D_gsw_gnss_set_start_mode(start_mode);
366 return ret;
367 }
b.liu68a94c92025-05-24 12:53:41 +0800368 char param_buf[32] = {0};
369 snprintf(param_buf, 32, "$SYSCFG,%d", map_gnss_mode(start_mode));
370 if(map_gnss_mode(start_mode) == -1)
371 {
zw.wangbd342b92025-07-21 11:24:16 +0800372 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_start_mode con't support");
hong.liud2417072025-06-27 07:10:37 -0700373 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800374 }
375 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
376 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
377 if(ret != 0)
378 {
zw.wangbd342b92025-07-21 11:24:16 +0800379 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700380 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800381 }
382 return GSW_HAL_SUCCESS;
383}
384
385/**
386 * @brief SDK interface to set EPO switch if open or close
387 * @param [in] switch_op
388 * @retval 0: success
389 * @retval other: fail
390 */
hong.liud2417072025-06-27 07:10:37 -0700391int32_t gsw_gnss_epo_switch(GSW_CONF_SWITCH switch_op)
b.liu68a94c92025-05-24 12:53:41 +0800392{
zw.wangbc534c02025-06-26 09:31:44 +0800393 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700394 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800395 int ret;
396 if (!strated)
397 {
398 gnss_switch_op = switch_op;
399 return GSW_HAL_SUCCESS;
400 }
401
402 if(switch_op)
403 {
404 mbtk_gnss_eph_download=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_download");
405 ret = mbtk_gnss_eph_download(QSER_GNSS_TIMEOUT);
406 if(ret != 0)
407 {
zw.wangbd342b92025-07-21 11:24:16 +0800408 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_eph_download fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700409 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800410 }
411 mbtk_gnss_eph_inject=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_eph_inject");
412 ret = mbtk_gnss_eph_inject(QSER_GNSS_TIMEOUT);
413 if(ret != 0)
414 {
zw.wangbd342b92025-07-21 11:24:16 +0800415 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_eph_inject fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700416 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800417 }
418 }
419 return GSW_HAL_SUCCESS;
420}
421
422static void gnss_callback(uint32_t ind_type, const void* data, uint32_t data_len)
423{
424 if(data == NULL || data_len <= 0)
425 {
zw.wangbd342b92025-07-21 11:24:16 +0800426 LOGE(GSW_GNSS,"[GSW_gnss] data is NULL.");
b.liu68a94c92025-05-24 12:53:41 +0800427 return;
428 }
429
430 if(gsw_cb == NULL)
431 {
zw.wangbd342b92025-07-21 11:24:16 +0800432 //LOGE(GSW_GNSS,"[qser_gnss] qser_gnss_callback is NULL.");
b.liu68a94c92025-05-24 12:53:41 +0800433 return;
434 }
435
zw.wanga5250d62025-06-13 16:01:34 +0800436 if(ind_type == MBTK_GNSS_IND_LOCATION && gsw_cb->gsw_location_cb != NULL) {
b.liu68a94c92025-05-24 12:53:41 +0800437 if(data_len != sizeof(mbtk_gnss_location_info_t))
438 {
zw.wangbd342b92025-07-21 11:24:16 +0800439 LOGE(GSW_GNSS,"[GSW_gnss] data size error");
b.liu68a94c92025-05-24 12:53:41 +0800440 return;
441 }
442 GSW_GNSS_LOCATION_EXT_T gsw_location;
hong.liud2417072025-06-27 07:10:37 -0700443 GSW_GNSS_LOCATION_T gsw_location_t = {0};
b.liu68a94c92025-05-24 12:53:41 +0800444 mbtk_gnss_location_info_t *locl_info = (mbtk_gnss_location_info_t *)data;
445 gsw_location_t.altitude = locl_info->altitude;
446 gsw_location_t.latitude = locl_info->latitude;
447 gsw_location_t.longitude = locl_info->longitude;
448 gsw_location_t.speed = locl_info->speed;
449 gsw_location_t.bearing = locl_info->bearing;
450 gsw_location_t.timestamp = locl_info->timestamp;
zw.wanga5250d62025-06-13 16:01:34 +0800451 gsw_location_t.flags = locl_info->flags;
b.liu68a94c92025-05-24 12:53:41 +0800452 gsw_location.legacyLocation = gsw_location_t;
453 gsw_cb->gsw_location_cb(&gsw_location);
zw.wanga5250d62025-06-13 16:01:34 +0800454 } else if(ind_type == MBTK_GNSS_IND_NMEA && gsw_cb->gsw_nmea_cb != NULL) {
b.liu68a94c92025-05-24 12:53:41 +0800455 mopen_gnss_nmea_info_t qser_nmea = {0};
456 memset(&qser_nmea, 0x0, sizeof(mopen_gnss_nmea_info_t));
457 qser_nmea.length = data_len;
458 memcpy(qser_nmea.nmea, (char *)data, data_len);
459 //qser_nmea.timestamp = qser_get_gnss_time_sec(data, data_len);
460 gsw_cb->gsw_nmea_cb(data,data_len);
461 } else {
zw.wangbd342b92025-07-21 11:24:16 +0800462 LOGD(GSW_GNSS,"Unknown IND : %d\n", ind_type);
b.liu68a94c92025-05-24 12:53:41 +0800463 }
464}
465
hong.liud2417072025-06-27 07:10:37 -0700466int32_t gsw_gnss_init(void)
b.liu68a94c92025-05-24 12:53:41 +0800467{
lichengzhanga7089172025-07-01 20:41:46 +0800468 int ret;
b.liu68a94c92025-05-24 12:53:41 +0800469 if(!inited)
470 {
lichengzhanga7089172025-07-01 20:41:46 +0800471 ret = system("serial_atcmd AT*IMLCONFIG=13");
472 if(ret != 0)
473 {
zw.wangbd342b92025-07-21 11:24:16 +0800474 LOGE(GSW_GNSS,"serial_atcmd fail\n");
lichengzhanga7089172025-07-01 20:41:46 +0800475 return GSW_HAL_NORMAL_FAIL;
476 }
zw.wang1907e8f2025-07-01 16:26:39 +0800477 if(dlHandle_gnss == NULL)
zw.wangbd342b92025-07-21 11:24:16 +0800478 dlHandle_gnss = dlopen(lynqLib_gnss, RTLD_NOW);;
479 if(dlHandle_gnss == NULL)
b.liu68a94c92025-05-24 12:53:41 +0800480 {
hong.liud2417072025-06-27 07:10:37 -0700481 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800482 }
483 mbtk_gnss_init=(int(*)(mbtk_gnss_callback_func))dlsym(dlHandle_gnss, "mbtk_gnss_init");
484 ret = mbtk_gnss_init(gnss_callback);
485 if(ret == 0)
486 {
487 mbtk_gnss_ind_set=(int(*)(uint32_t ,int))dlsym(dlHandle_gnss, "mbtk_gnss_ind_set");
zw.wanga5250d62025-06-13 16:01:34 +0800488 ret = mbtk_gnss_ind_set(MBTK_GNSS_IND_NMEA |MBTK_GNSS_IND_LOCATION, QSER_GNSS_TIMEOUT);
b.liu68a94c92025-05-24 12:53:41 +0800489 if(ret == 0)
490 {
491 inited = true;
492 }
493 else
494 {
zw.wangbd342b92025-07-21 11:24:16 +0800495 LOGE(GSW_GNSS,"[GSW_gnss] init mbtk_gnss_ind_set() 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 }
499 else
500 {
zw.wangbd342b92025-07-21 11:24:16 +0800501 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_init() fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700502 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800503 }
504 }
505
506 return GSW_HAL_SUCCESS;
507}
508
509/**
510 * @brief SDK interface to registered callback function
511 * @param [in] callback
512 * @retval 0: success
513 * @retval other: fail
514 */
hong.liud2417072025-06-27 07:10:37 -0700515int32_t gsw_gnss_reg_cb_group(gsw_gnss_cb callback)
b.liu68a94c92025-05-24 12:53:41 +0800516{
zw.wangbc534c02025-06-26 09:31:44 +0800517 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700518 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800519 if(callback.gsw_location_cb == NULL && callback.gsw_nmea_cb == NULL)
520 {
zw.wangbd342b92025-07-21 11:24:16 +0800521 LOGE(GSW_GNSS,"[GSW_gnss] handler_ptr is NULL.");
hong.liud2417072025-06-27 07:10:37 -0700522 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800523 }
524 if (gsw_cb == NULL)
525 {
526 gsw_cb = (gsw_gnss_cb *)malloc(sizeof(gsw_gnss_cb));
527 if (gsw_cb == NULL)
528 {
zw.wangbd342b92025-07-21 11:24:16 +0800529 LOGE(GSW_GNSS,"[GSW_gnss] Memory allocation failed.");
hong.liud2417072025-06-27 07:10:37 -0700530 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800531 }
532 }
533 gsw_cb->gsw_location_cb = callback.gsw_location_cb;
534 gsw_cb->gsw_nmea_cb = callback.gsw_nmea_cb;
535 return GSW_HAL_SUCCESS;
536}
537/**
538 * @brief SDK interface to start gnss
539 * @param
540 * @retval 0: success
541 * @retval other: fail
542 */
hong.liud2417072025-06-27 07:10:37 -0700543int32_t gsw_gnss_start(void)
b.liu68a94c92025-05-24 12:53:41 +0800544{
545 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800546 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700547 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800548 ret = system("/usr/sbin/gnss_gpio.sh on > /dev/null 2>&1");
549 if(ret != 0)
550 {
zw.wangbd342b92025-07-21 11:24:16 +0800551 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh on fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700552 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800553 }
zw.wang57f3a9f2025-07-10 14:26:52 +0800554 // 记录mbtk_gnss_open前的时间戳
555 struct timespec start_time;
556 if (clock_gettime(CLOCK_MONOTONIC, &start_time) != 0) {
zw.wangbd342b92025-07-21 11:24:16 +0800557 LOGE(GSW_GNSS,"[GSW_gnss] Failed to get start time");
zw.wang57f3a9f2025-07-10 14:26:52 +0800558 return GSW_HAL_NORMAL_FAIL;
559 }
560
b.liu68a94c92025-05-24 12:53:41 +0800561 mbtk_gnss_open=(int(*)(int,int))dlsym(dlHandle_gnss, "mbtk_gnss_open");
562 ret = mbtk_gnss_open(255, QSER_GNSS_TIMEOUT);
563 if(ret != 0)
564 {
zw.wangbd342b92025-07-21 11:24:16 +0800565 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_open is error.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700566 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800567 }
zw.wang89c18242025-06-24 19:07:10 +0800568
b.liu68a94c92025-05-24 12:53:41 +0800569 strated = true;
zw.wang7aa34062025-06-27 17:54:55 +0800570 /*
b.liu68a94c92025-05-24 12:53:41 +0800571 if (gnss_freq > 0)
572 gsw_gnss_set_freq(gnss_freq);
573 if (gnss_startmode >= 0)
574 gsw_gnss_set_start_mode(gnss_startmode);
575 if (gnss_switch_op > 0)
576 gsw_gnss_epo_switch(gnss_switch_op);
zw.wang7aa34062025-06-27 17:54:55 +0800577 */
zw.wang57f3a9f2025-07-10 14:26:52 +0800578
579 // 记录mbtk_gnss_set_VTG前的时间戳并计算等待时间
580 struct timespec end_time;
581 if (clock_gettime(CLOCK_MONOTONIC, &end_time) != 0) {
zw.wangbd342b92025-07-21 11:24:16 +0800582 LOGE(GSW_GNSS,"[GSW_gnss] Failed to get end time");
zw.wang57f3a9f2025-07-10 14:26:52 +0800583 return GSW_HAL_NORMAL_FAIL;
584 }
585 long start_ms = start_time.tv_sec * 1000 + start_time.tv_nsec / 1000000;
586 long end_ms = end_time.tv_sec * 1000 + end_time.tv_nsec / 1000000;
587 long diff_ms = end_ms - start_ms;
588 if (diff_ms < 700) {
589 long wait_ms = 700 - diff_ms;
590 usleep(wait_ms * 1000); // 转换为微秒等待
591 }
592
b.liu68a94c92025-05-24 12:53:41 +0800593 mbtk_gnss_set_VTG();
594
595 return GSW_HAL_SUCCESS;
596}
597
zw.wang57f3a9f2025-07-10 14:26:52 +0800598
b.liu68a94c92025-05-24 12:53:41 +0800599/**
600 * @brief SDK interface to stop gnss
601 * @param
602 * @retval 0: success
603 * @retval other: fail
604 */
hong.liud2417072025-06-27 07:10:37 -0700605int32_t gsw_gnss_stop(void)
b.liu68a94c92025-05-24 12:53:41 +0800606{
607 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800608 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700609 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800610 mbtk_gnss_close=(int(*)(int))dlsym(dlHandle_gnss, "mbtk_gnss_close");
611 ret = mbtk_gnss_close(QSER_GNSS_TIMEOUT);
612 if(ret != 0)
613 {
zw.wangbd342b92025-07-21 11:24:16 +0800614 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_close is error.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700615 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800616 }
zw.wangbc534c02025-06-26 09:31:44 +0800617 ret = system("/usr/sbin/gnss_gpio.sh off > /dev/null 2>&1");
618 if(ret != 0)
619 {
zw.wangbd342b92025-07-21 11:24:16 +0800620 LOGE(GSW_GNSS,"[GSW_gnss] gnss_gpio.sh off fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700621 return GSW_HAL_NORMAL_FAIL;
zw.wangbc534c02025-06-26 09:31:44 +0800622 }
b.liu68a94c92025-05-24 12:53:41 +0800623 strated = false;
624 return GSW_HAL_SUCCESS;
625}
626
627/**
628 * @brief SDK interface to de initialization gnss
629 * @param
630 * @retval 0: success
631 * @retval other: fail
632 */
hong.liud2417072025-06-27 07:10:37 -0700633int32_t gsw_gnss_deinit(void)
b.liu68a94c92025-05-24 12:53:41 +0800634{
635 int ret;
zw.wangbc534c02025-06-26 09:31:44 +0800636 if(!inited)
hong.liud2417072025-06-27 07:10:37 -0700637 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800638 if(inited)
639 {
lichengzhanga7089172025-07-01 20:41:46 +0800640 ret = system("serial_atcmd AT*IMLCONFIG=12");
641 if(ret != 0)
642 {
zw.wangbd342b92025-07-21 11:24:16 +0800643 LOGE(GSW_GNSS,"serial_atcmd fail\n");
lichengzhanga7089172025-07-01 20:41:46 +0800644 return GSW_HAL_NORMAL_FAIL;
645 }
b.liu68a94c92025-05-24 12:53:41 +0800646 mbtk_gnss_deinit=(int(*)())dlsym(dlHandle_gnss, "mbtk_gnss_deinit");
647 ret = mbtk_gnss_deinit();
648 if(ret == 0)
649 {
650 inited = false;
651 }
652 else
653 {
zw.wangbd342b92025-07-21 11:24:16 +0800654 LOGE(GSW_GNSS,"[GSW_gnss] mbtk_gnss_deinit() fail.ret = [%d]", ret);
zw.wang1907e8f2025-07-01 16:26:39 +0800655 /*
b.liu68a94c92025-05-24 12:53:41 +0800656 dlclose(dlHandle_gnss);
657 dlHandle_gnss = NULL;
zw.wang1907e8f2025-07-01 16:26:39 +0800658 */
hong.liud2417072025-06-27 07:10:37 -0700659 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800660 }
661 }
662
zw.wang1907e8f2025-07-01 16:26:39 +0800663 /*
b.liu68a94c92025-05-24 12:53:41 +0800664 dlclose(dlHandle_gnss);
665 dlHandle_gnss = NULL;
zw.wang1907e8f2025-07-01 16:26:39 +0800666 */
b.liu68a94c92025-05-24 12:53:41 +0800667 gnss_freq = -1;
668 gnss_startmode = -1;
669 gnss_switch_op = -1;
670 return GSW_HAL_SUCCESS;
671}
672
zw.wang75e98ea2025-05-29 17:57:38 +0800673int gsw_gnss_add_lib(void)
674{
675 return GSW_HAL_SUCCESS;
676}
b.liu68a94c92025-05-24 12:53:41 +0800677
678/**
679 * @brief SDK interface to enable XTRA switch
680 * @param [in] state
681 * @retval 0: success
682 * @retval other: fail
683 */
hong.liud2417072025-06-27 07:10:37 -0700684int32_t gsw_gnss_xtra_is_enable(gsw_xtra_state_e state)
b.liu68a94c92025-05-24 12:53:41 +0800685{
686 return GSW_HAL_SUCCESS;
687}
688
689/**
690 * @brief SDK interface to delete aiding data,delete aiding data for cold start(1-H,2-W,3-C)
691 * @param [in] switch_op
692 * @retval 0: success
693 * @retval other: fail
694 */
hong.liud2417072025-06-27 07:10:37 -0700695int32_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 +0800696{
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 int ret;
700 char param_buf[32] = {0};
701 snprintf(param_buf, 32, "$RESET,%u", flags);
702 mbtk_gnss_setting=(int(*)(const char *setting_cmd, int))dlsym(dlHandle_gnss, "mbtk_gnss_setting");
703 ret = mbtk_gnss_setting(param_buf, QSER_GNSS_TIMEOUT);
704 if(ret != 0)
705 {
zw.wangbd342b92025-07-21 11:24:16 +0800706 LOGE(GSW_GNSS,"[qser_gnss] mbtk_gnss_setting fail.ret = [%d]", ret);
hong.liud2417072025-06-27 07:10:37 -0700707 return GSW_HAL_NORMAL_FAIL;
b.liu68a94c92025-05-24 12:53:41 +0800708 }
709 return GSW_HAL_SUCCESS;
710}
711
712/**
713 * @brief init and configure gps
714 * @param [in] init_configure
715 * @retval 0: success
716 * @retval other: fail
717 */
hong.liud2417072025-06-27 07:10:37 -0700718int32_t gsw_gnss_init_configure_gps(gsw_gnss_init_configure_t init_configure)
b.liu68a94c92025-05-24 12:53:41 +0800719{
720 return GSW_HAL_SUCCESS;
721}
hong.liud2417072025-06-27 07:10:37 -0700722
723int gsw_gnss_get_tail_nmea_type(char *tail_type, int len)
724{
725 if(NULL == tail_type){
zw.wangbd342b92025-07-21 11:24:16 +0800726 LOGE(GSW_GNSS,"get_tail_nmea_type fail, tail_type is NULL");
hong.liud2417072025-06-27 07:10:37 -0700727 return GSW_HAL_ERROR_GNSS_FAIL;
728 }
729
730 if(len >= 3){
731 strcpy(tail_type, "RMC");
732 return GSW_HAL_GNSS_SUCCESS;
733 }else{
zw.wangbd342b92025-07-21 11:24:16 +0800734 LOGE(GSW_GNSS,"get_tail_nmea_type fail, len[%d] is too short", len);
hong.liud2417072025-06-27 07:10:37 -0700735 return GSW_HAL_ERROR_GNSS_FAIL;
736 }
737}
rx.xie85d47ac2025-08-08 05:16:29 -0700738
739
740/**
741* @brief Start install gnss software
742* @param [in] char* file_path
743* @param [out] NULL
744* @retval GSW_HAL_SUCCESS\GSW_HAL_FAIL
745*/
746int gsw_update_gnss_start(const char *fw_path)
747{
748 int ret;
749 mbtk_gnss_dl_ptr = (int(*)(const char *, int))dlsym(dlHandle_gnss, "mbtk_gnss_dl");
750 if (!mbtk_gnss_dl_ptr)
751 {
752 LOGE(GSW_GNSS,"[qser_gnss] dlsym failed for mbtk_gnss_dl: %s", dlerror());
753 return GSW_HAL_NORMAL_FAIL;
754 }
755
756 ret = mbtk_gnss_dl_ptr(fw_path, QSER_GNSS_TIMEOUT);
757 if(ret != 0)
758 {
759 LOGE(GSW_GNSS,"[qser_gnss] Firmware download failed. ret = [%d]", ret);
760 return GSW_HAL_NORMAL_FAIL;
761 }
762 return GSW_HAL_SUCCESS;
763}
764
765
766/**
767* @brief get gnss version info
768* @param [in] NULL
769* @param [out] char* version_info
770* @retval GSW_HAL_SUCCESS\GSW_HAL_FAIL
771*/
772int32_t gsw_get_gnss_version_info(char* version_info)
773{
774 if (!version_info)
775 {
776 LOGE(GSW_GNSS, "[GSW_gnss] version_info is NULL");
777 return GSW_HAL_NORMAL_FAIL;
778 }
779
780 GSW_DEVICE dev_type = get_gnss_device_version();
781 switch (dev_type)
782 {
783 case HD8122:
784 strncpy(version_info, "HD8122", 255);
785 break;
786 case HD8040D:
787 strncpy(version_info, "HD8040D", 255);
788 break;
789 case NO_DEVICE:
790 default:
791 LOGE(GSW_GNSS, "[GSW_gnss] Failed to detect GNSS device");
792 return GSW_HAL_NORMAL_FAIL;
793 }
794
795 version_info[255] = '\0';
796 LOGE(GSW_GNSS, "[GSW_gnss] Retrieved GNSS version: %s", version_info);
797 return GSW_HAL_SUCCESS;
798}
799
800
801