blob: 3f887f1b643c5c29fc0cc7c6572503aeab534b11 [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>
11
12#include "mbtk_type.h"
13#include "mbtk_log.h"
14#include "gnss_info.h"
15
16#include "gnss_6228.h"
b.liuf9fbfa12024-06-14 15:53:59 +080017#include "gnss_hd8122.h"
b.liu99c645d2024-06-20 10:52:15 +080018#include "gnss_asr5311.h"
19
b.liu8f231a12024-05-31 17:55:06 +080020
21#define GNSS_DEBUG 1
b.liud0ba7152024-06-19 14:47:21 +080022#define GNSS_UBUS_ENABLE 1
b.liu8f231a12024-05-31 17:55:06 +080023
24#define GNSS_TAG "MBTK_GNSS"
25#define GNSS_BUFF_SIZE 2048
26#define MBTK_PROP_GNSS_LOG "persist.mbtk.gnss_log_enable"
27#define GNSS_PORT_PTY "/dev/tty_gnss_nmea"
28#define GNSS_PORT_USB_AT "/dev/ttyGS0"
29#define GNSS_PORT_USB_NMEA "/dev/ttymodem0"
30#define GNSS_PORT_UART_AT "/dev/ttyS1"
31
32#ifdef GNSS_DEBUG
33#define GNSS_NMEA_FILE_LOG "/tmp/mbtk_gnss_nmea.log"
b.liu8f231a12024-05-31 17:55:06 +080034#define GNSS_FILE_LOG "/tmp/mbtk_gnss.log"
b.liu99c645d2024-06-20 10:52:15 +080035#define GNSS_FILE_LOG_MAX 104857600 // 100MB
b.liu8f231a12024-05-31 17:55:06 +080036#endif
37
38gnss_info_t gnss_info;
39
b.liud0ba7152024-06-19 14:47:21 +080040#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080041struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080042#else
43int gnss_ipc_service_start();
44#endif
45
b.liu8f231a12024-05-31 17:55:06 +080046int gnss_init_config(int fd);
47
b.liud0ba7152024-06-19 14:47:21 +080048static char nmea_buff[GNSS_BUFF_SIZE*2] = {0};
49static char data_buff[GNSS_BUFF_SIZE] = {0};
50static uint32 nmea_buff_len = 0;
51static uint32 data_buff_len = 0;
52
b.liu8f231a12024-05-31 17:55:06 +080053static bool nmea_found = FALSE;
54#ifdef GNSS_DEBUG
55static bool nmea_log_enable = FALSE;
56static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080057static int debug_fd = -1;
58static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080059#endif
60static int gnss_pty_master_fd = -1;
61static int gnss_pty_slave_fd = -1;
62static int gnss_usb_at_port_fd = -1;
63static int gnss_usb_nmea_port_fd = -1;
64static int gnss_uart_at_port_fd = -1;
65static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
66
67static void help()
68{
b.liu99c645d2024-06-20 10:52:15 +080069 LOGD("mbtk_gnssd <6228/8122/5311> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080070}
71
72static int arg_check(int argc, char *argv[])
73{
74 if(argc != 4) {
75 goto check_fail;
76 }
77
b.liu99c645d2024-06-20 10:52:15 +080078 // Only support 6228/8122/5311.
79 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)) {
b.liu8f231a12024-05-31 17:55:06 +080080 goto check_fail;
81 }
82
83 if(access(argv[2], R_OK | W_OK)) {
84 goto check_fail;
85 }
86
87 if(strcmp(argv[3], "0") && strcmp(argv[3], "1")) {
88 goto check_fail;
89 }
90
91 return 0;
92check_fail:
93 help();
94 return -1;
95}
96
97static int gnss_ports_open(uint32 print_port)
98{
99 if(print_port & GNSS_PRINT_PORT_TTY_AT) {
100 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
101 return -1;
102 }
103 LOGD("Open PTY port success.");
104 }
105
106 if(print_port & GNSS_PRINT_PORT_USB_AT) {
107 if((gnss_usb_at_port_fd = gnss_port_open(GNSS_PORT_USB_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
108 return -1;
109 }
110 LOGD("Open USB AT port success.");
111 }
112
113 if(print_port & GNSS_PRINT_PORT_USB_NMEA) {
114 if((gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
115 return -1;
116 }
117 LOGD("Open USB NMEA port success.");
118 }
119
120 if(print_port & GNSS_PRINT_PORT_UART1) {
121 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
122 return -1;
123 }
124 LOGD("Open UART AT port success.");
125 }
126
127 return 0;
128}
129
130static int gnss_ports_close()
131{
132 if(gnss_usb_at_port_fd > 0) {
133 close(gnss_usb_at_port_fd);
134 gnss_usb_at_port_fd = -1;
135 }
136
137 if(gnss_usb_nmea_port_fd > 0) {
138 close(gnss_usb_nmea_port_fd);
139 gnss_usb_nmea_port_fd = -1;
140 }
141
142 if(gnss_uart_at_port_fd > 0) {
143 close(gnss_uart_at_port_fd);
144 gnss_uart_at_port_fd = -1;
145 }
146
147 if(gnss_pty_master_fd > 0) {
148 close(gnss_pty_master_fd);
149 gnss_pty_master_fd = -1;
150 }
151
152 if(gnss_pty_slave_fd > 0) {
153 close(gnss_pty_slave_fd);
154 gnss_pty_slave_fd = -1;
155 unlink(GNSS_PORT_PTY);
156 }
157
158 return 0;
159}
160
b.liu8f231a12024-05-31 17:55:06 +0800161#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800162static void log_save(int fd, const char *data, int data_len)
163{
b.liu8f231a12024-05-31 17:55:06 +0800164 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800165 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
166 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
167 close(debug_fd);
168 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
169 if(debug_fd < 0) {
170 LOGE("Open debug fd fail.");
171 }
172 debug_fd_len = 0;
173
174 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800175 close(nmea_log_fd);
176 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
177 if(nmea_log_fd < 0) {
178 LOGE("Open debug fd fail.");
179 }
b.liu8f231a12024-05-31 17:55:06 +0800180 }
181
b.liu99c645d2024-06-20 10:52:15 +0800182 if(fd == nmea_log_fd) {
183 if(nmea_log_fd > 0) {
184 write(nmea_log_fd, data, data_len);
185 debug_fd_len += data_len;
186 }
187 } else if(fd == debug_fd) {
188 if(debug_fd > 0) {
189 write(debug_fd, data, data_len);
190 debug_fd_len += data_len;
191 }
b.liu8f231a12024-05-31 17:55:06 +0800192 }
193 }
b.liu99c645d2024-06-20 10:52:15 +0800194}
b.liu8f231a12024-05-31 17:55:06 +0800195#endif
196
b.liu99c645d2024-06-20 10:52:15 +0800197static void nmea_print(const char *nmea, int nmea_len)
198{
b.liu8f231a12024-05-31 17:55:06 +0800199 if(gnss_usb_at_port_fd > 0) {
200 write(gnss_usb_at_port_fd, nmea, nmea_len);
201 }
202
203 if(gnss_usb_nmea_port_fd > 0) {
204 write(gnss_usb_nmea_port_fd, nmea, nmea_len);
205 }
206
207 if(gnss_uart_at_port_fd > 0) {
208 write(gnss_uart_at_port_fd, nmea, nmea_len);
209 }
210
211 if(gnss_pty_master_fd > 0) {
212 write(gnss_pty_master_fd, nmea, nmea_len);
213 }
214}
215
216static unsigned char nmea_checksum(const char *nmea)
217{
218 const char *p = nmea;
219 unsigned char chs = 0;
220
221 while (*p == '$') // skip '$'
222 p++;
223 while (*p != '*' && *p != 0)
224 chs ^= *p++;
225
226 return chs;
227}
228
229static bool nmea_check(const char *nmea, int nmea_len)
230{
231 char **ptr = gnss_filter_info;
232 while(*ptr) {
233 if(strstr(nmea, *ptr)) {
234 break;
235 }
236 ptr++;
237 }
238
239 if(*ptr == NULL) {
240 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
241 return FALSE;
242 }
243
244 char *checksum_str = strstr(nmea, "*");
245 checksum_str++; // Jump '*'
246 char checksum_buf[3] = {0};
247 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
248 if(strncasecmp(checksum_buf, checksum_str, 2)) {
249 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
250 return FALSE;
251 }
252
253 return TRUE;
254}
255
256static void gnss_nmea_process(const char *data, int data_len)
257{
b.liu99c645d2024-06-20 10:52:15 +0800258 // LOGD("gnss_nmea_process() : data_len - %d", data_len);
259#if 0
b.liu8f231a12024-05-31 17:55:06 +0800260 char nmea[GNSS_BUFF_SIZE] = {0};
261 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800262#else
263 const char *nmea = data;
264#endif
b.liu8f231a12024-05-31 17:55:06 +0800265
266 if(!nmea_check(nmea, data_len)) {
b.liu99c645d2024-06-20 10:52:15 +0800267 LOGD("NO-NMEA:%s", nmea);
268#if GNSS_DEBUG
269 log_save(nmea_log_fd, "/**/", 4);
270 log_save(nmea_log_fd, nmea, data_len);
271#endif
272 if(gnss_info.gnss_set_cb)
273 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800274 return;
275 }
276
277#ifdef GNSS_DEBUG
278 if(nmea_log_enable) {
279 LOGD("NMEA[%d]:%s", data_len, nmea);
280 }
b.liu99c645d2024-06-20 10:52:15 +0800281
282 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800283#endif
284
285 nmea_print(nmea, data_len);
286}
287
288#if 0
289static void gnss_cmd_rsp_process(const char *data, int data_len)
290{
291 char rsp[GNSS_BUFF_SIZE] = {0};
292 memcpy(rsp, data, data_len);
293 LOGD("RSP[%d]:%s", data_len, rsp);
294}
295#endif
296
297static bool nmea_char_check(char ch)
298{
299 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
b.liu99c645d2024-06-20 10:52:15 +0800300 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=')
b.liu8f231a12024-05-31 17:55:06 +0800301 return TRUE;
302
303 return FALSE;
304}
305
306static void gnss_data_process(const char *data, int data_len)
307{
308 if(gnss_info.state == GNSS_STATE_OPEN) {
309 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
310 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
311 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800312 if(gnss_info.gnss_dl_read_cb) {
313 gnss_info.gnss_dl_read_cb(data, data_len);
314 }
b.liu8f231a12024-05-31 17:55:06 +0800315 } else if(gnss_info.state == GNSS_STATE_READY) {
316 int index = 0;
317 while(index < data_len) {
318 if(nmea_found) {
319 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800320 // Copy nmea_buff to data_buff
321 // Start with '$', but not nmea data, so copy to data_buff.
322 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
323 data_buff_len += nmea_buff_len;
324 data_buff[data_buff_len++] = data[index];
325
326 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800327 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800328 continue;
329 }
330
331 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800332 nmea_buff[nmea_buff_len++] = data[index];
333 if(nmea_buff[nmea_buff_len - 1] == '\n') {
334 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800335#if GNSS_DEBUG
336 log_save(nmea_log_fd, "/**/", 4);
337 log_save(nmea_log_fd, data_buff, data_buff_len);
338#endif
339 if(gnss_info.gnss_set_cb) {
340 gnss_info.gnss_set_cb(data_buff, data_buff_len);
341 }
b.liud0ba7152024-06-19 14:47:21 +0800342 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800343 }
344
b.liud0ba7152024-06-19 14:47:21 +0800345 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800346 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800347 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800348 } else if(nmea_buff_len > 0) {
349 nmea_buff[nmea_buff_len] = '\0';
350 LOGD("NO-NMEA:%s", nmea_buff);
351#if GNSS_DEBUG
352 log_save(nmea_log_fd, "/**/", 4);
353 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
354#endif
b.liud0ba7152024-06-19 14:47:21 +0800355 }
356
357 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800358 nmea_found = FALSE;
359 }
360 }
361 } else {
362 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800363 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800364 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800365 nmea_buff[nmea_buff_len++] = data[index];
366 } else {
367 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800368 }
369 }
370 index++;
371 }
372 } else {
373 LOGW("Unknown state : %d", gnss_info.state);
374 }
375}
376
377void* gnss_read_pthread(void* arg)
378{
379 LOGD("gnss_read_pthread enter.");
380 char buffer[GNSS_BUFF_SIZE];
381 int len = 0;
382 int ret = 0;
383 fd_set fdr, fdw;
384 int fd_max = 0;
385
386 FD_ZERO(&fdw);
387 FD_ZERO(&fdr);
388 FD_SET(gnss_info.fd, &fdr);
389 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
390 FD_SET(gnss_info.exit_fd[0], &fdr);
391 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800392 memset(nmea_buff, 0, sizeof(nmea_buff));
393 memset(data_buff, 0, sizeof(data_buff));
394 nmea_buff_len = 0;
395 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800396#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800397 if(nmea_log_enable) {
398 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
399 if(debug_fd < 0) {
400 LOGE("Open debug fd fail.");
401 }
402 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
403 if(nmea_log_fd < 0) {
404 LOGE("Open nmea fd fail.");
405 }
b.liu99c645d2024-06-20 10:52:15 +0800406 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800407 }
408#endif
409
410 while(gnss_info.state >= GNSS_STATE_OPEN) {
411 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
412 //LOGD("select - %d", ret);
413 if (ret < 0)
414 {
415 if (errno == EINTR)
416 {
417 continue;
418 }
419 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
420 break;
421 }
422 else if (ret == 0)
423 {
424 LOGE("select ret == 0");
425 break;
426 }
427
428 if (FD_ISSET(gnss_info.fd, &fdr))
429 {
430 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800431 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800432 if(len > 0) {
433 //log_hex("READ", buffer, len);
434
435#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800436 //LOGD("read data_len = %d", len);
437 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800438#endif
439
440 gnss_data_process(buffer, len);
441
442 } else if(len ==0 ){
443 LOGE("Read end : len = 0");
444 break;
445 } else {
446 if(EAGAIN == errno) {
447 usleep(50000);
448 continue;
449 } else {
450 LOGD("Read ret = -1 ,errno = %d", errno);
451 break;
452 }
453 }
454 }
455 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
456 {
457 memset(buffer, 0, GNSS_BUFF_SIZE);
458 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE);
459 if(len > 0) {
460 if(strcmp(buffer, "exit") == 0) {
461 LOGD("Get thread exit message.");
462 break;
463 }
464 }
465 }
466 else
467 {
468 LOGW("Unknown select event.");
469 continue;
470 }
471 }
472
473#if GNSS_DEBUG
474 if(debug_fd > 0) {
475 close(debug_fd);
476 debug_fd = -1;
477 }
478 if(nmea_log_fd > 0) {
479 close(nmea_log_fd);
480 nmea_log_fd = -1;
481 }
482#endif
483
484 gnss_info.state = GNSS_STATE_CLOSE;
485 LOGD("gnss_read_pthread exit.");
486 return NULL;
487}
488
489#if 0
490int gnss_write(int fd, const void *data, int data_len)
491{
492 int count = 0;
493 int len = 0;
494 while(1)
495 {
496 len = write(fd, data + count, data_len - count);
497 if (len > 0)
498 {
499 count += len;
500 }
501 else
502 {
503 LOGE("write() fail,ret = %d,errno = %d", len, errno);
504 break;
505 }
506
507 if (count == data_len)
508 break;
509 }
510
511 return count;
512}
513#else
514int gnss_write(int fd, const void* buf, unsigned int buf_len)
515{
516 size_t size;
517 size_t size_to_wr;
518 ssize_t size_written;
519 if(GNSS_BUFF_SIZE < buf_len)
520 {
521 return -1;
522 }
523 for(size = 0; size < buf_len;)
524 {
525 size_to_wr = buf_len - size;
526 if( size_to_wr > GNSS_BUFF_SIZE)
527 size_to_wr = GNSS_BUFF_SIZE;
528
529 size_written = write(fd, &buf[size], size_to_wr);
530 if (size_written==-1)
531 {
532 return -1;
533 }
534 size += size_written;
535 if(size_written != size_to_wr)
536 {
537 return size;
538 }
539 }
540 // LOGD("SEND %d / %d", size, buf_len);
541 return size;
542}
543#endif
544
545int gnss_init(uint32 print_port)
546{
547 if(gnss_info.state != GNSS_STATE_CLOSE) {
548 LOGW("GNSS not close:%d", gnss_info.state);
549 return 0;
550 }
551
552 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800553 if(gnss_info.dl_befor_open) {
554 //if(gnss_info.auto_dl_fw) {
555 gnss_info.state = GNSS_STATE_DOWNLOAD;
556 ret = gnss_info.gnss_fw_dl(gnss_info.fd, gnss_info.dev_name);
557 if(ret) {
558 LOGE("gnss_fw_dl() fail : %d", ret);
559 gnss_info.state = GNSS_STATE_CLOSE;
560 return -1;
561 }
b.liu8f231a12024-05-31 17:55:06 +0800562
b.liu99c645d2024-06-20 10:52:15 +0800563 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
564 if(gnss_info.fd <= 0) {
565 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
566 gnss_info.state = GNSS_STATE_CLOSE;
567 return -1;
568 }
569 if(pipe(gnss_info.exit_fd)) {
570 LOGE("pipe() fail[%d].", errno);
571 return -1;
572 }
573 // GNSS is opened.
574 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800575
b.liu99c645d2024-06-20 10:52:15 +0800576#if 0
577 // Start gnss read thread.
578 pthread_attr_t thread_attr;
579 pthread_attr_init(&thread_attr);
580 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
581 {
582 LOGE("pthread_attr_setdetachstate() fail.");
583 goto main_exit;
584 }
b.liu8f231a12024-05-31 17:55:06 +0800585
b.liu99c645d2024-06-20 10:52:15 +0800586 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800587#else
b.liu99c645d2024-06-20 10:52:15 +0800588 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800589#endif
b.liu99c645d2024-06-20 10:52:15 +0800590 {
591 LOGE("pthread_create() fail.");
592 goto exit_with_close;
593 }
b.liu8f231a12024-05-31 17:55:06 +0800594
b.liu99c645d2024-06-20 10:52:15 +0800595 ret = gnss_info.gnss_dev_open();
596 if(ret) {
597 LOGE("gnss_dev_open() fail : %d", ret);
598 goto exit_with_thread_exit;
599 }
600 //}
601 } else {
602 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
603 if(gnss_info.fd <= 0) {
604 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
605 gnss_info.state = GNSS_STATE_CLOSE;
606 return -1;
607 }
608 if(pipe(gnss_info.exit_fd)) {
609 LOGE("pipe() fail[%d].", errno);
610 return -1;
611 }
612 // GNSS is opened.
613 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800614
b.liu99c645d2024-06-20 10:52:15 +0800615#if 0
616 // Start gnss read thread.
617 pthread_attr_t thread_attr;
618 pthread_attr_init(&thread_attr);
619 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
620 {
621 LOGE("pthread_attr_setdetachstate() fail.");
622 goto main_exit;
623 }
624
625 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
626#else
627 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
628#endif
629 {
630 LOGE("pthread_create() fail.");
631 goto exit_with_close;
632 }
633
634 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800635 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800636 LOGE("gnss_dev_open() fail : %d", ret);
637 goto exit_with_thread_exit;
638 }
639
640 if(gnss_info.auto_dl_fw) {
641 gnss_info.state = GNSS_STATE_DOWNLOAD;
642 ret = gnss_info.gnss_fw_dl(gnss_info.fd, gnss_info.dev_name);
643 if(ret) {
644 LOGE("gnss_fw_dl() fail : %d", ret);
645 goto exit_with_dev_close;
646 }
b.liu8f231a12024-05-31 17:55:06 +0800647 }
648 }
649
650 // GNSS is ready, NMEA can print from uart.
651 gnss_info.state = GNSS_STATE_READY;
652 gnss_info.print_port = print_port;
653
654 LOGD("GNSS open success.");
655
656 return gnss_ports_open(gnss_info.print_port);
657
658exit_with_dev_close:
659 if(gnss_info.gnss_dev_close()) {
660 LOGE("gnss_dev_close() fail.");
661 }
662exit_with_thread_exit:
663 gnss_info.state = GNSS_STATE_CLOSING;
664 // Wait for read thread exit.
665 ret = pthread_join(gnss_info.read_pid, NULL);
666 if(ret){
667 LOGE("pthrad_join fail(%d)",ret);
668 }
669exit_with_close:
670 if(gnss_info.gnss_close(gnss_info.fd)) {
671 LOGE("gnss_close() fail.");
672 }
673 if(gnss_info.exit_fd[0] > 0) {
674 close(gnss_info.exit_fd[0]);
675 gnss_info.exit_fd[0] = -1;
676 }
677 if(gnss_info.exit_fd[1] > 0) {
678 close(gnss_info.exit_fd[1]);
679 gnss_info.exit_fd[1] = -1;
680 }
681 gnss_info.state = GNSS_STATE_CLOSE;
682 return -1;
683}
684
685int gnss_deinit()
686{
687 if(gnss_info.state == GNSS_STATE_CLOSE) {
688 LOGW("GNSS is closed.");
689 return 0;
690 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
691 LOGW("GNSS is closing...");
692 return -1;
693 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
694 LOGW("GNSS is downloading...");
695 return -1;
696 }
697
698 // Wait for read thread exit.
699 if(gnss_info.exit_fd[1] > 0) {
700 write(gnss_info.exit_fd[1], "exit", 4);
701 }
702
703 gnss_info.state = GNSS_STATE_CLOSING;
704 int ret = pthread_join(gnss_info.read_pid, NULL);
705 if(ret){
706 LOGE("pthrad_join fail(%d)",ret);
707 return -1;
708 }
709
710 if(gnss_info.gnss_close(gnss_info.fd)) {
711 LOGE("gnss_close() fail.");
712 return -1;
713 }
714
715 if(gnss_info.gnss_dev_close()) {
716 LOGE("gnss_dev_close() fail.");
717 return -1;
718 }
719
720 if(gnss_ports_close()) {
721 LOGE("gnss_ports_close fail.");
722 return -1;
723 }
724
b.liud0ba7152024-06-19 14:47:21 +0800725 LOGD("gnss_ports_close() complete.");
726
b.liu8f231a12024-05-31 17:55:06 +0800727 gnss_info.fd = -1;
728 if(gnss_info.exit_fd[0] > 0) {
729 close(gnss_info.exit_fd[0]);
730 gnss_info.exit_fd[0] = -1;
731 }
732 if(gnss_info.exit_fd[1] > 0) {
733 close(gnss_info.exit_fd[1]);
734 gnss_info.exit_fd[1] = -1;
735 }
736 gnss_info.state = GNSS_STATE_CLOSE;
737 LOGD("GNSS close success.");
738 return 0;
739}
740
741int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
742{
b.liud0ba7152024-06-19 14:47:21 +0800743 if(buf && buf_len > 0) {
744 if(cmd_rsp && cmd_rsp_len > 0) {
745 memset(cmd_rsp, 0, cmd_rsp_len);
746 }
b.liu8f231a12024-05-31 17:55:06 +0800747 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
748 } else {
749 return -1;
750 }
751}
752
753static void sig_process(int sig)
754{
755 LOGI("I got signal %d\n", sig);
756 if(gnss_deinit()) {
757 LOGE("gnss_deinit() fail, no exist...");
758 return;
759 }
760
761 switch(sig)
762 {
763 case SIGINT: // Ctrl + C
764 {
765 LOGI("Exit by SIGINT.\n");
766 exit(0);
767 }
768 case SIGQUIT: // Ctrl + \ (ÀàËÆ SIGINT £¬µ«Òª²úÉúcoreÎļþ)
769 {
770 LOGI("Exit by SIGQUIT.\n");
771 exit(0);
772 }
773 case SIGTERM:// ĬÈÏkill (ͬ SIGKILL £¬µ« SIGKILL ²»¿É²¶»ñ)
774 {
775 LOGI("Exit by SIGTERM.\n");
776 exit(0);
777 }
778 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP £¬µ« SIGSTOP ²»¿É²¶»ñ)
779 {
780 LOGI("Exit by SIGTSTP.\n");
781 exit(0);
782 }
783 case SIGSEGV: // Èç¿ÕÖ¸Õë
784 {
785 LOGI("Exit by SIGSEGV.\n");
786 exit(0);
787 }
788 default:
789 {
790 LOGI("Unknown sig:%d\n",sig);
791 break;
792 }
793 }
794}
795
796
797// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1
798int main(int argc, char *argv[])
799{
800 mbtk_log_init("radio", GNSS_TAG);
801
b.liubb590492024-06-13 16:42:08 +0800802#ifdef MBTK_DUMP_SUPPORT
803 mbtk_debug_open(NULL, TRUE);
804#endif
805
b.liu8f231a12024-05-31 17:55:06 +0800806 signal(SIGINT, sig_process);
807 signal(SIGQUIT, sig_process);
808 signal(SIGTERM, sig_process);
809
810 if(arg_check(argc, argv)) {
811 return -1;
812 }
813
814#ifdef GNSS_DEBUG
815 char buff[10];
816 memset(buff, 0, 10);
817 property_get(MBTK_PROP_GNSS_LOG, buff, "");
818 if(strlen(buff) > 0 && atoi(buff) > 0) {
819 nmea_log_enable = TRUE;
820 }
821#endif
822
823 memset(&gnss_info, 0, sizeof(gnss_info_t));
824 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
825 gnss_info.state = GNSS_STATE_CLOSE;
826 if(!strcmp(argv[1], GNSS_ID_6228)) {
827 gnss_info.gnss_id = GNSS_TYPE_6228;
828 gnss_info.auto_open = (bool)atoi(argv[3]);
829 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +0800830 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800831 gnss_info.gnss_dev_open = gnss_6228_dev_open;
832 gnss_info.gnss_dev_close = gnss_6228_dev_close;
833 gnss_info.gnss_open = gnss_6228_open;
834 gnss_info.gnss_close = gnss_6228_close;
835 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
836 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
837 gnss_info.gnss_set = gnss_6228_set;
838 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +0800839 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
840 gnss_info.gnss_id = GNSS_TYPE_8122;
841 gnss_info.auto_open = (bool)atoi(argv[3]);
842 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +0800843 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +0800844 gnss_info.gnss_dev_open = gnss_8122_dev_open;
845 gnss_info.gnss_dev_close = gnss_8122_dev_close;
846 gnss_info.gnss_open = gnss_8122_open;
847 gnss_info.gnss_close = gnss_8122_close;
848 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
849 gnss_info.gnss_dl_read_cb = NULL;
850 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +0800851 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +0800852 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
853 gnss_info.gnss_id = GNSS_TYPE_5311;
854 gnss_info.auto_open = (bool)atoi(argv[3]);
855 gnss_info.auto_dl_fw = TRUE;
856 gnss_info.dl_befor_open = TRUE;
857 gnss_info.gnss_dev_open = gnss_5311_dev_open;
858 gnss_info.gnss_dev_close = gnss_5311_dev_close;
859 gnss_info.gnss_open = gnss_5311_open;
860 gnss_info.gnss_close = gnss_5311_close;
861 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
862 gnss_info.gnss_dl_read_cb = NULL;
863 gnss_info.gnss_set = gnss_5311_set;
864 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu8f231a12024-05-31 17:55:06 +0800865 } else {
866 LOGE("No support : %s", argv[1]);
867 return -1;
868 }
869
870 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
871 // Auto open gnss.
872 if(gnss_info.auto_open) {
873 if(gnss_init(0)) { // No print to any port.
874 LOGE("gnss_init() fail.");
875 return -1;
876 }
877 }
878
879 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +0800880#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +0800881 if(gnss_ubus_init()) {
882 LOGD("main() run...");
883 uloop_run();
884 } else {
885 LOGE("gnss_ubus_init() fail.");
886 }
b.liu5f950c52024-06-15 20:13:12 +0800887#else
888 if(!gnss_ipc_service_start()) {
889 LOGD("main() run...");
890 while(1) {
891 sleep(24 * 60 * 60);
892 }
893 } else {
894 LOGE("gnss_ipc_service_start() fail.");
895 }
896#endif
b.liu8f231a12024-05-31 17:55:06 +0800897
898 LOGD("main() exit.");
899 return 0;
900}