blob: c0eae059994b5a6f8547f3da28151e12e20dcc08 [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.liubcf86c92024-08-19 19:48:28 +080041gnss_info_t gnss_info;
b.liu8f231a12024-05-31 17:55:06 +080042
b.liud0ba7152024-06-19 14:47:21 +080043#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080044struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080045#else
46int gnss_ipc_service_start();
47#endif
48
b.liu8f231a12024-05-31 17:55:06 +080049int gnss_init_config(int fd);
50
wangyouqiangfa897f82024-06-27 09:44:55 +080051static char nmea_buff[GNSS_BUFF_SIZE*4] = {0};
52static char data_buff[GNSS_BUFF_SIZE*4] = {0};
b.liud0ba7152024-06-19 14:47:21 +080053static uint32 nmea_buff_len = 0;
54static uint32 data_buff_len = 0;
b.liue77ac3a2024-07-17 17:36:57 +080055static gnss_ind_info_t ind_info[GNSS_CLI_IND_MAX];
b.liud0ba7152024-06-19 14:47:21 +080056
b.liu8f231a12024-05-31 17:55:06 +080057static bool nmea_found = FALSE;
58#ifdef GNSS_DEBUG
59static bool nmea_log_enable = FALSE;
60static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080061static int debug_fd = -1;
62static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080063#endif
yq.wang5c647e02024-08-10 00:01:11 -070064
65static bool mbtk_gnss_time_set_flag = 0;
66
b.liu8f231a12024-05-31 17:55:06 +080067static int gnss_pty_master_fd = -1;
68static int gnss_pty_slave_fd = -1;
69static int gnss_usb_at_port_fd = -1;
70static int gnss_usb_nmea_port_fd = -1;
71static int gnss_uart_at_port_fd = -1;
72static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
73
b.liue77ac3a2024-07-17 17:36:57 +080074int gnss_write(int fd, const void* buf, int buf_len);
75
b.liu8f231a12024-05-31 17:55:06 +080076static void help()
77{
b.liu42f558e2024-07-18 14:06:49 +080078 LOGD("mbtk_gnssd <6228/8122/5311/N50DB> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080079}
80
81static int arg_check(int argc, char *argv[])
82{
83 if(argc != 4) {
b.liu4ae41182024-06-28 16:30:15 +080084 LOGE("argc = %d", argc);
b.liu8f231a12024-05-31 17:55:06 +080085 goto check_fail;
86 }
87
b.liu99c645d2024-06-20 10:52:15 +080088 // Only support 6228/8122/5311.
b.liu42f558e2024-07-18 14:06:49 +080089 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)
90 && strcmp(argv[1], GNSS_ID_N50DB)) {
b.liu4ae41182024-06-28 16:30:15 +080091 LOGE("argv[1] = %s", argv[1]);
b.liu8f231a12024-05-31 17:55:06 +080092 goto check_fail;
93 }
94
95 if(access(argv[2], R_OK | W_OK)) {
b.liu4ae41182024-06-28 16:30:15 +080096 LOGE("access(%s) rw fail. ", argv[2]);
b.liu8f231a12024-05-31 17:55:06 +080097 goto check_fail;
98 }
99
b.liuced8dd02024-06-28 13:28:29 +0800100#if 0
101 int init_mode = atoi(argv[3]);
102 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 +0800103 goto check_fail;
104 }
b.liuced8dd02024-06-28 13:28:29 +0800105#endif
b.liu8f231a12024-05-31 17:55:06 +0800106
107 return 0;
108check_fail:
109 help();
110 return -1;
111}
112
113static int gnss_ports_open(uint32 print_port)
114{
b.liuced8dd02024-06-28 13:28:29 +0800115 // TTY AT change.
116 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
117 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
118 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
119 return GNSS_ERR_OPEN_DEV;
120 }
121 LOGD("Open PTY port success.");
122 } else { // Close
123 if(gnss_pty_slave_fd > 0) {
124 close(gnss_pty_slave_fd);
125 gnss_pty_slave_fd = -1;
126 unlink(GNSS_PORT_PTY);
127 }
128 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800129 }
b.liu8f231a12024-05-31 17:55:06 +0800130 }
131
b.liuced8dd02024-06-28 13:28:29 +0800132 // USB AT change.
133 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
134 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
b.liu978f5432024-07-01 18:04:18 +0800135 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 +0800136 return GNSS_ERR_OPEN_DEV;
137 }
138 LOGD("Open USB AT port success.");
139 } else { // Close
140 if(gnss_usb_at_port_fd > 0) {
141 close(gnss_usb_at_port_fd);
142 gnss_usb_at_port_fd = -1;
143 }
144 LOGD("Close USB AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800145 }
b.liu8f231a12024-05-31 17:55:06 +0800146 }
147
b.liuced8dd02024-06-28 13:28:29 +0800148 // USB NMEA change.
149 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
150 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
b.liu978f5432024-07-01 18:04:18 +0800151 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 +0800152 return GNSS_ERR_OPEN_DEV;
153 }
154 LOGD("Open USB NMEA port success.");
155 } else { // Close
156 if(gnss_usb_nmea_port_fd > 0) {
157 close(gnss_usb_nmea_port_fd);
158 gnss_usb_nmea_port_fd = -1;
159 }
160 LOGD("Close USB NMEA port success.");
b.liu8f231a12024-05-31 17:55:06 +0800161 }
b.liu8f231a12024-05-31 17:55:06 +0800162 }
163
b.liuced8dd02024-06-28 13:28:29 +0800164 // Uart AT change.
165 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
166 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
167 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
168 return GNSS_ERR_OPEN_DEV;
169 }
170 LOGD("Open UART AT port success.");
171 } else { // Close
172 if(gnss_uart_at_port_fd > 0) {
173 close(gnss_uart_at_port_fd);
174 gnss_uart_at_port_fd = -1;
175 }
176 LOGD("Close UART AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800177 }
b.liu8f231a12024-05-31 17:55:06 +0800178 }
179
b.liuced8dd02024-06-28 13:28:29 +0800180 gnss_info.print_port = print_port;
181
b.liudbc3f4b2024-06-25 18:22:24 +0800182 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800183}
184
185static int gnss_ports_close()
186{
187 if(gnss_usb_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800188 tcflush(gnss_usb_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800189 close(gnss_usb_at_port_fd);
190 gnss_usb_at_port_fd = -1;
191 }
192
193 if(gnss_usb_nmea_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800194 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800195 close(gnss_usb_nmea_port_fd);
196 gnss_usb_nmea_port_fd = -1;
197 }
198
199 if(gnss_uart_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800200 tcflush(gnss_uart_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800201 close(gnss_uart_at_port_fd);
202 gnss_uart_at_port_fd = -1;
203 }
204
205 if(gnss_pty_master_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800206 tcflush(gnss_pty_master_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800207 close(gnss_pty_master_fd);
208 gnss_pty_master_fd = -1;
209 }
210
211 if(gnss_pty_slave_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800212 tcflush(gnss_pty_slave_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800213 close(gnss_pty_slave_fd);
214 gnss_pty_slave_fd = -1;
215 unlink(GNSS_PORT_PTY);
216 }
217
b.liuced8dd02024-06-28 13:28:29 +0800218 gnss_info.print_port = 0;
219
b.liu8f231a12024-05-31 17:55:06 +0800220 return 0;
221}
222
b.liu8f231a12024-05-31 17:55:06 +0800223#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800224static void log_save(int fd, const char *data, int data_len)
225{
b.liu8f231a12024-05-31 17:55:06 +0800226 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800227 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
228 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
229 close(debug_fd);
230 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
231 if(debug_fd < 0) {
232 LOGE("Open debug fd fail.");
233 }
234 debug_fd_len = 0;
235
236 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800237 close(nmea_log_fd);
238 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
239 if(nmea_log_fd < 0) {
240 LOGE("Open debug fd fail.");
241 }
b.liu8f231a12024-05-31 17:55:06 +0800242 }
243
b.liu99c645d2024-06-20 10:52:15 +0800244 if(fd == nmea_log_fd) {
245 if(nmea_log_fd > 0) {
246 write(nmea_log_fd, data, data_len);
247 debug_fd_len += data_len;
248 }
249 } else if(fd == debug_fd) {
250 if(debug_fd > 0) {
251 write(debug_fd, data, data_len);
252 debug_fd_len += data_len;
253 }
b.liu8f231a12024-05-31 17:55:06 +0800254 }
255 }
b.liu99c645d2024-06-20 10:52:15 +0800256}
b.liu8f231a12024-05-31 17:55:06 +0800257#endif
258
b.liue77ac3a2024-07-17 17:36:57 +0800259static void ind_location_print(const char *data)
260{
261 int index = 0;
262 int buff_len = 0;
263 char buff[GNSS_BUFF_SIZE] = {0};
264 buff[0] = MBTK_IND_START_FLAG;
265 buff_len++;
266 memcpy(buff + 1, MBTK_IND_LOCATION_TAG, strlen(MBTK_IND_LOCATION_TAG));
267 buff_len += strlen(MBTK_IND_LOCATION_TAG);
268 memcpy(buff + strlen(buff), data, strlen(data));
269 buff_len += strlen(data);
270 buff[strlen(buff)] = MBTK_IND_END_FLAG;
271 buff_len++;
272
273 while(index < GNSS_CLI_IND_MAX) {
274 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_LOCATION)) {
275 gnss_write(ind_info[index].cli_fd, buff, buff_len);
276 }
277 index++;
278 }
279}
280
281static void ind_nmea_print(const char *data)
282{
283 int index = 0;
284 int buff_len = 0;
285 char buff[GNSS_BUFF_SIZE] = {0};
286 buff[0] = MBTK_IND_START_FLAG;
287 buff_len++;
288 memcpy(buff + 1, MBTK_IND_NMEA_TAG, strlen(MBTK_IND_NMEA_TAG));
289 buff_len += strlen(MBTK_IND_NMEA_TAG);
290 memcpy(buff + strlen(buff), data, strlen(data));
291 buff_len += strlen(data);
292 buff[strlen(buff)] = MBTK_IND_END_FLAG;
293 buff_len++;
294 while(index < GNSS_CLI_IND_MAX) {
295 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_NMEA)) {
296 gnss_write(ind_info[index].cli_fd, buff, buff_len);
297 }
298 index++;
299 }
300}
301
b.liu99c645d2024-06-20 10:52:15 +0800302static void nmea_print(const char *nmea, int nmea_len)
303{
yq.wang1ddd1fd2024-07-25 23:00:14 -0700304 int ret = -1;
b.liu8f231a12024-05-31 17:55:06 +0800305 if(gnss_usb_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700306 ret = write(gnss_usb_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800307 }
308
309 if(gnss_usb_nmea_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700310 ret = write(gnss_usb_nmea_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800311 }
312
313 if(gnss_uart_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700314 ret = write(gnss_uart_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800315 }
316
317 if(gnss_pty_master_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700318 ret = write(gnss_pty_master_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800319 }
yq.wang937355d2024-07-26 01:24:42 -0700320 ind_nmea_print(nmea);
321 ind_location_print(nmea);
b.liu8f231a12024-05-31 17:55:06 +0800322}
323
324static unsigned char nmea_checksum(const char *nmea)
325{
326 const char *p = nmea;
327 unsigned char chs = 0;
328
329 while (*p == '$') // skip '$'
330 p++;
331 while (*p != '*' && *p != 0)
332 chs ^= *p++;
333
334 return chs;
335}
336
337static bool nmea_check(const char *nmea, int nmea_len)
338{
339 char **ptr = gnss_filter_info;
340 while(*ptr) {
341 if(strstr(nmea, *ptr)) {
342 break;
343 }
344 ptr++;
345 }
346
347 if(*ptr == NULL) {
348 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
349 return FALSE;
350 }
351
352 char *checksum_str = strstr(nmea, "*");
353 checksum_str++; // Jump '*'
354 char checksum_buf[3] = {0};
355 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
356 if(strncasecmp(checksum_buf, checksum_str, 2)) {
357 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
358 return FALSE;
359 }
360
361 return TRUE;
362}
363
luojiand7960682024-08-02 16:50:01 +0800364static int nmea_tokenizer_init(mbtk_nmeatokenizer* t, const char* head, const char* end, int param_num)
365{
366 int count = 0;
367 const char* p = head;
368 const char* q = end;
369 const char* tmp = NULL;
370 // the initial '$' is optional
371 if (p < q && p[0] == '$')
372 {
373 p += 1;
374 }
375 else
376 {
377 return -1;
378 }
379
380 //find '*',del '*25\r\n'
381 // get rid of checksum at the end of the sentecne
382 if (q >= p + 5 && q[-5] == '*')
383 {
384 q -= 5;
385 }
386 else
387 {
388 return -1;
389 }
390
b.liubcf86c92024-08-19 19:48:28 +0800391 while (p <= q)
luojiand7960682024-08-02 16:50:01 +0800392 {
393 tmp = memchr(p, ',', q-p);
394 if (tmp == NULL)
395 {
396 tmp = q;
397 }
398 // if (q > p) {
399 // q >= p include empty token: ,,
400 if (tmp >= p)
401 {
402 if (count < MAX_NMEA_TOKENS)
403 {
404 t->tokens[count].head = p;
405 t->tokens[count].end = tmp;
406 count += 1;
407 }
408 }
b.liubcf86c92024-08-19 19:48:28 +0800409
luojiand7960682024-08-02 16:50:01 +0800410 if (tmp <= q)
411 {
412 tmp += 1;
413 }
414
415 p = tmp;
416 }
417
418 if(count != param_num)
419 {
420 LOGD("count [%d], param_num [%d]", count, param_num);
421 return -1;
422 }
423
424 t->count = count;
425 return count;
426}
427
428static mbtk_token nmea_tokenizer_get(mbtk_nmeatokenizer* t, int index)
429{
430 mbtk_token tok;
431 static const char* dummy = "";
432
433 if (index < 0 || index >= t->count)
434 {
435 tok.head = tok.end = dummy;
436 }
437 else
438 {
439 tok = t->tokens[index];
440 }
441 return tok;
442}
443
luojiand7960682024-08-02 16:50:01 +0800444static int mbtk_time_type_gnss_read() {
445 int type = 0;
446 char time_type[] ={0};
447 property_get("persist.mbtk.time_type", time_type, "0");
448
449 type = atoi(time_type);
450// LOGD("time_type :%d\n", type);
451 if(type != LYNQ_TIME_TYPE_GNSS)
452 mbtk_gnss_time_set_flag = 0;
453
454 return type;
455}
456
457static int strstr_n(const char *s1, const char *s2)
458{
459 int n;
460 int strlen = 0;
461
462 if(*s2)
463 {
464 while(*s1)
465 {
466 for(n = 0; *(s1+n) == *(s2 + n); n++)
467 {
468 if(!*(s2 + n + 1))
469 {
470 strlen++;
471 return strlen;
472 }
473 }
474 s1++;
475 strlen++;
476 }
477 return 0;
478 }
479
480 return 0;
481}
482static int nmea_update_date_time(mbtk_token date, mbtk_token time)
483{
484 char tmp_char[4] = {0};
485 struct tm tmp_time;
486 struct timeval tv;
487
488 memset(&tmp_time, 0x0, sizeof(struct tm));
489 if (date.head + 6 > date.end)
490 {
491 LOGD("date get fail");
492 return -1;
493 }
494
495 memcpy(tmp_char, date.head, 2);
496 tmp_time.tm_mday = atoi(tmp_char);
497 memcpy(tmp_char, date.head + 2, 2);
498 tmp_time.tm_mon = atoi(tmp_char) - 1;
499 memcpy(tmp_char, date.head + 4, 2);
500 tmp_time.tm_year = 100 + atoi(tmp_char);
501
502 if (time.head + 6 > time.end)
503 {
504 LOGD("time get fail");
505 return -1;
506 }
507
508 memcpy(tmp_char, time.head, 2);
509 tmp_time.tm_hour = atoi(tmp_char);
510 memcpy(tmp_char, time.head + 2, 2);
511 tmp_time.tm_min = atoi(tmp_char);
512 memcpy(tmp_char, time.head + 4, 2);
513 tmp_time.tm_sec = atoi(tmp_char);
514 tmp_time.tm_isdst = -1;
luojiand7960682024-08-02 16:50:01 +0800515
b.liubcf86c92024-08-19 19:48:28 +0800516
517 LOGD("data:%d-%d-%d %d:%d:%d", tmp_time.tm_year + 1900,
luojiand7960682024-08-02 16:50:01 +0800518 tmp_time.tm_mon,
519 tmp_time.tm_mday,
520 tmp_time.tm_hour,
521 tmp_time.tm_min,
522 tmp_time.tm_sec);
523
524
525 time_t _t = mktime(&tmp_time);//parse location tmp_time
526
527 tzset(); // auto set tz
528 _t = _t - timezone;
529
530 LOGD("timestamp:%ld, %ld", _t, timezone);
531
532 tv.tv_sec = _t;
533 if(settimeofday(&tv, NULL)) {
534 LOGD("%s: , Set time fail\n", __func__);
535 mbtk_gnss_time_set_flag = 0;
536 } else {
537 LOGD("%s: , Set time success \n", __func__);
luojian51d65f92024-08-08 15:39:42 +0800538 system("hwclock -w rtc0");
539 mbtk_gnss_time_set_flag = 1;
luojiand7960682024-08-02 16:50:01 +0800540 }
541
542 return 0;
543}
544
545static int ind_nmea_parse(const char *data, int data_len)
546{
547 int ret;
548 mbtk_nmeatokenizer tzer = {0};
549 if(strstr_n(data + 3, "RMC"))
550 {
551 ret = nmea_tokenizer_init(&tzer, data, data + data_len, NMEA_RMC_PARAM_NUM);
552 if(ret < 0)
553 {
554 LOGD("nmea_tokenizer_init fail");
555 return -1;
556 }
557
558 mbtk_token tok_time = nmea_tokenizer_get(&tzer,1);
559 mbtk_token tok_fixStatus = nmea_tokenizer_get(&tzer,2);
560 mbtk_token tok_date = nmea_tokenizer_get(&tzer,9);
561
562 if(tok_fixStatus.head[0] == 'A')
563 {
564 ret = nmea_update_date_time(tok_date, tok_time);
565 if(ret < 0)
566 {
567 LOGD("nmea_update_date_time fail");
568 return -1;
569 }
570
571 }
572 }
573
574 return 0;
575}
576
577
b.liu8f231a12024-05-31 17:55:06 +0800578static void gnss_nmea_process(const char *data, int data_len)
579{
luojiand7960682024-08-02 16:50:01 +0800580// LOGD("gnss_nmea_process() : data_len - %d", data_len);
b.liu99c645d2024-06-20 10:52:15 +0800581#if 0
b.liu8f231a12024-05-31 17:55:06 +0800582 char nmea[GNSS_BUFF_SIZE] = {0};
583 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800584#else
585 const char *nmea = data;
586#endif
b.liu8f231a12024-05-31 17:55:06 +0800587
588 if(!nmea_check(nmea, data_len)) {
b.liu42f558e2024-07-18 14:06:49 +0800589 // No print "$HOSTSLEEP".
590 if(memcmp(nmea, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
591 LOGD("NO-NMEA:%s", nmea);
592 }
b.liu99c645d2024-06-20 10:52:15 +0800593#if GNSS_DEBUG
594 log_save(nmea_log_fd, "/**/", 4);
595 log_save(nmea_log_fd, nmea, data_len);
596#endif
597 if(gnss_info.gnss_set_cb)
598 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800599 return;
600 }
601
602#ifdef GNSS_DEBUG
603 if(nmea_log_enable) {
604 LOGD("NMEA[%d]:%s", data_len, nmea);
605 }
b.liu99c645d2024-06-20 10:52:15 +0800606
607 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800608#endif
609
luojiand7960682024-08-02 16:50:01 +0800610 if( (mbtk_time_type_gnss_read() == LYNQ_TIME_TYPE_GNSS) && !mbtk_gnss_time_set_flag)
611 ind_nmea_parse(nmea, data_len);
612
b.liu8f231a12024-05-31 17:55:06 +0800613 nmea_print(nmea, data_len);
614}
615
616#if 0
617static void gnss_cmd_rsp_process(const char *data, int data_len)
618{
619 char rsp[GNSS_BUFF_SIZE] = {0};
620 memcpy(rsp, data, data_len);
621 LOGD("RSP[%d]:%s", data_len, rsp);
622}
623#endif
624
625static bool nmea_char_check(char ch)
626{
627 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
yq.wang1ddd1fd2024-07-25 23:00:14 -0700628 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=' || ch == '-')
b.liu8f231a12024-05-31 17:55:06 +0800629 return TRUE;
630
631 return FALSE;
632}
633
634static void gnss_data_process(const char *data, int data_len)
635{
636 if(gnss_info.state == GNSS_STATE_OPEN) {
637 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
638 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
639 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800640 if(gnss_info.gnss_dl_read_cb) {
641 gnss_info.gnss_dl_read_cb(data, data_len);
642 }
b.liu8f231a12024-05-31 17:55:06 +0800643 } else if(gnss_info.state == GNSS_STATE_READY) {
644 int index = 0;
645 while(index < data_len) {
646 if(nmea_found) {
647 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800648 // Copy nmea_buff to data_buff
649 // Start with '$', but not nmea data, so copy to data_buff.
650 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
651 data_buff_len += nmea_buff_len;
652 data_buff[data_buff_len++] = data[index];
653
654 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800655 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800656 continue;
657 }
658
659 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800660 nmea_buff[nmea_buff_len++] = data[index];
661 if(nmea_buff[nmea_buff_len - 1] == '\n') {
662 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800663#if GNSS_DEBUG
664 log_save(nmea_log_fd, "/**/", 4);
665 log_save(nmea_log_fd, data_buff, data_buff_len);
666#endif
667 if(gnss_info.gnss_set_cb) {
668 gnss_info.gnss_set_cb(data_buff, data_buff_len);
669 }
b.liud0ba7152024-06-19 14:47:21 +0800670 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800671 }
672
b.liud0ba7152024-06-19 14:47:21 +0800673 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800674 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800675 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800676 } else if(nmea_buff_len > 0) {
677 nmea_buff[nmea_buff_len] = '\0';
b.liu42f558e2024-07-18 14:06:49 +0800678 if(memcmp(nmea_buff, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
679 LOGD("NO-NMEA:%s", nmea_buff);
680 }
b.liu99c645d2024-06-20 10:52:15 +0800681#if GNSS_DEBUG
682 log_save(nmea_log_fd, "/**/", 4);
683 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
684#endif
b.liud0ba7152024-06-19 14:47:21 +0800685 }
686
687 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800688 nmea_found = FALSE;
689 }
690 }
691 } else {
692 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800693 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800694 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800695 nmea_buff[nmea_buff_len++] = data[index];
696 } else {
697 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800698 }
699 }
700 index++;
701 }
702 } else {
703 LOGW("Unknown state : %d", gnss_info.state);
704 }
705}
706
707void* gnss_read_pthread(void* arg)
708{
709 LOGD("gnss_read_pthread enter.");
710 char buffer[GNSS_BUFF_SIZE];
711 int len = 0;
712 int ret = 0;
713 fd_set fdr, fdw;
714 int fd_max = 0;
715
b.liu8f231a12024-05-31 17:55:06 +0800716 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800717 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800718 memset(nmea_buff, 0, sizeof(nmea_buff));
719 memset(data_buff, 0, sizeof(data_buff));
720 nmea_buff_len = 0;
721 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800722#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800723 if(nmea_log_enable) {
724 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
725 if(debug_fd < 0) {
726 LOGE("Open debug fd fail.");
727 }
728 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
729 if(nmea_log_fd < 0) {
730 LOGE("Open nmea fd fail.");
731 }
b.liu99c645d2024-06-20 10:52:15 +0800732 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800733 }
734#endif
735
b.liudbc3f4b2024-06-25 18:22:24 +0800736 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
737
b.liu8f231a12024-05-31 17:55:06 +0800738 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800739 FD_ZERO(&fdw);
740 FD_ZERO(&fdr);
741 FD_SET(gnss_info.fd, &fdr);
742 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800743 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
744 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800745 if(gnss_info.state < GNSS_STATE_OPEN) {
746 LOGD("State = %d, ret = %d", gnss_info.state, ret);
747 if(ret > 0) {
748 if (FD_ISSET(gnss_info.fd, &fdr)) {
749 LOGD("gnss_fd can read.");
750 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
751 LOGD("exit_fd can read.");
752 } else {
753 LOGW("Unknown select event.");
754 }
755 }
756 break;
757 }
758
b.liu8f231a12024-05-31 17:55:06 +0800759 if (ret < 0)
760 {
761 if (errno == EINTR)
762 {
763 continue;
764 }
765 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
766 break;
767 }
768 else if (ret == 0)
769 {
770 LOGE("select ret == 0");
771 break;
772 }
773
774 if (FD_ISSET(gnss_info.fd, &fdr))
775 {
776 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800777 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800778 if(len > 0) {
779 //log_hex("READ", buffer, len);
780
781#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800782 //LOGD("read data_len = %d", len);
783 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800784#endif
785
786 gnss_data_process(buffer, len);
787
788 } else if(len ==0 ){
789 LOGE("Read end : len = 0");
790 break;
791 } else {
792 if(EAGAIN == errno) {
793 usleep(50000);
794 continue;
795 } else {
796 LOGD("Read ret = -1 ,errno = %d", errno);
797 break;
798 }
799 }
800 }
801 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
802 {
b.liuece0db02024-06-25 18:39:09 +0800803 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800804 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800805 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800806 if(len > 0) {
807 if(strcmp(buffer, "exit") == 0) {
808 LOGD("Get thread exit message.");
809 break;
810 }
811 }
812 }
813 else
814 {
815 LOGW("Unknown select event.");
816 continue;
817 }
818 }
819
820#if GNSS_DEBUG
821 if(debug_fd > 0) {
822 close(debug_fd);
823 debug_fd = -1;
824 }
825 if(nmea_log_fd > 0) {
826 close(nmea_log_fd);
827 nmea_log_fd = -1;
828 }
829#endif
830
831 gnss_info.state = GNSS_STATE_CLOSE;
832 LOGD("gnss_read_pthread exit.");
833 return NULL;
834}
835
836#if 0
837int gnss_write(int fd, const void *data, int data_len)
838{
839 int count = 0;
840 int len = 0;
841 while(1)
842 {
843 len = write(fd, data + count, data_len - count);
844 if (len > 0)
845 {
846 count += len;
847 }
848 else
849 {
850 LOGE("write() fail,ret = %d,errno = %d", len, errno);
851 break;
852 }
853
854 if (count == data_len)
855 break;
856 }
857
858 return count;
859}
860#else
b.liu778645e2024-06-21 16:47:42 +0800861int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800862{
b.liu778645e2024-06-21 16:47:42 +0800863 ssize_t size;
864 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800865 ssize_t size_written;
866 if(GNSS_BUFF_SIZE < buf_len)
867 {
868 return -1;
869 }
870 for(size = 0; size < buf_len;)
871 {
872 size_to_wr = buf_len - size;
873 if( size_to_wr > GNSS_BUFF_SIZE)
874 size_to_wr = GNSS_BUFF_SIZE;
875
b.liu778645e2024-06-21 16:47:42 +0800876 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800877 if (size_written==-1)
878 {
879 return -1;
880 }
881 size += size_written;
882 if(size_written != size_to_wr)
883 {
884 return size;
885 }
886 }
887 // LOGD("SEND %d / %d", size, buf_len);
888 return size;
889}
890#endif
891
892int gnss_init(uint32 print_port)
893{
894 if(gnss_info.state != GNSS_STATE_CLOSE) {
895 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800896 if(gnss_info.state == GNSS_STATE_READY) {
897 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
898 if(gnss_info.print_port != print_port) {
899 return gnss_ports_open(print_port);
900 } else {
901 return GNSS_ERR_OK;
902 }
903 } else {
904 return GNSS_ERR_OK;
905 }
b.liu8f231a12024-05-31 17:55:06 +0800906 }
907
908 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800909 if(gnss_info.dl_befor_open) {
910 //if(gnss_info.auto_dl_fw) {
911 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800912 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800913 if(ret) {
914 LOGE("gnss_fw_dl() fail : %d", ret);
915 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800916 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800917 }
b.liu8f231a12024-05-31 17:55:06 +0800918
b.liu99c645d2024-06-20 10:52:15 +0800919 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
920 if(gnss_info.fd <= 0) {
921 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
922 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800923 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800924 }
925 if(pipe(gnss_info.exit_fd)) {
926 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800927 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800928 }
929 // GNSS is opened.
930 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800931
b.liu99c645d2024-06-20 10:52:15 +0800932#if 0
933 // Start gnss read thread.
934 pthread_attr_t thread_attr;
935 pthread_attr_init(&thread_attr);
936 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
937 {
938 LOGE("pthread_attr_setdetachstate() fail.");
939 goto main_exit;
940 }
b.liu8f231a12024-05-31 17:55:06 +0800941
b.liu99c645d2024-06-20 10:52:15 +0800942 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800943#else
b.liu99c645d2024-06-20 10:52:15 +0800944 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800945#endif
b.liu99c645d2024-06-20 10:52:15 +0800946 {
947 LOGE("pthread_create() fail.");
948 goto exit_with_close;
949 }
b.liu8f231a12024-05-31 17:55:06 +0800950
b.liu99c645d2024-06-20 10:52:15 +0800951 ret = gnss_info.gnss_dev_open();
952 if(ret) {
953 LOGE("gnss_dev_open() fail : %d", ret);
954 goto exit_with_thread_exit;
955 }
956 //}
957 } else {
958 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
959 if(gnss_info.fd <= 0) {
960 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
961 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800962 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800963 }
964 if(pipe(gnss_info.exit_fd)) {
965 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800966 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800967 }
968 // GNSS is opened.
969 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800970
b.liu99c645d2024-06-20 10:52:15 +0800971#if 0
972 // Start gnss read thread.
973 pthread_attr_t thread_attr;
974 pthread_attr_init(&thread_attr);
975 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
976 {
977 LOGE("pthread_attr_setdetachstate() fail.");
978 goto main_exit;
979 }
980
981 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
982#else
983 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
984#endif
985 {
986 LOGE("pthread_create() fail.");
987 goto exit_with_close;
988 }
989
990 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800991 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800992 LOGE("gnss_dev_open() fail : %d", ret);
993 goto exit_with_thread_exit;
994 }
b.liu8f231a12024-05-31 17:55:06 +0800995 }
996
997 // GNSS is ready, NMEA can print from uart.
998 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +0800999
1000 LOGD("GNSS open success.");
1001
b.liuced8dd02024-06-28 13:28:29 +08001002 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +08001003
b.liu8f231a12024-05-31 17:55:06 +08001004exit_with_thread_exit:
1005 gnss_info.state = GNSS_STATE_CLOSING;
1006 // Wait for read thread exit.
1007 ret = pthread_join(gnss_info.read_pid, NULL);
1008 if(ret){
1009 LOGE("pthrad_join fail(%d)",ret);
1010 }
1011exit_with_close:
1012 if(gnss_info.gnss_close(gnss_info.fd)) {
1013 LOGE("gnss_close() fail.");
1014 }
1015 if(gnss_info.exit_fd[0] > 0) {
1016 close(gnss_info.exit_fd[0]);
1017 gnss_info.exit_fd[0] = -1;
1018 }
1019 if(gnss_info.exit_fd[1] > 0) {
1020 close(gnss_info.exit_fd[1]);
1021 gnss_info.exit_fd[1] = -1;
1022 }
1023 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +08001024 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001025}
1026
1027int gnss_deinit()
1028{
1029 if(gnss_info.state == GNSS_STATE_CLOSE) {
1030 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +08001031 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +08001032 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
1033 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +08001034 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001035 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
1036 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +08001037 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001038 }
1039
b.liu978f5432024-07-01 18:04:18 +08001040 if(gnss_info.gnss_dev_close(gnss_info.fd)) {
1041 LOGE("gnss_dev_close() fail.");
1042 return GNSS_ERR_UNKNOWN;
1043 }
1044
b.liu8f231a12024-05-31 17:55:06 +08001045 // Wait for read thread exit.
1046 if(gnss_info.exit_fd[1] > 0) {
1047 write(gnss_info.exit_fd[1], "exit", 4);
1048 }
1049
1050 gnss_info.state = GNSS_STATE_CLOSING;
1051 int ret = pthread_join(gnss_info.read_pid, NULL);
1052 if(ret){
1053 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +08001054 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001055 }
1056
1057 if(gnss_info.gnss_close(gnss_info.fd)) {
1058 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +08001059 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001060 }
1061
b.liu8f231a12024-05-31 17:55:06 +08001062 if(gnss_ports_close()) {
1063 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +08001064 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001065 }
1066
b.liud0ba7152024-06-19 14:47:21 +08001067 LOGD("gnss_ports_close() complete.");
1068
b.liu8f231a12024-05-31 17:55:06 +08001069 gnss_info.fd = -1;
1070 if(gnss_info.exit_fd[0] > 0) {
1071 close(gnss_info.exit_fd[0]);
1072 gnss_info.exit_fd[0] = -1;
1073 }
1074 if(gnss_info.exit_fd[1] > 0) {
1075 close(gnss_info.exit_fd[1]);
1076 gnss_info.exit_fd[1] = -1;
1077 }
1078 gnss_info.state = GNSS_STATE_CLOSE;
1079 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +08001080 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +08001081}
1082
1083int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
1084{
b.liud0ba7152024-06-19 14:47:21 +08001085 if(buf && buf_len > 0) {
1086 if(cmd_rsp && cmd_rsp_len > 0) {
1087 memset(cmd_rsp, 0, cmd_rsp_len);
1088 }
b.liu8f231a12024-05-31 17:55:06 +08001089 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
1090 } else {
b.liudbc3f4b2024-06-25 18:22:24 +08001091 return GNSS_ERR_UNKNOWN;
1092 }
1093}
1094
1095int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
1096{
b.liu42f558e2024-07-18 14:06:49 +08001097 // Only 8122 support download fw.
b.liudbc3f4b2024-06-25 18:22:24 +08001098 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
1099 return GNSS_ERR_UNSUPPORT;
1100 }
1101
1102 if(rsp && rsp_len > 0) {
1103 memset(rsp, 0, rsp_len);
1104 }
1105
1106 if(gnss_info.gnss_fw_dl) {
1107 if(GNSS_ERR_OK != gnss_deinit()) {
1108 LOGE("Close gnss fail.");
1109 return GNSS_ERR_UNKNOWN;
1110 } else {
1111 LOGD("Start gnss fw dl.");
1112 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
1113 }
1114 } else {
b.liu42f558e2024-07-18 14:06:49 +08001115 return GNSS_ERR_UNSUPPORT;
b.liu8f231a12024-05-31 17:55:06 +08001116 }
1117}
1118
b.liue77ac3a2024-07-17 17:36:57 +08001119int gnss_ind_set(int fd, int ind_type)
1120{
1121 int index = 0;
1122 if(ind_type) { // Add IND flag.
1123 while(index < GNSS_CLI_IND_MAX) {
1124 if(ind_info[index].cli_fd == fd)
1125 break;
1126 index++;
1127 }
1128
1129 if(index == GNSS_CLI_IND_MAX) { // Add flag
1130 index = 0;
1131 while(index < GNSS_CLI_IND_MAX) {
1132 if(ind_info[index].cli_fd <= 0)
1133 break;
1134 index++;
1135 }
yq.wang1ddd1fd2024-07-25 23:00:14 -07001136 if(index == GNSS_CLI_IND_MAX)
1137 {
1138 LOGE("ind flag is full.");
1139 return GNSS_ERR_CLI_FULL;
1140 }
b.liue77ac3a2024-07-17 17:36:57 +08001141 ind_info[index].cli_fd = fd;
1142 ind_info[index].ind_flag = (uint32)ind_type;
b.liubcf86c92024-08-19 19:48:28 +08001143 } else { // Change flag
b.liue77ac3a2024-07-17 17:36:57 +08001144 ind_info[index].cli_fd = fd;
1145 ind_info[index].ind_flag = (uint32)ind_type;
1146 }
1147 } else { // Clear IND flag.
1148 while(index < GNSS_CLI_IND_MAX) {
1149 if(ind_info[index].cli_fd == fd)
1150 break;
1151 index++;
1152 }
1153
1154 if(index == GNSS_CLI_IND_MAX) {
1155 return GNSS_ERR_ARG;
b.liubcf86c92024-08-19 19:48:28 +08001156 }
b.liue77ac3a2024-07-17 17:36:57 +08001157 ind_info[index].cli_fd = 0;
1158 ind_info[index].ind_flag = 0;
1159 }
1160
1161 return GNSS_ERR_OK;
1162}
1163
b.liu8f231a12024-05-31 17:55:06 +08001164static void sig_process(int sig)
1165{
1166 LOGI("I got signal %d\n", sig);
1167 if(gnss_deinit()) {
1168 LOGE("gnss_deinit() fail, no exist...");
1169 return;
1170 }
1171
1172 switch(sig)
1173 {
1174 case SIGINT: // Ctrl + C
1175 {
1176 LOGI("Exit by SIGINT.\n");
1177 exit(0);
1178 }
luojiand7960682024-08-02 16:50:01 +08001179 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 +08001180 {
1181 LOGI("Exit by SIGQUIT.\n");
1182 exit(0);
1183 }
luojiand7960682024-08-02 16:50:01 +08001184 case SIGTERM:// Ĭ\C8\CFkill (ͬ SIGKILL \A3\AC\B5\AB SIGKILL \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001185 {
1186 LOGI("Exit by SIGTERM.\n");
1187 exit(0);
1188 }
luojiand7960682024-08-02 16:50:01 +08001189 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP \A3\AC\B5\AB SIGSTOP \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001190 {
1191 LOGI("Exit by SIGTSTP.\n");
1192 exit(0);
1193 }
luojiand7960682024-08-02 16:50:01 +08001194 case SIGSEGV: // \C8\E7\BF\D5Ö¸\D5\EB
b.liu8f231a12024-05-31 17:55:06 +08001195 {
1196 LOGI("Exit by SIGSEGV.\n");
1197 exit(0);
1198 }
1199 default:
1200 {
1201 LOGI("Unknown sig:%d\n",sig);
1202 break;
1203 }
1204 }
1205}
1206
1207
b.liuced8dd02024-06-28 13:28:29 +08001208// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +08001209int main(int argc, char *argv[])
1210{
1211 mbtk_log_init("radio", GNSS_TAG);
1212
b.liubcf86c92024-08-19 19:48:28 +08001213 MBTK_SOURCE_INFO_PRINT("mbtk_gnssd");
1214
b.liubb590492024-06-13 16:42:08 +08001215#ifdef MBTK_DUMP_SUPPORT
1216 mbtk_debug_open(NULL, TRUE);
1217#endif
1218
b.liu8f231a12024-05-31 17:55:06 +08001219 signal(SIGINT, sig_process);
1220 signal(SIGQUIT, sig_process);
1221 signal(SIGTERM, sig_process);
1222
1223 if(arg_check(argc, argv)) {
1224 return -1;
1225 }
1226
1227#ifdef GNSS_DEBUG
1228 char buff[10];
1229 memset(buff, 0, 10);
1230 property_get(MBTK_PROP_GNSS_LOG, buff, "");
1231 if(strlen(buff) > 0 && atoi(buff) > 0) {
1232 nmea_log_enable = TRUE;
1233 }
1234#endif
1235
1236 memset(&gnss_info, 0, sizeof(gnss_info_t));
1237 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
1238 gnss_info.state = GNSS_STATE_CLOSE;
1239 if(!strcmp(argv[1], GNSS_ID_6228)) {
1240 gnss_info.gnss_id = GNSS_TYPE_6228;
1241 gnss_info.auto_open = (bool)atoi(argv[3]);
1242 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +08001243 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +08001244 gnss_info.gnss_dev_open = gnss_6228_dev_open;
1245 gnss_info.gnss_dev_close = gnss_6228_dev_close;
1246 gnss_info.gnss_open = gnss_6228_open;
1247 gnss_info.gnss_close = gnss_6228_close;
1248 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
1249 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
1250 gnss_info.gnss_set = gnss_6228_set;
1251 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +08001252 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
1253 gnss_info.gnss_id = GNSS_TYPE_8122;
1254 gnss_info.auto_open = (bool)atoi(argv[3]);
1255 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +08001256 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +08001257 gnss_info.gnss_dev_open = gnss_8122_dev_open;
1258 gnss_info.gnss_dev_close = gnss_8122_dev_close;
1259 gnss_info.gnss_open = gnss_8122_open;
1260 gnss_info.gnss_close = gnss_8122_close;
1261 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
1262 gnss_info.gnss_dl_read_cb = NULL;
1263 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +08001264 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +08001265 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
1266 gnss_info.gnss_id = GNSS_TYPE_5311;
1267 gnss_info.auto_open = (bool)atoi(argv[3]);
1268 gnss_info.auto_dl_fw = TRUE;
1269 gnss_info.dl_befor_open = TRUE;
1270 gnss_info.gnss_dev_open = gnss_5311_dev_open;
1271 gnss_info.gnss_dev_close = gnss_5311_dev_close;
1272 gnss_info.gnss_open = gnss_5311_open;
1273 gnss_info.gnss_close = gnss_5311_close;
1274 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
1275 gnss_info.gnss_dl_read_cb = NULL;
1276 gnss_info.gnss_set = gnss_5311_set;
1277 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu42f558e2024-07-18 14:06:49 +08001278 } else if(!strcmp(argv[1], GNSS_ID_N50DB)) {
1279 gnss_info.gnss_id = GNSS_TYPE_N50DB;
1280 gnss_info.auto_open = (bool)atoi(argv[3]);
1281 gnss_info.auto_dl_fw = FALSE;
1282 gnss_info.dl_befor_open = FALSE;
1283 gnss_info.gnss_dev_open = gnss_n50db_dev_open;
1284 gnss_info.gnss_dev_close = gnss_n50db_dev_close;
1285 gnss_info.gnss_open = gnss_n50db_open;
1286 gnss_info.gnss_close = gnss_n50db_close;
1287 gnss_info.gnss_fw_dl = gnss_n50db_fw_dl;
1288 gnss_info.gnss_dl_read_cb = NULL;
1289 gnss_info.gnss_set = gnss_n50db_set;
1290 gnss_info.gnss_set_cb = gnss_n50db_set_cb;
b.liu8f231a12024-05-31 17:55:06 +08001291 } else {
1292 LOGE("No support : %s", argv[1]);
1293 return -1;
1294 }
1295
1296 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
1297 // Auto open gnss.
1298 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +08001299 int init_mode = atoi(argv[3]);
1300 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
1301 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +08001302 }
b.liuced8dd02024-06-28 13:28:29 +08001303 if(gnss_init((uint32)init_mode)) {
1304 LOGE("gnss_init() fail.");
1305 // return -1;
1306 }
1307 } else {
1308 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +08001309 }
1310
1311 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +08001312#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +08001313 if(gnss_ubus_init()) {
1314 LOGD("main() run...");
1315 uloop_run();
1316 } else {
1317 LOGE("gnss_ubus_init() fail.");
1318 }
b.liu5f950c52024-06-15 20:13:12 +08001319#else
1320 if(!gnss_ipc_service_start()) {
1321 LOGD("main() run...");
1322 while(1) {
1323 sleep(24 * 60 * 60);
1324 }
1325 } else {
1326 LOGE("gnss_ipc_service_start() fail.");
1327 }
1328#endif
b.liu8f231a12024-05-31 17:55:06 +08001329
1330 LOGD("main() exit.");
1331 return 0;
1332}