blob: c820489b4056c9806363f4200712627d7566abb4 [file] [log] [blame]
b.liu8f231a12024-05-31 17:55:06 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <errno.h>
5#include <pthread.h>
6#include <fcntl.h>
7#include <libubox/ustream.h>
8#include <libubus.h>
9#include <signal.h>
10#include <cutils/properties.h>
b.liu778645e2024-06-21 16:47:42 +080011#include <ctype.h>
b.liu978f5432024-07-01 18:04:18 +080012#include <termios.h>
b.liu8f231a12024-05-31 17:55:06 +080013
14#include "mbtk_type.h"
15#include "mbtk_log.h"
16#include "gnss_info.h"
b.liu778645e2024-06-21 16:47:42 +080017#include "gnss_utils.h"
b.liu8f231a12024-05-31 17:55:06 +080018#include "gnss_6228.h"
b.liuf9fbfa12024-06-14 15:53:59 +080019#include "gnss_hd8122.h"
b.liu99c645d2024-06-20 10:52:15 +080020#include "gnss_asr5311.h"
b.liu42f558e2024-07-18 14:06:49 +080021#include "gnss_n50db.h"
b.liu8f231a12024-05-31 17:55:06 +080022
23#define GNSS_DEBUG 1
b.liud0ba7152024-06-19 14:47:21 +080024#define GNSS_UBUS_ENABLE 1
b.liu8f231a12024-05-31 17:55:06 +080025
26#define GNSS_TAG "MBTK_GNSS"
27#define GNSS_BUFF_SIZE 2048
28#define MBTK_PROP_GNSS_LOG "persist.mbtk.gnss_log_enable"
29#define GNSS_PORT_PTY "/dev/tty_gnss_nmea"
30#define GNSS_PORT_USB_AT "/dev/ttyGS0"
31#define GNSS_PORT_USB_NMEA "/dev/ttymodem0"
32#define GNSS_PORT_UART_AT "/dev/ttyS1"
b.liue77ac3a2024-07-17 17:36:57 +080033#define GNSS_CLI_IND_MAX 10
b.liu8f231a12024-05-31 17:55:06 +080034
35#ifdef GNSS_DEBUG
36#define GNSS_NMEA_FILE_LOG "/tmp/mbtk_gnss_nmea.log"
b.liu8f231a12024-05-31 17:55:06 +080037#define GNSS_FILE_LOG "/tmp/mbtk_gnss.log"
b.liu99c645d2024-06-20 10:52:15 +080038#define GNSS_FILE_LOG_MAX 104857600 // 100MB
b.liu8f231a12024-05-31 17:55:06 +080039#endif
40
b.liua1b69262024-09-04 16:32:59 +080041#define MBTK_GNSS_PTY_AUTO_INIT 1
42
b.liubcf86c92024-08-19 19:48:28 +080043gnss_info_t gnss_info;
b.liu8f231a12024-05-31 17:55:06 +080044
b.liud0ba7152024-06-19 14:47:21 +080045#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080046struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080047#else
48int gnss_ipc_service_start();
49#endif
50
b.liu8f231a12024-05-31 17:55:06 +080051int gnss_init_config(int fd);
52
wangyouqiangfa897f82024-06-27 09:44:55 +080053static char nmea_buff[GNSS_BUFF_SIZE*4] = {0};
54static char data_buff[GNSS_BUFF_SIZE*4] = {0};
b.liud0ba7152024-06-19 14:47:21 +080055static uint32 nmea_buff_len = 0;
56static uint32 data_buff_len = 0;
b.liue77ac3a2024-07-17 17:36:57 +080057static gnss_ind_info_t ind_info[GNSS_CLI_IND_MAX];
b.liud0ba7152024-06-19 14:47:21 +080058
b.liu8f231a12024-05-31 17:55:06 +080059static bool nmea_found = FALSE;
60#ifdef GNSS_DEBUG
61static bool nmea_log_enable = FALSE;
62static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080063static int debug_fd = -1;
64static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080065#endif
yq.wang5c647e02024-08-10 00:01:11 -070066
67static bool mbtk_gnss_time_set_flag = 0;
68
b.liua1b69262024-09-04 16:32:59 +080069#if MBTK_GNSS_PTY_AUTO_INIT
70static bool gnss_pty_print_enable = FALSE;
71#endif
b.liu8f231a12024-05-31 17:55:06 +080072static int gnss_pty_master_fd = -1;
73static int gnss_pty_slave_fd = -1;
74static int gnss_usb_at_port_fd = -1;
75static int gnss_usb_nmea_port_fd = -1;
76static int gnss_uart_at_port_fd = -1;
77static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
78
b.liue77ac3a2024-07-17 17:36:57 +080079int gnss_write(int fd, const void* buf, int buf_len);
80
b.liu8f231a12024-05-31 17:55:06 +080081static void help()
82{
b.liu42f558e2024-07-18 14:06:49 +080083 LOGD("mbtk_gnssd <6228/8122/5311/N50DB> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080084}
85
86static int arg_check(int argc, char *argv[])
87{
88 if(argc != 4) {
b.liu4ae41182024-06-28 16:30:15 +080089 LOGE("argc = %d", argc);
b.liu8f231a12024-05-31 17:55:06 +080090 goto check_fail;
91 }
92
b.liu99c645d2024-06-20 10:52:15 +080093 // Only support 6228/8122/5311.
b.liu42f558e2024-07-18 14:06:49 +080094 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)
95 && strcmp(argv[1], GNSS_ID_N50DB)) {
b.liu4ae41182024-06-28 16:30:15 +080096 LOGE("argv[1] = %s", argv[1]);
b.liu8f231a12024-05-31 17:55:06 +080097 goto check_fail;
98 }
99
100 if(access(argv[2], R_OK | W_OK)) {
b.liu4ae41182024-06-28 16:30:15 +0800101 LOGE("access(%s) rw fail. ", argv[2]);
b.liu8f231a12024-05-31 17:55:06 +0800102 goto check_fail;
103 }
104
b.liuced8dd02024-06-28 13:28:29 +0800105#if 0
106 int init_mode = atoi(argv[3]);
107 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
b.liu8f231a12024-05-31 17:55:06 +0800108 goto check_fail;
109 }
b.liuced8dd02024-06-28 13:28:29 +0800110#endif
b.liu8f231a12024-05-31 17:55:06 +0800111
112 return 0;
113check_fail:
114 help();
115 return -1;
116}
117
118static int gnss_ports_open(uint32 print_port)
119{
b.liuced8dd02024-06-28 13:28:29 +0800120 // TTY AT change.
121 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
122 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
b.liua1b69262024-09-04 16:32:59 +0800123#if MBTK_GNSS_PTY_AUTO_INIT
124 gnss_pty_print_enable = TRUE;
125#else
b.liuced8dd02024-06-28 13:28:29 +0800126 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
127 return GNSS_ERR_OPEN_DEV;
128 }
b.liua1b69262024-09-04 16:32:59 +0800129#endif
b.liuced8dd02024-06-28 13:28:29 +0800130 LOGD("Open PTY port success.");
131 } else { // Close
b.liua1b69262024-09-04 16:32:59 +0800132#if MBTK_GNSS_PTY_AUTO_INIT
133 gnss_pty_print_enable = FALSE;
134#else
b.liuced8dd02024-06-28 13:28:29 +0800135 if(gnss_pty_slave_fd > 0) {
136 close(gnss_pty_slave_fd);
137 gnss_pty_slave_fd = -1;
138 unlink(GNSS_PORT_PTY);
139 }
b.liua1b69262024-09-04 16:32:59 +0800140#endif
b.liuced8dd02024-06-28 13:28:29 +0800141 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800142 }
b.liu8f231a12024-05-31 17:55:06 +0800143 }
144
b.liuced8dd02024-06-28 13:28:29 +0800145 // USB AT change.
146 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
147 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
b.liu978f5432024-07-01 18:04:18 +0800148 if((gnss_usb_at_port_fd = gnss_port_open(GNSS_PORT_USB_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
b.liuced8dd02024-06-28 13:28:29 +0800149 return GNSS_ERR_OPEN_DEV;
150 }
151 LOGD("Open USB AT port success.");
152 } else { // Close
153 if(gnss_usb_at_port_fd > 0) {
154 close(gnss_usb_at_port_fd);
155 gnss_usb_at_port_fd = -1;
156 }
157 LOGD("Close USB AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800158 }
b.liu8f231a12024-05-31 17:55:06 +0800159 }
160
b.liuced8dd02024-06-28 13:28:29 +0800161 // USB NMEA change.
162 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
163 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
b.liu978f5432024-07-01 18:04:18 +0800164 if((gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
b.liuced8dd02024-06-28 13:28:29 +0800165 return GNSS_ERR_OPEN_DEV;
166 }
167 LOGD("Open USB NMEA port success.");
168 } else { // Close
169 if(gnss_usb_nmea_port_fd > 0) {
170 close(gnss_usb_nmea_port_fd);
171 gnss_usb_nmea_port_fd = -1;
172 }
173 LOGD("Close USB NMEA port success.");
b.liu8f231a12024-05-31 17:55:06 +0800174 }
b.liu8f231a12024-05-31 17:55:06 +0800175 }
176
b.liuced8dd02024-06-28 13:28:29 +0800177 // Uart AT change.
178 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
179 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
180 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
181 return GNSS_ERR_OPEN_DEV;
182 }
183 LOGD("Open UART AT port success.");
184 } else { // Close
185 if(gnss_uart_at_port_fd > 0) {
186 close(gnss_uart_at_port_fd);
187 gnss_uart_at_port_fd = -1;
188 }
189 LOGD("Close UART AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800190 }
b.liu8f231a12024-05-31 17:55:06 +0800191 }
192
b.liuced8dd02024-06-28 13:28:29 +0800193 gnss_info.print_port = print_port;
194
b.liudbc3f4b2024-06-25 18:22:24 +0800195 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800196}
197
198static int gnss_ports_close()
199{
200 if(gnss_usb_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800201 tcflush(gnss_usb_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800202 close(gnss_usb_at_port_fd);
203 gnss_usb_at_port_fd = -1;
204 }
205
206 if(gnss_usb_nmea_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800207 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800208 close(gnss_usb_nmea_port_fd);
209 gnss_usb_nmea_port_fd = -1;
210 }
211
212 if(gnss_uart_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800213 tcflush(gnss_uart_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800214 close(gnss_uart_at_port_fd);
215 gnss_uart_at_port_fd = -1;
216 }
b.liua1b69262024-09-04 16:32:59 +0800217#if MBTK_GNSS_PTY_AUTO_INIT
218 gnss_pty_print_enable = FALSE;
219#else
b.liu8f231a12024-05-31 17:55:06 +0800220 if(gnss_pty_master_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800221 tcflush(gnss_pty_master_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800222 close(gnss_pty_master_fd);
223 gnss_pty_master_fd = -1;
224 }
225
226 if(gnss_pty_slave_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800227 tcflush(gnss_pty_slave_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800228 close(gnss_pty_slave_fd);
229 gnss_pty_slave_fd = -1;
230 unlink(GNSS_PORT_PTY);
231 }
b.liua1b69262024-09-04 16:32:59 +0800232#endif
b.liuced8dd02024-06-28 13:28:29 +0800233 gnss_info.print_port = 0;
234
b.liu8f231a12024-05-31 17:55:06 +0800235 return 0;
236}
237
b.liu8f231a12024-05-31 17:55:06 +0800238#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800239static void log_save(int fd, const char *data, int data_len)
240{
b.liu8f231a12024-05-31 17:55:06 +0800241 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800242 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
243 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
244 close(debug_fd);
245 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
246 if(debug_fd < 0) {
247 LOGE("Open debug fd fail.");
248 }
249 debug_fd_len = 0;
250
251 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800252 close(nmea_log_fd);
253 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
254 if(nmea_log_fd < 0) {
255 LOGE("Open debug fd fail.");
256 }
b.liu8f231a12024-05-31 17:55:06 +0800257 }
258
b.liu99c645d2024-06-20 10:52:15 +0800259 if(fd == nmea_log_fd) {
260 if(nmea_log_fd > 0) {
261 write(nmea_log_fd, data, data_len);
262 debug_fd_len += data_len;
263 }
264 } else if(fd == debug_fd) {
265 if(debug_fd > 0) {
266 write(debug_fd, data, data_len);
267 debug_fd_len += data_len;
268 }
b.liu8f231a12024-05-31 17:55:06 +0800269 }
270 }
b.liu99c645d2024-06-20 10:52:15 +0800271}
b.liu8f231a12024-05-31 17:55:06 +0800272#endif
273
b.liue77ac3a2024-07-17 17:36:57 +0800274static void ind_location_print(const char *data)
275{
276 int index = 0;
277 int buff_len = 0;
278 char buff[GNSS_BUFF_SIZE] = {0};
279 buff[0] = MBTK_IND_START_FLAG;
280 buff_len++;
281 memcpy(buff + 1, MBTK_IND_LOCATION_TAG, strlen(MBTK_IND_LOCATION_TAG));
282 buff_len += strlen(MBTK_IND_LOCATION_TAG);
283 memcpy(buff + strlen(buff), data, strlen(data));
284 buff_len += strlen(data);
285 buff[strlen(buff)] = MBTK_IND_END_FLAG;
286 buff_len++;
287
288 while(index < GNSS_CLI_IND_MAX) {
289 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_LOCATION)) {
290 gnss_write(ind_info[index].cli_fd, buff, buff_len);
291 }
292 index++;
293 }
294}
295
296static void ind_nmea_print(const char *data)
297{
298 int index = 0;
299 int buff_len = 0;
300 char buff[GNSS_BUFF_SIZE] = {0};
301 buff[0] = MBTK_IND_START_FLAG;
302 buff_len++;
303 memcpy(buff + 1, MBTK_IND_NMEA_TAG, strlen(MBTK_IND_NMEA_TAG));
304 buff_len += strlen(MBTK_IND_NMEA_TAG);
305 memcpy(buff + strlen(buff), data, strlen(data));
306 buff_len += strlen(data);
307 buff[strlen(buff)] = MBTK_IND_END_FLAG;
308 buff_len++;
309 while(index < GNSS_CLI_IND_MAX) {
310 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_NMEA)) {
311 gnss_write(ind_info[index].cli_fd, buff, buff_len);
312 }
313 index++;
314 }
315}
316
b.liu99c645d2024-06-20 10:52:15 +0800317static void nmea_print(const char *nmea, int nmea_len)
318{
yq.wang1ddd1fd2024-07-25 23:00:14 -0700319 int ret = -1;
b.liu8f231a12024-05-31 17:55:06 +0800320 if(gnss_usb_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700321 ret = write(gnss_usb_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800322 }
323
324 if(gnss_usb_nmea_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700325 ret = write(gnss_usb_nmea_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800326 }
327
328 if(gnss_uart_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700329 ret = write(gnss_uart_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800330 }
331
332 if(gnss_pty_master_fd > 0) {
b.liua1b69262024-09-04 16:32:59 +0800333#if MBTK_GNSS_PTY_AUTO_INIT
334 if(gnss_pty_print_enable) {
335 ret = write(gnss_pty_master_fd, nmea, nmea_len);
336 }
337#else
yq.wang1ddd1fd2024-07-25 23:00:14 -0700338 ret = write(gnss_pty_master_fd, nmea, nmea_len);
b.liua1b69262024-09-04 16:32:59 +0800339#endif
b.liu8f231a12024-05-31 17:55:06 +0800340 }
yq.wang937355d2024-07-26 01:24:42 -0700341 ind_nmea_print(nmea);
342 ind_location_print(nmea);
b.liu8f231a12024-05-31 17:55:06 +0800343}
344
345static unsigned char nmea_checksum(const char *nmea)
346{
347 const char *p = nmea;
348 unsigned char chs = 0;
349
350 while (*p == '$') // skip '$'
351 p++;
352 while (*p != '*' && *p != 0)
353 chs ^= *p++;
354
355 return chs;
356}
357
358static bool nmea_check(const char *nmea, int nmea_len)
359{
360 char **ptr = gnss_filter_info;
361 while(*ptr) {
362 if(strstr(nmea, *ptr)) {
363 break;
364 }
365 ptr++;
366 }
367
368 if(*ptr == NULL) {
369 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
370 return FALSE;
371 }
372
373 char *checksum_str = strstr(nmea, "*");
374 checksum_str++; // Jump '*'
375 char checksum_buf[3] = {0};
376 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
377 if(strncasecmp(checksum_buf, checksum_str, 2)) {
378 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
379 return FALSE;
380 }
381
382 return TRUE;
383}
384
luojiand7960682024-08-02 16:50:01 +0800385static int nmea_tokenizer_init(mbtk_nmeatokenizer* t, const char* head, const char* end, int param_num)
386{
387 int count = 0;
388 const char* p = head;
389 const char* q = end;
390 const char* tmp = NULL;
391 // the initial '$' is optional
392 if (p < q && p[0] == '$')
393 {
394 p += 1;
395 }
396 else
397 {
398 return -1;
399 }
400
401 //find '*',del '*25\r\n'
402 // get rid of checksum at the end of the sentecne
403 if (q >= p + 5 && q[-5] == '*')
404 {
405 q -= 5;
406 }
407 else
408 {
409 return -1;
410 }
411
b.liubcf86c92024-08-19 19:48:28 +0800412 while (p <= q)
luojiand7960682024-08-02 16:50:01 +0800413 {
414 tmp = memchr(p, ',', q-p);
415 if (tmp == NULL)
416 {
417 tmp = q;
418 }
419 // if (q > p) {
420 // q >= p include empty token: ,,
421 if (tmp >= p)
422 {
423 if (count < MAX_NMEA_TOKENS)
424 {
425 t->tokens[count].head = p;
426 t->tokens[count].end = tmp;
427 count += 1;
428 }
429 }
b.liubcf86c92024-08-19 19:48:28 +0800430
luojiand7960682024-08-02 16:50:01 +0800431 if (tmp <= q)
432 {
433 tmp += 1;
434 }
435
436 p = tmp;
437 }
438
439 if(count != param_num)
440 {
441 LOGD("count [%d], param_num [%d]", count, param_num);
442 return -1;
443 }
444
445 t->count = count;
446 return count;
447}
448
449static mbtk_token nmea_tokenizer_get(mbtk_nmeatokenizer* t, int index)
450{
451 mbtk_token tok;
452 static const char* dummy = "";
453
454 if (index < 0 || index >= t->count)
455 {
456 tok.head = tok.end = dummy;
457 }
458 else
459 {
460 tok = t->tokens[index];
461 }
462 return tok;
463}
464
luojiand7960682024-08-02 16:50:01 +0800465static int mbtk_time_type_gnss_read() {
466 int type = 0;
467 char time_type[] ={0};
468 property_get("persist.mbtk.time_type", time_type, "0");
469
470 type = atoi(time_type);
471// LOGD("time_type :%d\n", type);
472 if(type != LYNQ_TIME_TYPE_GNSS)
473 mbtk_gnss_time_set_flag = 0;
474
475 return type;
476}
477
478static int strstr_n(const char *s1, const char *s2)
479{
480 int n;
481 int strlen = 0;
482
483 if(*s2)
484 {
485 while(*s1)
486 {
487 for(n = 0; *(s1+n) == *(s2 + n); n++)
488 {
489 if(!*(s2 + n + 1))
490 {
491 strlen++;
492 return strlen;
493 }
494 }
495 s1++;
496 strlen++;
497 }
498 return 0;
499 }
500
501 return 0;
502}
503static int nmea_update_date_time(mbtk_token date, mbtk_token time)
504{
505 char tmp_char[4] = {0};
506 struct tm tmp_time;
507 struct timeval tv;
508
509 memset(&tmp_time, 0x0, sizeof(struct tm));
510 if (date.head + 6 > date.end)
511 {
512 LOGD("date get fail");
513 return -1;
514 }
515
516 memcpy(tmp_char, date.head, 2);
517 tmp_time.tm_mday = atoi(tmp_char);
518 memcpy(tmp_char, date.head + 2, 2);
519 tmp_time.tm_mon = atoi(tmp_char) - 1;
520 memcpy(tmp_char, date.head + 4, 2);
521 tmp_time.tm_year = 100 + atoi(tmp_char);
522
523 if (time.head + 6 > time.end)
524 {
525 LOGD("time get fail");
526 return -1;
527 }
528
529 memcpy(tmp_char, time.head, 2);
530 tmp_time.tm_hour = atoi(tmp_char);
531 memcpy(tmp_char, time.head + 2, 2);
532 tmp_time.tm_min = atoi(tmp_char);
533 memcpy(tmp_char, time.head + 4, 2);
534 tmp_time.tm_sec = atoi(tmp_char);
535 tmp_time.tm_isdst = -1;
luojiand7960682024-08-02 16:50:01 +0800536
b.liubcf86c92024-08-19 19:48:28 +0800537
538 LOGD("data:%d-%d-%d %d:%d:%d", tmp_time.tm_year + 1900,
luojiand7960682024-08-02 16:50:01 +0800539 tmp_time.tm_mon,
540 tmp_time.tm_mday,
541 tmp_time.tm_hour,
542 tmp_time.tm_min,
543 tmp_time.tm_sec);
544
545
546 time_t _t = mktime(&tmp_time);//parse location tmp_time
547
548 tzset(); // auto set tz
549 _t = _t - timezone;
550
551 LOGD("timestamp:%ld, %ld", _t, timezone);
552
553 tv.tv_sec = _t;
554 if(settimeofday(&tv, NULL)) {
555 LOGD("%s: , Set time fail\n", __func__);
556 mbtk_gnss_time_set_flag = 0;
557 } else {
558 LOGD("%s: , Set time success \n", __func__);
luojian51d65f92024-08-08 15:39:42 +0800559 system("hwclock -w rtc0");
560 mbtk_gnss_time_set_flag = 1;
luojiand7960682024-08-02 16:50:01 +0800561 }
562
563 return 0;
564}
565
566static int ind_nmea_parse(const char *data, int data_len)
567{
568 int ret;
569 mbtk_nmeatokenizer tzer = {0};
570 if(strstr_n(data + 3, "RMC"))
571 {
572 ret = nmea_tokenizer_init(&tzer, data, data + data_len, NMEA_RMC_PARAM_NUM);
573 if(ret < 0)
574 {
575 LOGD("nmea_tokenizer_init fail");
576 return -1;
577 }
578
579 mbtk_token tok_time = nmea_tokenizer_get(&tzer,1);
580 mbtk_token tok_fixStatus = nmea_tokenizer_get(&tzer,2);
581 mbtk_token tok_date = nmea_tokenizer_get(&tzer,9);
582
583 if(tok_fixStatus.head[0] == 'A')
584 {
585 ret = nmea_update_date_time(tok_date, tok_time);
586 if(ret < 0)
587 {
588 LOGD("nmea_update_date_time fail");
589 return -1;
590 }
591
592 }
593 }
594
595 return 0;
596}
597
598
b.liu8f231a12024-05-31 17:55:06 +0800599static void gnss_nmea_process(const char *data, int data_len)
600{
luojiand7960682024-08-02 16:50:01 +0800601// LOGD("gnss_nmea_process() : data_len - %d", data_len);
b.liu99c645d2024-06-20 10:52:15 +0800602#if 0
b.liu8f231a12024-05-31 17:55:06 +0800603 char nmea[GNSS_BUFF_SIZE] = {0};
604 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800605#else
606 const char *nmea = data;
607#endif
b.liu8f231a12024-05-31 17:55:06 +0800608
609 if(!nmea_check(nmea, data_len)) {
b.liu42f558e2024-07-18 14:06:49 +0800610 // No print "$HOSTSLEEP".
611 if(memcmp(nmea, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
612 LOGD("NO-NMEA:%s", nmea);
613 }
b.liu99c645d2024-06-20 10:52:15 +0800614#if GNSS_DEBUG
615 log_save(nmea_log_fd, "/**/", 4);
616 log_save(nmea_log_fd, nmea, data_len);
617#endif
618 if(gnss_info.gnss_set_cb)
619 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800620 return;
621 }
622
623#ifdef GNSS_DEBUG
624 if(nmea_log_enable) {
625 LOGD("NMEA[%d]:%s", data_len, nmea);
626 }
b.liu99c645d2024-06-20 10:52:15 +0800627
628 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800629#endif
630
luojiand7960682024-08-02 16:50:01 +0800631 if( (mbtk_time_type_gnss_read() == LYNQ_TIME_TYPE_GNSS) && !mbtk_gnss_time_set_flag)
632 ind_nmea_parse(nmea, data_len);
633
b.liu8f231a12024-05-31 17:55:06 +0800634 nmea_print(nmea, data_len);
635}
636
637#if 0
638static void gnss_cmd_rsp_process(const char *data, int data_len)
639{
640 char rsp[GNSS_BUFF_SIZE] = {0};
641 memcpy(rsp, data, data_len);
642 LOGD("RSP[%d]:%s", data_len, rsp);
643}
644#endif
645
646static bool nmea_char_check(char ch)
647{
648 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
yq.wang1ddd1fd2024-07-25 23:00:14 -0700649 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=' || ch == '-')
b.liu8f231a12024-05-31 17:55:06 +0800650 return TRUE;
651
652 return FALSE;
653}
654
655static void gnss_data_process(const char *data, int data_len)
656{
657 if(gnss_info.state == GNSS_STATE_OPEN) {
658 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
659 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
660 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800661 if(gnss_info.gnss_dl_read_cb) {
662 gnss_info.gnss_dl_read_cb(data, data_len);
663 }
b.liu8f231a12024-05-31 17:55:06 +0800664 } else if(gnss_info.state == GNSS_STATE_READY) {
665 int index = 0;
666 while(index < data_len) {
667 if(nmea_found) {
668 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800669 // Copy nmea_buff to data_buff
670 // Start with '$', but not nmea data, so copy to data_buff.
671 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
672 data_buff_len += nmea_buff_len;
673 data_buff[data_buff_len++] = data[index];
674
675 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800676 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800677 continue;
678 }
679
680 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800681 nmea_buff[nmea_buff_len++] = data[index];
682 if(nmea_buff[nmea_buff_len - 1] == '\n') {
683 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800684#if GNSS_DEBUG
685 log_save(nmea_log_fd, "/**/", 4);
686 log_save(nmea_log_fd, data_buff, data_buff_len);
687#endif
688 if(gnss_info.gnss_set_cb) {
689 gnss_info.gnss_set_cb(data_buff, data_buff_len);
690 }
b.liud0ba7152024-06-19 14:47:21 +0800691 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800692 }
693
b.liud0ba7152024-06-19 14:47:21 +0800694 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800695 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800696 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800697 } else if(nmea_buff_len > 0) {
698 nmea_buff[nmea_buff_len] = '\0';
b.liu42f558e2024-07-18 14:06:49 +0800699 if(memcmp(nmea_buff, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
700 LOGD("NO-NMEA:%s", nmea_buff);
701 }
b.liu99c645d2024-06-20 10:52:15 +0800702#if GNSS_DEBUG
703 log_save(nmea_log_fd, "/**/", 4);
704 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
705#endif
b.liud0ba7152024-06-19 14:47:21 +0800706 }
707
708 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800709 nmea_found = FALSE;
710 }
711 }
712 } else {
713 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800714 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800715 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800716 nmea_buff[nmea_buff_len++] = data[index];
717 } else {
718 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800719 }
720 }
721 index++;
722 }
723 } else {
724 LOGW("Unknown state : %d", gnss_info.state);
725 }
726}
727
728void* gnss_read_pthread(void* arg)
729{
730 LOGD("gnss_read_pthread enter.");
731 char buffer[GNSS_BUFF_SIZE];
732 int len = 0;
733 int ret = 0;
734 fd_set fdr, fdw;
735 int fd_max = 0;
736
b.liu8f231a12024-05-31 17:55:06 +0800737 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800738 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800739 memset(nmea_buff, 0, sizeof(nmea_buff));
740 memset(data_buff, 0, sizeof(data_buff));
741 nmea_buff_len = 0;
742 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800743#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800744 if(nmea_log_enable) {
745 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
746 if(debug_fd < 0) {
747 LOGE("Open debug fd fail.");
748 }
749 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
750 if(nmea_log_fd < 0) {
751 LOGE("Open nmea fd fail.");
752 }
b.liu99c645d2024-06-20 10:52:15 +0800753 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800754 }
755#endif
756
b.liudbc3f4b2024-06-25 18:22:24 +0800757 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
758
b.liu8f231a12024-05-31 17:55:06 +0800759 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800760 FD_ZERO(&fdw);
761 FD_ZERO(&fdr);
762 FD_SET(gnss_info.fd, &fdr);
763 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800764 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
765 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800766 if(gnss_info.state < GNSS_STATE_OPEN) {
767 LOGD("State = %d, ret = %d", gnss_info.state, ret);
768 if(ret > 0) {
769 if (FD_ISSET(gnss_info.fd, &fdr)) {
770 LOGD("gnss_fd can read.");
771 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
772 LOGD("exit_fd can read.");
773 } else {
774 LOGW("Unknown select event.");
775 }
776 }
777 break;
778 }
779
b.liu8f231a12024-05-31 17:55:06 +0800780 if (ret < 0)
781 {
782 if (errno == EINTR)
783 {
784 continue;
785 }
786 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
787 break;
788 }
789 else if (ret == 0)
790 {
791 LOGE("select ret == 0");
792 break;
793 }
794
795 if (FD_ISSET(gnss_info.fd, &fdr))
796 {
797 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800798 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800799 if(len > 0) {
800 //log_hex("READ", buffer, len);
801
802#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800803 //LOGD("read data_len = %d", len);
804 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800805#endif
806
807 gnss_data_process(buffer, len);
808
809 } else if(len ==0 ){
810 LOGE("Read end : len = 0");
811 break;
812 } else {
813 if(EAGAIN == errno) {
814 usleep(50000);
815 continue;
816 } else {
817 LOGD("Read ret = -1 ,errno = %d", errno);
818 break;
819 }
820 }
821 }
822 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
823 {
b.liuece0db02024-06-25 18:39:09 +0800824 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800825 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800826 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800827 if(len > 0) {
828 if(strcmp(buffer, "exit") == 0) {
829 LOGD("Get thread exit message.");
830 break;
831 }
832 }
833 }
834 else
835 {
836 LOGW("Unknown select event.");
837 continue;
838 }
839 }
840
841#if GNSS_DEBUG
842 if(debug_fd > 0) {
843 close(debug_fd);
844 debug_fd = -1;
845 }
846 if(nmea_log_fd > 0) {
847 close(nmea_log_fd);
848 nmea_log_fd = -1;
849 }
850#endif
851
852 gnss_info.state = GNSS_STATE_CLOSE;
853 LOGD("gnss_read_pthread exit.");
854 return NULL;
855}
856
857#if 0
858int gnss_write(int fd, const void *data, int data_len)
859{
860 int count = 0;
861 int len = 0;
862 while(1)
863 {
864 len = write(fd, data + count, data_len - count);
865 if (len > 0)
866 {
867 count += len;
868 }
869 else
870 {
871 LOGE("write() fail,ret = %d,errno = %d", len, errno);
872 break;
873 }
874
875 if (count == data_len)
876 break;
877 }
878
879 return count;
880}
881#else
b.liu778645e2024-06-21 16:47:42 +0800882int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800883{
b.liu778645e2024-06-21 16:47:42 +0800884 ssize_t size;
885 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800886 ssize_t size_written;
887 if(GNSS_BUFF_SIZE < buf_len)
888 {
889 return -1;
890 }
891 for(size = 0; size < buf_len;)
892 {
893 size_to_wr = buf_len - size;
894 if( size_to_wr > GNSS_BUFF_SIZE)
895 size_to_wr = GNSS_BUFF_SIZE;
896
b.liu778645e2024-06-21 16:47:42 +0800897 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800898 if (size_written==-1)
899 {
900 return -1;
901 }
902 size += size_written;
903 if(size_written != size_to_wr)
904 {
905 return size;
906 }
907 }
908 // LOGD("SEND %d / %d", size, buf_len);
909 return size;
910}
911#endif
912
913int gnss_init(uint32 print_port)
914{
915 if(gnss_info.state != GNSS_STATE_CLOSE) {
916 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800917 if(gnss_info.state == GNSS_STATE_READY) {
918 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
919 if(gnss_info.print_port != print_port) {
920 return gnss_ports_open(print_port);
921 } else {
922 return GNSS_ERR_OK;
923 }
924 } else {
925 return GNSS_ERR_OK;
926 }
b.liu8f231a12024-05-31 17:55:06 +0800927 }
928
929 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800930 if(gnss_info.dl_befor_open) {
931 //if(gnss_info.auto_dl_fw) {
932 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800933 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800934 if(ret) {
935 LOGE("gnss_fw_dl() fail : %d", ret);
936 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800937 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800938 }
b.liu8f231a12024-05-31 17:55:06 +0800939
b.liu99c645d2024-06-20 10:52:15 +0800940 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
941 if(gnss_info.fd <= 0) {
942 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
943 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800944 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800945 }
946 if(pipe(gnss_info.exit_fd)) {
947 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800948 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800949 }
950 // GNSS is opened.
951 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800952
b.liu99c645d2024-06-20 10:52:15 +0800953#if 0
954 // Start gnss read thread.
955 pthread_attr_t thread_attr;
956 pthread_attr_init(&thread_attr);
957 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
958 {
959 LOGE("pthread_attr_setdetachstate() fail.");
960 goto main_exit;
961 }
b.liu8f231a12024-05-31 17:55:06 +0800962
b.liu99c645d2024-06-20 10:52:15 +0800963 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800964#else
b.liu99c645d2024-06-20 10:52:15 +0800965 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800966#endif
b.liu99c645d2024-06-20 10:52:15 +0800967 {
968 LOGE("pthread_create() fail.");
969 goto exit_with_close;
970 }
b.liu8f231a12024-05-31 17:55:06 +0800971
b.liu99c645d2024-06-20 10:52:15 +0800972 ret = gnss_info.gnss_dev_open();
973 if(ret) {
974 LOGE("gnss_dev_open() fail : %d", ret);
975 goto exit_with_thread_exit;
976 }
977 //}
978 } else {
979 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
980 if(gnss_info.fd <= 0) {
981 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
982 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800983 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800984 }
985 if(pipe(gnss_info.exit_fd)) {
986 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800987 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800988 }
989 // GNSS is opened.
990 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800991
b.liu99c645d2024-06-20 10:52:15 +0800992#if 0
993 // Start gnss read thread.
994 pthread_attr_t thread_attr;
995 pthread_attr_init(&thread_attr);
996 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
997 {
998 LOGE("pthread_attr_setdetachstate() fail.");
999 goto main_exit;
1000 }
1001
1002 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
1003#else
1004 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
1005#endif
1006 {
1007 LOGE("pthread_create() fail.");
1008 goto exit_with_close;
1009 }
1010
1011 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +08001012 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +08001013 LOGE("gnss_dev_open() fail : %d", ret);
1014 goto exit_with_thread_exit;
1015 }
b.liu8f231a12024-05-31 17:55:06 +08001016 }
1017
1018 // GNSS is ready, NMEA can print from uart.
1019 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +08001020
1021 LOGD("GNSS open success.");
1022
b.liuced8dd02024-06-28 13:28:29 +08001023 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +08001024
b.liu8f231a12024-05-31 17:55:06 +08001025exit_with_thread_exit:
1026 gnss_info.state = GNSS_STATE_CLOSING;
1027 // Wait for read thread exit.
1028 ret = pthread_join(gnss_info.read_pid, NULL);
1029 if(ret){
1030 LOGE("pthrad_join fail(%d)",ret);
1031 }
1032exit_with_close:
1033 if(gnss_info.gnss_close(gnss_info.fd)) {
1034 LOGE("gnss_close() fail.");
1035 }
1036 if(gnss_info.exit_fd[0] > 0) {
1037 close(gnss_info.exit_fd[0]);
1038 gnss_info.exit_fd[0] = -1;
1039 }
1040 if(gnss_info.exit_fd[1] > 0) {
1041 close(gnss_info.exit_fd[1]);
1042 gnss_info.exit_fd[1] = -1;
1043 }
1044 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +08001045 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001046}
1047
1048int gnss_deinit()
1049{
1050 if(gnss_info.state == GNSS_STATE_CLOSE) {
1051 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +08001052 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +08001053 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
1054 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +08001055 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001056 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
1057 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +08001058 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001059 }
1060
b.liu978f5432024-07-01 18:04:18 +08001061 if(gnss_info.gnss_dev_close(gnss_info.fd)) {
1062 LOGE("gnss_dev_close() fail.");
1063 return GNSS_ERR_UNKNOWN;
1064 }
1065
b.liu8f231a12024-05-31 17:55:06 +08001066 // Wait for read thread exit.
1067 if(gnss_info.exit_fd[1] > 0) {
1068 write(gnss_info.exit_fd[1], "exit", 4);
1069 }
1070
1071 gnss_info.state = GNSS_STATE_CLOSING;
1072 int ret = pthread_join(gnss_info.read_pid, NULL);
1073 if(ret){
1074 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +08001075 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001076 }
1077
1078 if(gnss_info.gnss_close(gnss_info.fd)) {
1079 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +08001080 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001081 }
1082
b.liu8f231a12024-05-31 17:55:06 +08001083 if(gnss_ports_close()) {
1084 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +08001085 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001086 }
1087
b.liud0ba7152024-06-19 14:47:21 +08001088 LOGD("gnss_ports_close() complete.");
1089
b.liu8f231a12024-05-31 17:55:06 +08001090 gnss_info.fd = -1;
1091 if(gnss_info.exit_fd[0] > 0) {
1092 close(gnss_info.exit_fd[0]);
1093 gnss_info.exit_fd[0] = -1;
1094 }
1095 if(gnss_info.exit_fd[1] > 0) {
1096 close(gnss_info.exit_fd[1]);
1097 gnss_info.exit_fd[1] = -1;
1098 }
1099 gnss_info.state = GNSS_STATE_CLOSE;
1100 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +08001101 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +08001102}
1103
1104int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
1105{
b.liud0ba7152024-06-19 14:47:21 +08001106 if(buf && buf_len > 0) {
1107 if(cmd_rsp && cmd_rsp_len > 0) {
1108 memset(cmd_rsp, 0, cmd_rsp_len);
1109 }
b.liu8f231a12024-05-31 17:55:06 +08001110 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
1111 } else {
b.liudbc3f4b2024-06-25 18:22:24 +08001112 return GNSS_ERR_UNKNOWN;
1113 }
1114}
1115
1116int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
1117{
b.liu42f558e2024-07-18 14:06:49 +08001118 // Only 8122 support download fw.
b.liudbc3f4b2024-06-25 18:22:24 +08001119 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
1120 return GNSS_ERR_UNSUPPORT;
1121 }
1122
1123 if(rsp && rsp_len > 0) {
1124 memset(rsp, 0, rsp_len);
1125 }
1126
1127 if(gnss_info.gnss_fw_dl) {
1128 if(GNSS_ERR_OK != gnss_deinit()) {
1129 LOGE("Close gnss fail.");
1130 return GNSS_ERR_UNKNOWN;
1131 } else {
1132 LOGD("Start gnss fw dl.");
1133 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
1134 }
1135 } else {
b.liu42f558e2024-07-18 14:06:49 +08001136 return GNSS_ERR_UNSUPPORT;
b.liu8f231a12024-05-31 17:55:06 +08001137 }
1138}
1139
b.liue77ac3a2024-07-17 17:36:57 +08001140int gnss_ind_set(int fd, int ind_type)
1141{
1142 int index = 0;
1143 if(ind_type) { // Add IND flag.
1144 while(index < GNSS_CLI_IND_MAX) {
1145 if(ind_info[index].cli_fd == fd)
1146 break;
1147 index++;
1148 }
1149
1150 if(index == GNSS_CLI_IND_MAX) { // Add flag
1151 index = 0;
1152 while(index < GNSS_CLI_IND_MAX) {
1153 if(ind_info[index].cli_fd <= 0)
1154 break;
1155 index++;
1156 }
yq.wang1ddd1fd2024-07-25 23:00:14 -07001157 if(index == GNSS_CLI_IND_MAX)
1158 {
1159 LOGE("ind flag is full.");
1160 return GNSS_ERR_CLI_FULL;
1161 }
b.liue77ac3a2024-07-17 17:36:57 +08001162 ind_info[index].cli_fd = fd;
1163 ind_info[index].ind_flag = (uint32)ind_type;
b.liubcf86c92024-08-19 19:48:28 +08001164 } else { // Change flag
b.liue77ac3a2024-07-17 17:36:57 +08001165 ind_info[index].cli_fd = fd;
1166 ind_info[index].ind_flag = (uint32)ind_type;
1167 }
1168 } else { // Clear IND flag.
1169 while(index < GNSS_CLI_IND_MAX) {
1170 if(ind_info[index].cli_fd == fd)
1171 break;
1172 index++;
1173 }
1174
1175 if(index == GNSS_CLI_IND_MAX) {
1176 return GNSS_ERR_ARG;
b.liubcf86c92024-08-19 19:48:28 +08001177 }
b.liue77ac3a2024-07-17 17:36:57 +08001178 ind_info[index].cli_fd = 0;
1179 ind_info[index].ind_flag = 0;
1180 }
1181
1182 return GNSS_ERR_OK;
1183}
1184
b.liu8f231a12024-05-31 17:55:06 +08001185static void sig_process(int sig)
1186{
1187 LOGI("I got signal %d\n", sig);
1188 if(gnss_deinit()) {
1189 LOGE("gnss_deinit() fail, no exist...");
1190 return;
1191 }
1192
1193 switch(sig)
1194 {
1195 case SIGINT: // Ctrl + C
1196 {
1197 LOGI("Exit by SIGINT.\n");
1198 exit(0);
1199 }
luojiand7960682024-08-02 16:50:01 +08001200 case SIGQUIT: // Ctrl + \ (\C0\E0\CB\C6 SIGINT \A3\AC\B5\ABҪ\B2\FA\C9\FAcore\CEļ\FE)
b.liu8f231a12024-05-31 17:55:06 +08001201 {
1202 LOGI("Exit by SIGQUIT.\n");
1203 exit(0);
1204 }
luojiand7960682024-08-02 16:50:01 +08001205 case SIGTERM:// Ĭ\C8\CFkill (ͬ SIGKILL \A3\AC\B5\AB SIGKILL \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001206 {
1207 LOGI("Exit by SIGTERM.\n");
1208 exit(0);
1209 }
luojiand7960682024-08-02 16:50:01 +08001210 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP \A3\AC\B5\AB SIGSTOP \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001211 {
1212 LOGI("Exit by SIGTSTP.\n");
1213 exit(0);
1214 }
luojiand7960682024-08-02 16:50:01 +08001215 case SIGSEGV: // \C8\E7\BF\D5Ö¸\D5\EB
b.liu8f231a12024-05-31 17:55:06 +08001216 {
1217 LOGI("Exit by SIGSEGV.\n");
1218 exit(0);
1219 }
1220 default:
1221 {
1222 LOGI("Unknown sig:%d\n",sig);
1223 break;
1224 }
1225 }
1226}
1227
1228
b.liuced8dd02024-06-28 13:28:29 +08001229// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +08001230int main(int argc, char *argv[])
1231{
1232 mbtk_log_init("radio", GNSS_TAG);
1233
b.liubcf86c92024-08-19 19:48:28 +08001234 MBTK_SOURCE_INFO_PRINT("mbtk_gnssd");
1235
b.liubb590492024-06-13 16:42:08 +08001236#ifdef MBTK_DUMP_SUPPORT
1237 mbtk_debug_open(NULL, TRUE);
1238#endif
1239
b.liu8f231a12024-05-31 17:55:06 +08001240 signal(SIGINT, sig_process);
1241 signal(SIGQUIT, sig_process);
1242 signal(SIGTERM, sig_process);
1243
1244 if(arg_check(argc, argv)) {
1245 return -1;
1246 }
1247
1248#ifdef GNSS_DEBUG
1249 char buff[10];
1250 memset(buff, 0, 10);
1251 property_get(MBTK_PROP_GNSS_LOG, buff, "");
1252 if(strlen(buff) > 0 && atoi(buff) > 0) {
1253 nmea_log_enable = TRUE;
1254 }
1255#endif
1256
1257 memset(&gnss_info, 0, sizeof(gnss_info_t));
1258 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
1259 gnss_info.state = GNSS_STATE_CLOSE;
1260 if(!strcmp(argv[1], GNSS_ID_6228)) {
1261 gnss_info.gnss_id = GNSS_TYPE_6228;
1262 gnss_info.auto_open = (bool)atoi(argv[3]);
1263 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +08001264 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +08001265 gnss_info.gnss_dev_open = gnss_6228_dev_open;
1266 gnss_info.gnss_dev_close = gnss_6228_dev_close;
1267 gnss_info.gnss_open = gnss_6228_open;
1268 gnss_info.gnss_close = gnss_6228_close;
1269 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
1270 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
1271 gnss_info.gnss_set = gnss_6228_set;
1272 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +08001273 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
1274 gnss_info.gnss_id = GNSS_TYPE_8122;
1275 gnss_info.auto_open = (bool)atoi(argv[3]);
1276 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +08001277 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +08001278 gnss_info.gnss_dev_open = gnss_8122_dev_open;
1279 gnss_info.gnss_dev_close = gnss_8122_dev_close;
1280 gnss_info.gnss_open = gnss_8122_open;
1281 gnss_info.gnss_close = gnss_8122_close;
1282 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
1283 gnss_info.gnss_dl_read_cb = NULL;
1284 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +08001285 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +08001286 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
1287 gnss_info.gnss_id = GNSS_TYPE_5311;
1288 gnss_info.auto_open = (bool)atoi(argv[3]);
1289 gnss_info.auto_dl_fw = TRUE;
1290 gnss_info.dl_befor_open = TRUE;
1291 gnss_info.gnss_dev_open = gnss_5311_dev_open;
1292 gnss_info.gnss_dev_close = gnss_5311_dev_close;
1293 gnss_info.gnss_open = gnss_5311_open;
1294 gnss_info.gnss_close = gnss_5311_close;
1295 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
1296 gnss_info.gnss_dl_read_cb = NULL;
1297 gnss_info.gnss_set = gnss_5311_set;
1298 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu42f558e2024-07-18 14:06:49 +08001299 } else if(!strcmp(argv[1], GNSS_ID_N50DB)) {
1300 gnss_info.gnss_id = GNSS_TYPE_N50DB;
1301 gnss_info.auto_open = (bool)atoi(argv[3]);
1302 gnss_info.auto_dl_fw = FALSE;
1303 gnss_info.dl_befor_open = FALSE;
1304 gnss_info.gnss_dev_open = gnss_n50db_dev_open;
1305 gnss_info.gnss_dev_close = gnss_n50db_dev_close;
1306 gnss_info.gnss_open = gnss_n50db_open;
1307 gnss_info.gnss_close = gnss_n50db_close;
1308 gnss_info.gnss_fw_dl = gnss_n50db_fw_dl;
1309 gnss_info.gnss_dl_read_cb = NULL;
1310 gnss_info.gnss_set = gnss_n50db_set;
1311 gnss_info.gnss_set_cb = gnss_n50db_set_cb;
b.liu8f231a12024-05-31 17:55:06 +08001312 } else {
1313 LOGE("No support : %s", argv[1]);
1314 return -1;
1315 }
1316
1317 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
1318 // Auto open gnss.
1319 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +08001320 int init_mode = atoi(argv[3]);
1321 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
1322 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +08001323 }
b.liuced8dd02024-06-28 13:28:29 +08001324 if(gnss_init((uint32)init_mode)) {
1325 LOGE("gnss_init() fail.");
1326 // return -1;
1327 }
1328 } else {
1329 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +08001330 }
1331
b.liua1b69262024-09-04 16:32:59 +08001332#if MBTK_GNSS_PTY_AUTO_INIT
1333 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
1334 LOGE("gnss_pty_open() fail.");
1335 return -1;
1336 }
1337#endif
1338
b.liu8f231a12024-05-31 17:55:06 +08001339 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +08001340#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +08001341 if(gnss_ubus_init()) {
1342 LOGD("main() run...");
1343 uloop_run();
1344 } else {
1345 LOGE("gnss_ubus_init() fail.");
1346 }
b.liu5f950c52024-06-15 20:13:12 +08001347#else
1348 if(!gnss_ipc_service_start()) {
1349 LOGD("main() run...");
1350 while(1) {
1351 sleep(24 * 60 * 60);
1352 }
1353 } else {
1354 LOGE("gnss_ipc_service_start() fail.");
1355 }
1356#endif
b.liu8f231a12024-05-31 17:55:06 +08001357
1358 LOGD("main() exit.");
1359 return 0;
1360}