blob: 76971c3ff9ae94f0c5282b086df5c2bc1c539aa5 [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
yq.wang1ddd1fd2024-07-25 23:00:14 -070041gnss_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
64static int gnss_pty_master_fd = -1;
65static int gnss_pty_slave_fd = -1;
66static int gnss_usb_at_port_fd = -1;
67static int gnss_usb_nmea_port_fd = -1;
68static int gnss_uart_at_port_fd = -1;
69static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
70
b.liue77ac3a2024-07-17 17:36:57 +080071int gnss_write(int fd, const void* buf, int buf_len);
72
b.liu8f231a12024-05-31 17:55:06 +080073static void help()
74{
b.liu42f558e2024-07-18 14:06:49 +080075 LOGD("mbtk_gnssd <6228/8122/5311/N50DB> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080076}
77
78static int arg_check(int argc, char *argv[])
79{
80 if(argc != 4) {
b.liu4ae41182024-06-28 16:30:15 +080081 LOGE("argc = %d", argc);
b.liu8f231a12024-05-31 17:55:06 +080082 goto check_fail;
83 }
84
b.liu99c645d2024-06-20 10:52:15 +080085 // Only support 6228/8122/5311.
b.liu42f558e2024-07-18 14:06:49 +080086 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)
87 && strcmp(argv[1], GNSS_ID_N50DB)) {
b.liu4ae41182024-06-28 16:30:15 +080088 LOGE("argv[1] = %s", argv[1]);
b.liu8f231a12024-05-31 17:55:06 +080089 goto check_fail;
90 }
91
92 if(access(argv[2], R_OK | W_OK)) {
b.liu4ae41182024-06-28 16:30:15 +080093 LOGE("access(%s) rw fail. ", argv[2]);
b.liu8f231a12024-05-31 17:55:06 +080094 goto check_fail;
95 }
96
b.liuced8dd02024-06-28 13:28:29 +080097#if 0
98 int init_mode = atoi(argv[3]);
99 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 +0800100 goto check_fail;
101 }
b.liuced8dd02024-06-28 13:28:29 +0800102#endif
b.liu8f231a12024-05-31 17:55:06 +0800103
104 return 0;
105check_fail:
106 help();
107 return -1;
108}
109
110static int gnss_ports_open(uint32 print_port)
111{
b.liuced8dd02024-06-28 13:28:29 +0800112 // TTY AT change.
113 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
114 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
115 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
116 return GNSS_ERR_OPEN_DEV;
117 }
118 LOGD("Open PTY port success.");
119 } else { // Close
120 if(gnss_pty_slave_fd > 0) {
121 close(gnss_pty_slave_fd);
122 gnss_pty_slave_fd = -1;
123 unlink(GNSS_PORT_PTY);
124 }
125 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800126 }
b.liu8f231a12024-05-31 17:55:06 +0800127 }
128
b.liuced8dd02024-06-28 13:28:29 +0800129 // USB AT change.
130 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
131 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
b.liu978f5432024-07-01 18:04:18 +0800132 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 +0800133 return GNSS_ERR_OPEN_DEV;
134 }
135 LOGD("Open USB AT port success.");
136 } else { // Close
137 if(gnss_usb_at_port_fd > 0) {
138 close(gnss_usb_at_port_fd);
139 gnss_usb_at_port_fd = -1;
140 }
141 LOGD("Close USB AT 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 NMEA change.
146 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
147 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
b.liu978f5432024-07-01 18:04:18 +0800148 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 +0800149 return GNSS_ERR_OPEN_DEV;
150 }
151 LOGD("Open USB NMEA port success.");
152 } else { // Close
153 if(gnss_usb_nmea_port_fd > 0) {
154 close(gnss_usb_nmea_port_fd);
155 gnss_usb_nmea_port_fd = -1;
156 }
157 LOGD("Close USB NMEA 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 // Uart AT change.
162 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
163 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
164 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
165 return GNSS_ERR_OPEN_DEV;
166 }
167 LOGD("Open UART AT port success.");
168 } else { // Close
169 if(gnss_uart_at_port_fd > 0) {
170 close(gnss_uart_at_port_fd);
171 gnss_uart_at_port_fd = -1;
172 }
173 LOGD("Close UART AT 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 gnss_info.print_port = print_port;
178
b.liudbc3f4b2024-06-25 18:22:24 +0800179 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800180}
181
182static int gnss_ports_close()
183{
184 if(gnss_usb_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800185 tcflush(gnss_usb_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800186 close(gnss_usb_at_port_fd);
187 gnss_usb_at_port_fd = -1;
188 }
189
190 if(gnss_usb_nmea_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800191 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800192 close(gnss_usb_nmea_port_fd);
193 gnss_usb_nmea_port_fd = -1;
194 }
195
196 if(gnss_uart_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800197 tcflush(gnss_uart_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800198 close(gnss_uart_at_port_fd);
199 gnss_uart_at_port_fd = -1;
200 }
201
202 if(gnss_pty_master_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800203 tcflush(gnss_pty_master_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800204 close(gnss_pty_master_fd);
205 gnss_pty_master_fd = -1;
206 }
207
208 if(gnss_pty_slave_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800209 tcflush(gnss_pty_slave_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800210 close(gnss_pty_slave_fd);
211 gnss_pty_slave_fd = -1;
212 unlink(GNSS_PORT_PTY);
213 }
214
b.liuced8dd02024-06-28 13:28:29 +0800215 gnss_info.print_port = 0;
216
b.liu8f231a12024-05-31 17:55:06 +0800217 return 0;
218}
219
b.liu8f231a12024-05-31 17:55:06 +0800220#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800221static void log_save(int fd, const char *data, int data_len)
222{
b.liu8f231a12024-05-31 17:55:06 +0800223 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800224 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
225 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
226 close(debug_fd);
227 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
228 if(debug_fd < 0) {
229 LOGE("Open debug fd fail.");
230 }
231 debug_fd_len = 0;
232
233 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800234 close(nmea_log_fd);
235 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
236 if(nmea_log_fd < 0) {
237 LOGE("Open debug fd fail.");
238 }
b.liu8f231a12024-05-31 17:55:06 +0800239 }
240
b.liu99c645d2024-06-20 10:52:15 +0800241 if(fd == nmea_log_fd) {
242 if(nmea_log_fd > 0) {
243 write(nmea_log_fd, data, data_len);
244 debug_fd_len += data_len;
245 }
246 } else if(fd == debug_fd) {
247 if(debug_fd > 0) {
248 write(debug_fd, data, data_len);
249 debug_fd_len += data_len;
250 }
b.liu8f231a12024-05-31 17:55:06 +0800251 }
252 }
b.liu99c645d2024-06-20 10:52:15 +0800253}
b.liu8f231a12024-05-31 17:55:06 +0800254#endif
255
b.liue77ac3a2024-07-17 17:36:57 +0800256static void ind_location_print(const char *data)
257{
258 int index = 0;
259 int buff_len = 0;
260 char buff[GNSS_BUFF_SIZE] = {0};
261 buff[0] = MBTK_IND_START_FLAG;
262 buff_len++;
263 memcpy(buff + 1, MBTK_IND_LOCATION_TAG, strlen(MBTK_IND_LOCATION_TAG));
264 buff_len += strlen(MBTK_IND_LOCATION_TAG);
265 memcpy(buff + strlen(buff), data, strlen(data));
266 buff_len += strlen(data);
267 buff[strlen(buff)] = MBTK_IND_END_FLAG;
268 buff_len++;
269
270 while(index < GNSS_CLI_IND_MAX) {
271 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_LOCATION)) {
272 gnss_write(ind_info[index].cli_fd, buff, buff_len);
273 }
274 index++;
275 }
276}
277
278static void ind_nmea_print(const char *data)
279{
280 int index = 0;
281 int buff_len = 0;
282 char buff[GNSS_BUFF_SIZE] = {0};
283 buff[0] = MBTK_IND_START_FLAG;
284 buff_len++;
285 memcpy(buff + 1, MBTK_IND_NMEA_TAG, strlen(MBTK_IND_NMEA_TAG));
286 buff_len += strlen(MBTK_IND_NMEA_TAG);
287 memcpy(buff + strlen(buff), data, strlen(data));
288 buff_len += strlen(data);
289 buff[strlen(buff)] = MBTK_IND_END_FLAG;
290 buff_len++;
291 while(index < GNSS_CLI_IND_MAX) {
292 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_NMEA)) {
293 gnss_write(ind_info[index].cli_fd, buff, buff_len);
294 }
295 index++;
296 }
297}
298
b.liu99c645d2024-06-20 10:52:15 +0800299static void nmea_print(const char *nmea, int nmea_len)
300{
yq.wang1ddd1fd2024-07-25 23:00:14 -0700301 int ret = -1;
b.liu8f231a12024-05-31 17:55:06 +0800302 if(gnss_usb_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700303 ret = write(gnss_usb_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800304 }
305
306 if(gnss_usb_nmea_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700307 ret = write(gnss_usb_nmea_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800308 }
309
310 if(gnss_uart_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700311 ret = write(gnss_uart_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800312 }
313
314 if(gnss_pty_master_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700315 ret = write(gnss_pty_master_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800316 }
yq.wang937355d2024-07-26 01:24:42 -0700317 ind_nmea_print(nmea);
318 ind_location_print(nmea);
b.liu8f231a12024-05-31 17:55:06 +0800319}
320
321static unsigned char nmea_checksum(const char *nmea)
322{
323 const char *p = nmea;
324 unsigned char chs = 0;
325
326 while (*p == '$') // skip '$'
327 p++;
328 while (*p != '*' && *p != 0)
329 chs ^= *p++;
330
331 return chs;
332}
333
334static bool nmea_check(const char *nmea, int nmea_len)
335{
336 char **ptr = gnss_filter_info;
337 while(*ptr) {
338 if(strstr(nmea, *ptr)) {
339 break;
340 }
341 ptr++;
342 }
343
344 if(*ptr == NULL) {
345 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
346 return FALSE;
347 }
348
349 char *checksum_str = strstr(nmea, "*");
350 checksum_str++; // Jump '*'
351 char checksum_buf[3] = {0};
352 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
353 if(strncasecmp(checksum_buf, checksum_str, 2)) {
354 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
355 return FALSE;
356 }
357
358 return TRUE;
359}
360
luojiand7960682024-08-02 16:50:01 +0800361static int nmea_tokenizer_init(mbtk_nmeatokenizer* t, const char* head, const char* end, int param_num)
362{
363 int count = 0;
364 const char* p = head;
365 const char* q = end;
366 const char* tmp = NULL;
367 // the initial '$' is optional
368 if (p < q && p[0] == '$')
369 {
370 p += 1;
371 }
372 else
373 {
374 return -1;
375 }
376
377 //find '*',del '*25\r\n'
378 // get rid of checksum at the end of the sentecne
379 if (q >= p + 5 && q[-5] == '*')
380 {
381 q -= 5;
382 }
383 else
384 {
385 return -1;
386 }
387
388 while (p <= q)
389 {
390 tmp = memchr(p, ',', q-p);
391 if (tmp == NULL)
392 {
393 tmp = q;
394 }
395 // if (q > p) {
396 // q >= p include empty token: ,,
397 if (tmp >= p)
398 {
399 if (count < MAX_NMEA_TOKENS)
400 {
401 t->tokens[count].head = p;
402 t->tokens[count].end = tmp;
403 count += 1;
404 }
405 }
406
407 if (tmp <= q)
408 {
409 tmp += 1;
410 }
411
412 p = tmp;
413 }
414
415 if(count != param_num)
416 {
417 LOGD("count [%d], param_num [%d]", count, param_num);
418 return -1;
419 }
420
421 t->count = count;
422 return count;
423}
424
425static mbtk_token nmea_tokenizer_get(mbtk_nmeatokenizer* t, int index)
426{
427 mbtk_token tok;
428 static const char* dummy = "";
429
430 if (index < 0 || index >= t->count)
431 {
432 tok.head = tok.end = dummy;
433 }
434 else
435 {
436 tok = t->tokens[index];
437 }
438 return tok;
439}
440
441typedef enum {
442 LYNQ_TIME_TYPE_CELL = 0, //NITZ
443 LYNQ_TIME_TYPE_NTP,
444 LYNQ_TIME_TYPE_GNSS,
445 LYNQ_TIME_TYPE_USER,
446
447 LYNQ_TIME_TYPE_UNUSE
448} lynq_time_type_enum;
449
450bool mbtk_gnss_time_set_flag = 0;
451
452static int mbtk_time_type_gnss_read() {
453 int type = 0;
454 char time_type[] ={0};
455 property_get("persist.mbtk.time_type", time_type, "0");
456
457 type = atoi(time_type);
458// LOGD("time_type :%d\n", type);
459 if(type != LYNQ_TIME_TYPE_GNSS)
460 mbtk_gnss_time_set_flag = 0;
461
462 return type;
463}
464
465static int strstr_n(const char *s1, const char *s2)
466{
467 int n;
468 int strlen = 0;
469
470 if(*s2)
471 {
472 while(*s1)
473 {
474 for(n = 0; *(s1+n) == *(s2 + n); n++)
475 {
476 if(!*(s2 + n + 1))
477 {
478 strlen++;
479 return strlen;
480 }
481 }
482 s1++;
483 strlen++;
484 }
485 return 0;
486 }
487
488 return 0;
489}
490static int nmea_update_date_time(mbtk_token date, mbtk_token time)
491{
492 char tmp_char[4] = {0};
493 struct tm tmp_time;
494 struct timeval tv;
495
496 memset(&tmp_time, 0x0, sizeof(struct tm));
497 if (date.head + 6 > date.end)
498 {
499 LOGD("date get fail");
500 return -1;
501 }
502
503 memcpy(tmp_char, date.head, 2);
504 tmp_time.tm_mday = atoi(tmp_char);
505 memcpy(tmp_char, date.head + 2, 2);
506 tmp_time.tm_mon = atoi(tmp_char) - 1;
507 memcpy(tmp_char, date.head + 4, 2);
508 tmp_time.tm_year = 100 + atoi(tmp_char);
509
510 if (time.head + 6 > time.end)
511 {
512 LOGD("time get fail");
513 return -1;
514 }
515
516 memcpy(tmp_char, time.head, 2);
517 tmp_time.tm_hour = atoi(tmp_char);
518 memcpy(tmp_char, time.head + 2, 2);
519 tmp_time.tm_min = atoi(tmp_char);
520 memcpy(tmp_char, time.head + 4, 2);
521 tmp_time.tm_sec = atoi(tmp_char);
522 tmp_time.tm_isdst = -1;
523
524
525 LOGD("data:%d-%d-%d %d:%d:%d", tmp_time.tm_year + 1900,
526 tmp_time.tm_mon,
527 tmp_time.tm_mday,
528 tmp_time.tm_hour,
529 tmp_time.tm_min,
530 tmp_time.tm_sec);
531
532
533 time_t _t = mktime(&tmp_time);//parse location tmp_time
534
535 tzset(); // auto set tz
536 _t = _t - timezone;
537
538 LOGD("timestamp:%ld, %ld", _t, timezone);
539
540 tv.tv_sec = _t;
541 if(settimeofday(&tv, NULL)) {
542 LOGD("%s: , Set time fail\n", __func__);
543 mbtk_gnss_time_set_flag = 0;
544 } else {
545 LOGD("%s: , Set time success \n", __func__);
luojian51d65f92024-08-08 15:39:42 +0800546 system("hwclock -w rtc0");
547 mbtk_gnss_time_set_flag = 1;
luojiand7960682024-08-02 16:50:01 +0800548 }
549
550 return 0;
551}
552
553static int ind_nmea_parse(const char *data, int data_len)
554{
555 int ret;
556 mbtk_nmeatokenizer tzer = {0};
557 if(strstr_n(data + 3, "RMC"))
558 {
559 ret = nmea_tokenizer_init(&tzer, data, data + data_len, NMEA_RMC_PARAM_NUM);
560 if(ret < 0)
561 {
562 LOGD("nmea_tokenizer_init fail");
563 return -1;
564 }
565
566 mbtk_token tok_time = nmea_tokenizer_get(&tzer,1);
567 mbtk_token tok_fixStatus = nmea_tokenizer_get(&tzer,2);
568 mbtk_token tok_date = nmea_tokenizer_get(&tzer,9);
569
570 if(tok_fixStatus.head[0] == 'A')
571 {
572 ret = nmea_update_date_time(tok_date, tok_time);
573 if(ret < 0)
574 {
575 LOGD("nmea_update_date_time fail");
576 return -1;
577 }
578
579 }
580 }
581
582 return 0;
583}
584
585
b.liu8f231a12024-05-31 17:55:06 +0800586static void gnss_nmea_process(const char *data, int data_len)
587{
luojiand7960682024-08-02 16:50:01 +0800588// LOGD("gnss_nmea_process() : data_len - %d", data_len);
b.liu99c645d2024-06-20 10:52:15 +0800589#if 0
b.liu8f231a12024-05-31 17:55:06 +0800590 char nmea[GNSS_BUFF_SIZE] = {0};
591 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800592#else
593 const char *nmea = data;
594#endif
b.liu8f231a12024-05-31 17:55:06 +0800595
596 if(!nmea_check(nmea, data_len)) {
b.liu42f558e2024-07-18 14:06:49 +0800597 // No print "$HOSTSLEEP".
598 if(memcmp(nmea, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
599 LOGD("NO-NMEA:%s", nmea);
600 }
b.liu99c645d2024-06-20 10:52:15 +0800601#if GNSS_DEBUG
602 log_save(nmea_log_fd, "/**/", 4);
603 log_save(nmea_log_fd, nmea, data_len);
604#endif
605 if(gnss_info.gnss_set_cb)
606 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800607 return;
608 }
609
610#ifdef GNSS_DEBUG
611 if(nmea_log_enable) {
612 LOGD("NMEA[%d]:%s", data_len, nmea);
613 }
b.liu99c645d2024-06-20 10:52:15 +0800614
615 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800616#endif
617
luojiand7960682024-08-02 16:50:01 +0800618 if( (mbtk_time_type_gnss_read() == LYNQ_TIME_TYPE_GNSS) && !mbtk_gnss_time_set_flag)
619 ind_nmea_parse(nmea, data_len);
620
b.liu8f231a12024-05-31 17:55:06 +0800621 nmea_print(nmea, data_len);
622}
623
624#if 0
625static void gnss_cmd_rsp_process(const char *data, int data_len)
626{
627 char rsp[GNSS_BUFF_SIZE] = {0};
628 memcpy(rsp, data, data_len);
629 LOGD("RSP[%d]:%s", data_len, rsp);
630}
631#endif
632
633static bool nmea_char_check(char ch)
634{
635 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
yq.wang1ddd1fd2024-07-25 23:00:14 -0700636 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=' || ch == '-')
b.liu8f231a12024-05-31 17:55:06 +0800637 return TRUE;
638
639 return FALSE;
640}
641
642static void gnss_data_process(const char *data, int data_len)
643{
644 if(gnss_info.state == GNSS_STATE_OPEN) {
645 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
646 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
647 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800648 if(gnss_info.gnss_dl_read_cb) {
649 gnss_info.gnss_dl_read_cb(data, data_len);
650 }
b.liu8f231a12024-05-31 17:55:06 +0800651 } else if(gnss_info.state == GNSS_STATE_READY) {
652 int index = 0;
653 while(index < data_len) {
654 if(nmea_found) {
655 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800656 // Copy nmea_buff to data_buff
657 // Start with '$', but not nmea data, so copy to data_buff.
658 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
659 data_buff_len += nmea_buff_len;
660 data_buff[data_buff_len++] = data[index];
661
662 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800663 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800664 continue;
665 }
666
667 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800668 nmea_buff[nmea_buff_len++] = data[index];
669 if(nmea_buff[nmea_buff_len - 1] == '\n') {
670 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800671#if GNSS_DEBUG
672 log_save(nmea_log_fd, "/**/", 4);
673 log_save(nmea_log_fd, data_buff, data_buff_len);
674#endif
675 if(gnss_info.gnss_set_cb) {
676 gnss_info.gnss_set_cb(data_buff, data_buff_len);
677 }
b.liud0ba7152024-06-19 14:47:21 +0800678 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800679 }
680
b.liud0ba7152024-06-19 14:47:21 +0800681 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800682 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800683 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800684 } else if(nmea_buff_len > 0) {
685 nmea_buff[nmea_buff_len] = '\0';
b.liu42f558e2024-07-18 14:06:49 +0800686 if(memcmp(nmea_buff, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
687 LOGD("NO-NMEA:%s", nmea_buff);
688 }
b.liu99c645d2024-06-20 10:52:15 +0800689#if GNSS_DEBUG
690 log_save(nmea_log_fd, "/**/", 4);
691 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
692#endif
b.liud0ba7152024-06-19 14:47:21 +0800693 }
694
695 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800696 nmea_found = FALSE;
697 }
698 }
699 } else {
700 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800701 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800702 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800703 nmea_buff[nmea_buff_len++] = data[index];
704 } else {
705 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800706 }
707 }
708 index++;
709 }
710 } else {
711 LOGW("Unknown state : %d", gnss_info.state);
712 }
713}
714
715void* gnss_read_pthread(void* arg)
716{
717 LOGD("gnss_read_pthread enter.");
718 char buffer[GNSS_BUFF_SIZE];
719 int len = 0;
720 int ret = 0;
721 fd_set fdr, fdw;
722 int fd_max = 0;
723
b.liu8f231a12024-05-31 17:55:06 +0800724 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800725 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800726 memset(nmea_buff, 0, sizeof(nmea_buff));
727 memset(data_buff, 0, sizeof(data_buff));
728 nmea_buff_len = 0;
729 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800730#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800731 if(nmea_log_enable) {
732 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
733 if(debug_fd < 0) {
734 LOGE("Open debug fd fail.");
735 }
736 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
737 if(nmea_log_fd < 0) {
738 LOGE("Open nmea fd fail.");
739 }
b.liu99c645d2024-06-20 10:52:15 +0800740 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800741 }
742#endif
743
b.liudbc3f4b2024-06-25 18:22:24 +0800744 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
745
b.liu8f231a12024-05-31 17:55:06 +0800746 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800747 FD_ZERO(&fdw);
748 FD_ZERO(&fdr);
749 FD_SET(gnss_info.fd, &fdr);
750 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800751 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
752 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800753 if(gnss_info.state < GNSS_STATE_OPEN) {
754 LOGD("State = %d, ret = %d", gnss_info.state, ret);
755 if(ret > 0) {
756 if (FD_ISSET(gnss_info.fd, &fdr)) {
757 LOGD("gnss_fd can read.");
758 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
759 LOGD("exit_fd can read.");
760 } else {
761 LOGW("Unknown select event.");
762 }
763 }
764 break;
765 }
766
b.liu8f231a12024-05-31 17:55:06 +0800767 if (ret < 0)
768 {
769 if (errno == EINTR)
770 {
771 continue;
772 }
773 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
774 break;
775 }
776 else if (ret == 0)
777 {
778 LOGE("select ret == 0");
779 break;
780 }
781
782 if (FD_ISSET(gnss_info.fd, &fdr))
783 {
784 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800785 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800786 if(len > 0) {
787 //log_hex("READ", buffer, len);
788
789#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800790 //LOGD("read data_len = %d", len);
791 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800792#endif
793
794 gnss_data_process(buffer, len);
795
796 } else if(len ==0 ){
797 LOGE("Read end : len = 0");
798 break;
799 } else {
800 if(EAGAIN == errno) {
801 usleep(50000);
802 continue;
803 } else {
804 LOGD("Read ret = -1 ,errno = %d", errno);
805 break;
806 }
807 }
808 }
809 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
810 {
b.liuece0db02024-06-25 18:39:09 +0800811 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800812 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800813 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800814 if(len > 0) {
815 if(strcmp(buffer, "exit") == 0) {
816 LOGD("Get thread exit message.");
817 break;
818 }
819 }
820 }
821 else
822 {
823 LOGW("Unknown select event.");
824 continue;
825 }
826 }
827
828#if GNSS_DEBUG
829 if(debug_fd > 0) {
830 close(debug_fd);
831 debug_fd = -1;
832 }
833 if(nmea_log_fd > 0) {
834 close(nmea_log_fd);
835 nmea_log_fd = -1;
836 }
837#endif
838
839 gnss_info.state = GNSS_STATE_CLOSE;
840 LOGD("gnss_read_pthread exit.");
841 return NULL;
842}
843
844#if 0
845int gnss_write(int fd, const void *data, int data_len)
846{
847 int count = 0;
848 int len = 0;
849 while(1)
850 {
851 len = write(fd, data + count, data_len - count);
852 if (len > 0)
853 {
854 count += len;
855 }
856 else
857 {
858 LOGE("write() fail,ret = %d,errno = %d", len, errno);
859 break;
860 }
861
862 if (count == data_len)
863 break;
864 }
865
866 return count;
867}
868#else
b.liu778645e2024-06-21 16:47:42 +0800869int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800870{
b.liu778645e2024-06-21 16:47:42 +0800871 ssize_t size;
872 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800873 ssize_t size_written;
874 if(GNSS_BUFF_SIZE < buf_len)
875 {
876 return -1;
877 }
878 for(size = 0; size < buf_len;)
879 {
880 size_to_wr = buf_len - size;
881 if( size_to_wr > GNSS_BUFF_SIZE)
882 size_to_wr = GNSS_BUFF_SIZE;
883
b.liu778645e2024-06-21 16:47:42 +0800884 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800885 if (size_written==-1)
886 {
887 return -1;
888 }
889 size += size_written;
890 if(size_written != size_to_wr)
891 {
892 return size;
893 }
894 }
895 // LOGD("SEND %d / %d", size, buf_len);
896 return size;
897}
898#endif
899
900int gnss_init(uint32 print_port)
901{
902 if(gnss_info.state != GNSS_STATE_CLOSE) {
903 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800904 if(gnss_info.state == GNSS_STATE_READY) {
905 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
906 if(gnss_info.print_port != print_port) {
907 return gnss_ports_open(print_port);
908 } else {
909 return GNSS_ERR_OK;
910 }
911 } else {
912 return GNSS_ERR_OK;
913 }
b.liu8f231a12024-05-31 17:55:06 +0800914 }
915
916 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800917 if(gnss_info.dl_befor_open) {
918 //if(gnss_info.auto_dl_fw) {
919 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800920 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800921 if(ret) {
922 LOGE("gnss_fw_dl() fail : %d", ret);
923 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800924 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800925 }
b.liu8f231a12024-05-31 17:55:06 +0800926
b.liu99c645d2024-06-20 10:52:15 +0800927 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
928 if(gnss_info.fd <= 0) {
929 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
930 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800931 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800932 }
933 if(pipe(gnss_info.exit_fd)) {
934 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800935 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800936 }
937 // GNSS is opened.
938 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800939
b.liu99c645d2024-06-20 10:52:15 +0800940#if 0
941 // Start gnss read thread.
942 pthread_attr_t thread_attr;
943 pthread_attr_init(&thread_attr);
944 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
945 {
946 LOGE("pthread_attr_setdetachstate() fail.");
947 goto main_exit;
948 }
b.liu8f231a12024-05-31 17:55:06 +0800949
b.liu99c645d2024-06-20 10:52:15 +0800950 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800951#else
b.liu99c645d2024-06-20 10:52:15 +0800952 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800953#endif
b.liu99c645d2024-06-20 10:52:15 +0800954 {
955 LOGE("pthread_create() fail.");
956 goto exit_with_close;
957 }
b.liu8f231a12024-05-31 17:55:06 +0800958
b.liu99c645d2024-06-20 10:52:15 +0800959 ret = gnss_info.gnss_dev_open();
960 if(ret) {
961 LOGE("gnss_dev_open() fail : %d", ret);
962 goto exit_with_thread_exit;
963 }
964 //}
965 } else {
966 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
967 if(gnss_info.fd <= 0) {
968 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
969 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800970 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800971 }
972 if(pipe(gnss_info.exit_fd)) {
973 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800974 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800975 }
976 // GNSS is opened.
977 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800978
b.liu99c645d2024-06-20 10:52:15 +0800979#if 0
980 // Start gnss read thread.
981 pthread_attr_t thread_attr;
982 pthread_attr_init(&thread_attr);
983 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
984 {
985 LOGE("pthread_attr_setdetachstate() fail.");
986 goto main_exit;
987 }
988
989 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
990#else
991 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
992#endif
993 {
994 LOGE("pthread_create() fail.");
995 goto exit_with_close;
996 }
997
998 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800999 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +08001000 LOGE("gnss_dev_open() fail : %d", ret);
1001 goto exit_with_thread_exit;
1002 }
b.liu8f231a12024-05-31 17:55:06 +08001003 }
1004
1005 // GNSS is ready, NMEA can print from uart.
1006 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +08001007
1008 LOGD("GNSS open success.");
1009
b.liuced8dd02024-06-28 13:28:29 +08001010 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +08001011
b.liu8f231a12024-05-31 17:55:06 +08001012exit_with_thread_exit:
1013 gnss_info.state = GNSS_STATE_CLOSING;
1014 // Wait for read thread exit.
1015 ret = pthread_join(gnss_info.read_pid, NULL);
1016 if(ret){
1017 LOGE("pthrad_join fail(%d)",ret);
1018 }
1019exit_with_close:
1020 if(gnss_info.gnss_close(gnss_info.fd)) {
1021 LOGE("gnss_close() fail.");
1022 }
1023 if(gnss_info.exit_fd[0] > 0) {
1024 close(gnss_info.exit_fd[0]);
1025 gnss_info.exit_fd[0] = -1;
1026 }
1027 if(gnss_info.exit_fd[1] > 0) {
1028 close(gnss_info.exit_fd[1]);
1029 gnss_info.exit_fd[1] = -1;
1030 }
1031 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +08001032 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001033}
1034
1035int gnss_deinit()
1036{
1037 if(gnss_info.state == GNSS_STATE_CLOSE) {
1038 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +08001039 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +08001040 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
1041 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +08001042 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001043 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
1044 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +08001045 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001046 }
1047
b.liu978f5432024-07-01 18:04:18 +08001048 if(gnss_info.gnss_dev_close(gnss_info.fd)) {
1049 LOGE("gnss_dev_close() fail.");
1050 return GNSS_ERR_UNKNOWN;
1051 }
1052
b.liu8f231a12024-05-31 17:55:06 +08001053 // Wait for read thread exit.
1054 if(gnss_info.exit_fd[1] > 0) {
1055 write(gnss_info.exit_fd[1], "exit", 4);
1056 }
1057
1058 gnss_info.state = GNSS_STATE_CLOSING;
1059 int ret = pthread_join(gnss_info.read_pid, NULL);
1060 if(ret){
1061 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +08001062 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001063 }
1064
1065 if(gnss_info.gnss_close(gnss_info.fd)) {
1066 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +08001067 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001068 }
1069
b.liu8f231a12024-05-31 17:55:06 +08001070 if(gnss_ports_close()) {
1071 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +08001072 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +08001073 }
1074
b.liud0ba7152024-06-19 14:47:21 +08001075 LOGD("gnss_ports_close() complete.");
1076
b.liu8f231a12024-05-31 17:55:06 +08001077 gnss_info.fd = -1;
1078 if(gnss_info.exit_fd[0] > 0) {
1079 close(gnss_info.exit_fd[0]);
1080 gnss_info.exit_fd[0] = -1;
1081 }
1082 if(gnss_info.exit_fd[1] > 0) {
1083 close(gnss_info.exit_fd[1]);
1084 gnss_info.exit_fd[1] = -1;
1085 }
1086 gnss_info.state = GNSS_STATE_CLOSE;
1087 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +08001088 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +08001089}
1090
1091int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
1092{
b.liud0ba7152024-06-19 14:47:21 +08001093 if(buf && buf_len > 0) {
1094 if(cmd_rsp && cmd_rsp_len > 0) {
1095 memset(cmd_rsp, 0, cmd_rsp_len);
1096 }
b.liu8f231a12024-05-31 17:55:06 +08001097 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
1098 } else {
b.liudbc3f4b2024-06-25 18:22:24 +08001099 return GNSS_ERR_UNKNOWN;
1100 }
1101}
1102
1103int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
1104{
b.liu42f558e2024-07-18 14:06:49 +08001105 // Only 8122 support download fw.
b.liudbc3f4b2024-06-25 18:22:24 +08001106 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
1107 return GNSS_ERR_UNSUPPORT;
1108 }
1109
1110 if(rsp && rsp_len > 0) {
1111 memset(rsp, 0, rsp_len);
1112 }
1113
1114 if(gnss_info.gnss_fw_dl) {
1115 if(GNSS_ERR_OK != gnss_deinit()) {
1116 LOGE("Close gnss fail.");
1117 return GNSS_ERR_UNKNOWN;
1118 } else {
1119 LOGD("Start gnss fw dl.");
1120 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
1121 }
1122 } else {
b.liu42f558e2024-07-18 14:06:49 +08001123 return GNSS_ERR_UNSUPPORT;
b.liu8f231a12024-05-31 17:55:06 +08001124 }
1125}
1126
b.liue77ac3a2024-07-17 17:36:57 +08001127int gnss_ind_set(int fd, int ind_type)
1128{
1129 int index = 0;
1130 if(ind_type) { // Add IND flag.
1131 while(index < GNSS_CLI_IND_MAX) {
1132 if(ind_info[index].cli_fd == fd)
1133 break;
1134 index++;
1135 }
1136
1137 if(index == GNSS_CLI_IND_MAX) { // Add flag
1138 index = 0;
1139 while(index < GNSS_CLI_IND_MAX) {
1140 if(ind_info[index].cli_fd <= 0)
1141 break;
1142 index++;
1143 }
yq.wang1ddd1fd2024-07-25 23:00:14 -07001144 if(index == GNSS_CLI_IND_MAX)
1145 {
1146 LOGE("ind flag is full.");
1147 return GNSS_ERR_CLI_FULL;
1148 }
b.liue77ac3a2024-07-17 17:36:57 +08001149 ind_info[index].cli_fd = fd;
1150 ind_info[index].ind_flag = (uint32)ind_type;
yq.wang937355d2024-07-26 01:24:42 -07001151 } else { // Change flag
b.liue77ac3a2024-07-17 17:36:57 +08001152 ind_info[index].cli_fd = fd;
1153 ind_info[index].ind_flag = (uint32)ind_type;
1154 }
1155 } else { // Clear IND flag.
1156 while(index < GNSS_CLI_IND_MAX) {
1157 if(ind_info[index].cli_fd == fd)
1158 break;
1159 index++;
1160 }
1161
1162 if(index == GNSS_CLI_IND_MAX) {
1163 return GNSS_ERR_ARG;
yq.wang937355d2024-07-26 01:24:42 -07001164 }
b.liue77ac3a2024-07-17 17:36:57 +08001165 ind_info[index].cli_fd = 0;
1166 ind_info[index].ind_flag = 0;
1167 }
1168
1169 return GNSS_ERR_OK;
1170}
1171
b.liu8f231a12024-05-31 17:55:06 +08001172static void sig_process(int sig)
1173{
1174 LOGI("I got signal %d\n", sig);
1175 if(gnss_deinit()) {
1176 LOGE("gnss_deinit() fail, no exist...");
1177 return;
1178 }
1179
1180 switch(sig)
1181 {
1182 case SIGINT: // Ctrl + C
1183 {
1184 LOGI("Exit by SIGINT.\n");
1185 exit(0);
1186 }
luojiand7960682024-08-02 16:50:01 +08001187 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 +08001188 {
1189 LOGI("Exit by SIGQUIT.\n");
1190 exit(0);
1191 }
luojiand7960682024-08-02 16:50:01 +08001192 case SIGTERM:// Ĭ\C8\CFkill (ͬ SIGKILL \A3\AC\B5\AB SIGKILL \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001193 {
1194 LOGI("Exit by SIGTERM.\n");
1195 exit(0);
1196 }
luojiand7960682024-08-02 16:50:01 +08001197 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP \A3\AC\B5\AB SIGSTOP \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001198 {
1199 LOGI("Exit by SIGTSTP.\n");
1200 exit(0);
1201 }
luojiand7960682024-08-02 16:50:01 +08001202 case SIGSEGV: // \C8\E7\BF\D5ָ\D5\EB
b.liu8f231a12024-05-31 17:55:06 +08001203 {
1204 LOGI("Exit by SIGSEGV.\n");
1205 exit(0);
1206 }
1207 default:
1208 {
1209 LOGI("Unknown sig:%d\n",sig);
1210 break;
1211 }
1212 }
1213}
1214
1215
b.liuced8dd02024-06-28 13:28:29 +08001216// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +08001217int main(int argc, char *argv[])
1218{
1219 mbtk_log_init("radio", GNSS_TAG);
1220
b.liubb590492024-06-13 16:42:08 +08001221#ifdef MBTK_DUMP_SUPPORT
1222 mbtk_debug_open(NULL, TRUE);
1223#endif
1224
b.liu8f231a12024-05-31 17:55:06 +08001225 signal(SIGINT, sig_process);
1226 signal(SIGQUIT, sig_process);
1227 signal(SIGTERM, sig_process);
1228
1229 if(arg_check(argc, argv)) {
1230 return -1;
1231 }
1232
1233#ifdef GNSS_DEBUG
1234 char buff[10];
1235 memset(buff, 0, 10);
1236 property_get(MBTK_PROP_GNSS_LOG, buff, "");
1237 if(strlen(buff) > 0 && atoi(buff) > 0) {
1238 nmea_log_enable = TRUE;
1239 }
1240#endif
1241
1242 memset(&gnss_info, 0, sizeof(gnss_info_t));
1243 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
1244 gnss_info.state = GNSS_STATE_CLOSE;
1245 if(!strcmp(argv[1], GNSS_ID_6228)) {
1246 gnss_info.gnss_id = GNSS_TYPE_6228;
1247 gnss_info.auto_open = (bool)atoi(argv[3]);
1248 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +08001249 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +08001250 gnss_info.gnss_dev_open = gnss_6228_dev_open;
1251 gnss_info.gnss_dev_close = gnss_6228_dev_close;
1252 gnss_info.gnss_open = gnss_6228_open;
1253 gnss_info.gnss_close = gnss_6228_close;
1254 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
1255 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
1256 gnss_info.gnss_set = gnss_6228_set;
1257 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +08001258 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
1259 gnss_info.gnss_id = GNSS_TYPE_8122;
1260 gnss_info.auto_open = (bool)atoi(argv[3]);
1261 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +08001262 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +08001263 gnss_info.gnss_dev_open = gnss_8122_dev_open;
1264 gnss_info.gnss_dev_close = gnss_8122_dev_close;
1265 gnss_info.gnss_open = gnss_8122_open;
1266 gnss_info.gnss_close = gnss_8122_close;
1267 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
1268 gnss_info.gnss_dl_read_cb = NULL;
1269 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +08001270 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +08001271 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
1272 gnss_info.gnss_id = GNSS_TYPE_5311;
1273 gnss_info.auto_open = (bool)atoi(argv[3]);
1274 gnss_info.auto_dl_fw = TRUE;
1275 gnss_info.dl_befor_open = TRUE;
1276 gnss_info.gnss_dev_open = gnss_5311_dev_open;
1277 gnss_info.gnss_dev_close = gnss_5311_dev_close;
1278 gnss_info.gnss_open = gnss_5311_open;
1279 gnss_info.gnss_close = gnss_5311_close;
1280 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
1281 gnss_info.gnss_dl_read_cb = NULL;
1282 gnss_info.gnss_set = gnss_5311_set;
1283 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu42f558e2024-07-18 14:06:49 +08001284 } else if(!strcmp(argv[1], GNSS_ID_N50DB)) {
1285 gnss_info.gnss_id = GNSS_TYPE_N50DB;
1286 gnss_info.auto_open = (bool)atoi(argv[3]);
1287 gnss_info.auto_dl_fw = FALSE;
1288 gnss_info.dl_befor_open = FALSE;
1289 gnss_info.gnss_dev_open = gnss_n50db_dev_open;
1290 gnss_info.gnss_dev_close = gnss_n50db_dev_close;
1291 gnss_info.gnss_open = gnss_n50db_open;
1292 gnss_info.gnss_close = gnss_n50db_close;
1293 gnss_info.gnss_fw_dl = gnss_n50db_fw_dl;
1294 gnss_info.gnss_dl_read_cb = NULL;
1295 gnss_info.gnss_set = gnss_n50db_set;
1296 gnss_info.gnss_set_cb = gnss_n50db_set_cb;
b.liu8f231a12024-05-31 17:55:06 +08001297 } else {
1298 LOGE("No support : %s", argv[1]);
1299 return -1;
1300 }
1301
1302 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
1303 // Auto open gnss.
1304 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +08001305 int init_mode = atoi(argv[3]);
1306 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
1307 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +08001308 }
b.liuced8dd02024-06-28 13:28:29 +08001309 if(gnss_init((uint32)init_mode)) {
1310 LOGE("gnss_init() fail.");
1311 // return -1;
1312 }
1313 } else {
1314 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +08001315 }
1316
1317 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +08001318#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +08001319 if(gnss_ubus_init()) {
1320 LOGD("main() run...");
1321 uloop_run();
1322 } else {
1323 LOGE("gnss_ubus_init() fail.");
1324 }
b.liu5f950c52024-06-15 20:13:12 +08001325#else
1326 if(!gnss_ipc_service_start()) {
1327 LOGD("main() run...");
1328 while(1) {
1329 sleep(24 * 60 * 60);
1330 }
1331 } else {
1332 LOGE("gnss_ipc_service_start() fail.");
1333 }
1334#endif
b.liu8f231a12024-05-31 17:55:06 +08001335
1336 LOGD("main() exit.");
1337 return 0;
1338}