blob: a20b75e91395825c6d1a1b6a2ee78564ebad1b4c [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.liu8f231a12024-05-31 17:55:06 +080012
13#include "mbtk_type.h"
14#include "mbtk_log.h"
15#include "gnss_info.h"
b.liu778645e2024-06-21 16:47:42 +080016#include "gnss_utils.h"
b.liu8f231a12024-05-31 17:55:06 +080017#include "gnss_6228.h"
b.liuf9fbfa12024-06-14 15:53:59 +080018#include "gnss_hd8122.h"
b.liu99c645d2024-06-20 10:52:15 +080019#include "gnss_asr5311.h"
20
b.liu8f231a12024-05-31 17:55:06 +080021
22#define GNSS_DEBUG 1
b.liud0ba7152024-06-19 14:47:21 +080023#define GNSS_UBUS_ENABLE 1
b.liu8f231a12024-05-31 17:55:06 +080024
25#define GNSS_TAG "MBTK_GNSS"
26#define GNSS_BUFF_SIZE 2048
27#define MBTK_PROP_GNSS_LOG "persist.mbtk.gnss_log_enable"
28#define GNSS_PORT_PTY "/dev/tty_gnss_nmea"
29#define GNSS_PORT_USB_AT "/dev/ttyGS0"
30#define GNSS_PORT_USB_NMEA "/dev/ttymodem0"
31#define GNSS_PORT_UART_AT "/dev/ttyS1"
32
33#ifdef GNSS_DEBUG
34#define GNSS_NMEA_FILE_LOG "/tmp/mbtk_gnss_nmea.log"
b.liu8f231a12024-05-31 17:55:06 +080035#define GNSS_FILE_LOG "/tmp/mbtk_gnss.log"
b.liu99c645d2024-06-20 10:52:15 +080036#define GNSS_FILE_LOG_MAX 104857600 // 100MB
b.liu8f231a12024-05-31 17:55:06 +080037#endif
38
39gnss_info_t gnss_info;
40
b.liud0ba7152024-06-19 14:47:21 +080041#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080042struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080043#else
44int gnss_ipc_service_start();
45#endif
46
b.liu8f231a12024-05-31 17:55:06 +080047int gnss_init_config(int fd);
48
b.liud0ba7152024-06-19 14:47:21 +080049static char nmea_buff[GNSS_BUFF_SIZE*2] = {0};
50static char data_buff[GNSS_BUFF_SIZE] = {0};
51static uint32 nmea_buff_len = 0;
52static uint32 data_buff_len = 0;
53
b.liu8f231a12024-05-31 17:55:06 +080054static bool nmea_found = FALSE;
55#ifdef GNSS_DEBUG
56static bool nmea_log_enable = FALSE;
57static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080058static int debug_fd = -1;
59static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080060#endif
61static int gnss_pty_master_fd = -1;
62static int gnss_pty_slave_fd = -1;
63static int gnss_usb_at_port_fd = -1;
64static int gnss_usb_nmea_port_fd = -1;
65static int gnss_uart_at_port_fd = -1;
66static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
67
68static void help()
69{
b.liu99c645d2024-06-20 10:52:15 +080070 LOGD("mbtk_gnssd <6228/8122/5311> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080071}
72
73static int arg_check(int argc, char *argv[])
74{
75 if(argc != 4) {
76 goto check_fail;
77 }
78
b.liu99c645d2024-06-20 10:52:15 +080079 // Only support 6228/8122/5311.
80 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 +080081 goto check_fail;
82 }
83
84 if(access(argv[2], R_OK | W_OK)) {
85 goto check_fail;
86 }
87
88 if(strcmp(argv[3], "0") && strcmp(argv[3], "1")) {
89 goto check_fail;
90 }
91
92 return 0;
93check_fail:
94 help();
95 return -1;
96}
97
98static int gnss_ports_open(uint32 print_port)
99{
100 if(print_port & GNSS_PRINT_PORT_TTY_AT) {
101 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
b.liudbc3f4b2024-06-25 18:22:24 +0800102 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800103 }
104 LOGD("Open PTY port success.");
105 }
106
107 if(print_port & GNSS_PRINT_PORT_USB_AT) {
108 if((gnss_usb_at_port_fd = gnss_port_open(GNSS_PORT_USB_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
b.liudbc3f4b2024-06-25 18:22:24 +0800109 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800110 }
111 LOGD("Open USB AT port success.");
112 }
113
114 if(print_port & GNSS_PRINT_PORT_USB_NMEA) {
115 if((gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
b.liudbc3f4b2024-06-25 18:22:24 +0800116 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800117 }
118 LOGD("Open USB NMEA port success.");
119 }
120
121 if(print_port & GNSS_PRINT_PORT_UART1) {
122 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
b.liudbc3f4b2024-06-25 18:22:24 +0800123 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800124 }
125 LOGD("Open UART AT port success.");
126 }
127
b.liudbc3f4b2024-06-25 18:22:24 +0800128 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800129}
130
131static int gnss_ports_close()
132{
133 if(gnss_usb_at_port_fd > 0) {
134 close(gnss_usb_at_port_fd);
135 gnss_usb_at_port_fd = -1;
136 }
137
138 if(gnss_usb_nmea_port_fd > 0) {
139 close(gnss_usb_nmea_port_fd);
140 gnss_usb_nmea_port_fd = -1;
141 }
142
143 if(gnss_uart_at_port_fd > 0) {
144 close(gnss_uart_at_port_fd);
145 gnss_uart_at_port_fd = -1;
146 }
147
148 if(gnss_pty_master_fd > 0) {
149 close(gnss_pty_master_fd);
150 gnss_pty_master_fd = -1;
151 }
152
153 if(gnss_pty_slave_fd > 0) {
154 close(gnss_pty_slave_fd);
155 gnss_pty_slave_fd = -1;
156 unlink(GNSS_PORT_PTY);
157 }
158
159 return 0;
160}
161
b.liu8f231a12024-05-31 17:55:06 +0800162#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800163static void log_save(int fd, const char *data, int data_len)
164{
b.liu8f231a12024-05-31 17:55:06 +0800165 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800166 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
167 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
168 close(debug_fd);
169 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
170 if(debug_fd < 0) {
171 LOGE("Open debug fd fail.");
172 }
173 debug_fd_len = 0;
174
175 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800176 close(nmea_log_fd);
177 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
178 if(nmea_log_fd < 0) {
179 LOGE("Open debug fd fail.");
180 }
b.liu8f231a12024-05-31 17:55:06 +0800181 }
182
b.liu99c645d2024-06-20 10:52:15 +0800183 if(fd == nmea_log_fd) {
184 if(nmea_log_fd > 0) {
185 write(nmea_log_fd, data, data_len);
186 debug_fd_len += data_len;
187 }
188 } else if(fd == debug_fd) {
189 if(debug_fd > 0) {
190 write(debug_fd, data, data_len);
191 debug_fd_len += data_len;
192 }
b.liu8f231a12024-05-31 17:55:06 +0800193 }
194 }
b.liu99c645d2024-06-20 10:52:15 +0800195}
b.liu8f231a12024-05-31 17:55:06 +0800196#endif
197
b.liu99c645d2024-06-20 10:52:15 +0800198static void nmea_print(const char *nmea, int nmea_len)
199{
b.liu8f231a12024-05-31 17:55:06 +0800200 if(gnss_usb_at_port_fd > 0) {
201 write(gnss_usb_at_port_fd, nmea, nmea_len);
202 }
203
204 if(gnss_usb_nmea_port_fd > 0) {
205 write(gnss_usb_nmea_port_fd, nmea, nmea_len);
206 }
207
208 if(gnss_uart_at_port_fd > 0) {
209 write(gnss_uart_at_port_fd, nmea, nmea_len);
210 }
211
212 if(gnss_pty_master_fd > 0) {
213 write(gnss_pty_master_fd, nmea, nmea_len);
214 }
215}
216
217static unsigned char nmea_checksum(const char *nmea)
218{
219 const char *p = nmea;
220 unsigned char chs = 0;
221
222 while (*p == '$') // skip '$'
223 p++;
224 while (*p != '*' && *p != 0)
225 chs ^= *p++;
226
227 return chs;
228}
229
230static bool nmea_check(const char *nmea, int nmea_len)
231{
232 char **ptr = gnss_filter_info;
233 while(*ptr) {
234 if(strstr(nmea, *ptr)) {
235 break;
236 }
237 ptr++;
238 }
239
240 if(*ptr == NULL) {
241 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
242 return FALSE;
243 }
244
245 char *checksum_str = strstr(nmea, "*");
246 checksum_str++; // Jump '*'
247 char checksum_buf[3] = {0};
248 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
249 if(strncasecmp(checksum_buf, checksum_str, 2)) {
250 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
251 return FALSE;
252 }
253
254 return TRUE;
255}
256
257static void gnss_nmea_process(const char *data, int data_len)
258{
b.liu99c645d2024-06-20 10:52:15 +0800259 // LOGD("gnss_nmea_process() : data_len - %d", data_len);
260#if 0
b.liu8f231a12024-05-31 17:55:06 +0800261 char nmea[GNSS_BUFF_SIZE] = {0};
262 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800263#else
264 const char *nmea = data;
265#endif
b.liu8f231a12024-05-31 17:55:06 +0800266
267 if(!nmea_check(nmea, data_len)) {
b.liu99c645d2024-06-20 10:52:15 +0800268 LOGD("NO-NMEA:%s", nmea);
269#if GNSS_DEBUG
270 log_save(nmea_log_fd, "/**/", 4);
271 log_save(nmea_log_fd, nmea, data_len);
272#endif
273 if(gnss_info.gnss_set_cb)
274 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800275 return;
276 }
277
278#ifdef GNSS_DEBUG
279 if(nmea_log_enable) {
280 LOGD("NMEA[%d]:%s", data_len, nmea);
281 }
b.liu99c645d2024-06-20 10:52:15 +0800282
283 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800284#endif
285
286 nmea_print(nmea, data_len);
287}
288
289#if 0
290static void gnss_cmd_rsp_process(const char *data, int data_len)
291{
292 char rsp[GNSS_BUFF_SIZE] = {0};
293 memcpy(rsp, data, data_len);
294 LOGD("RSP[%d]:%s", data_len, rsp);
295}
296#endif
297
298static bool nmea_char_check(char ch)
299{
300 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
b.liu99c645d2024-06-20 10:52:15 +0800301 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=')
b.liu8f231a12024-05-31 17:55:06 +0800302 return TRUE;
303
304 return FALSE;
305}
306
307static void gnss_data_process(const char *data, int data_len)
308{
309 if(gnss_info.state == GNSS_STATE_OPEN) {
310 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
311 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
312 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800313 if(gnss_info.gnss_dl_read_cb) {
314 gnss_info.gnss_dl_read_cb(data, data_len);
315 }
b.liu8f231a12024-05-31 17:55:06 +0800316 } else if(gnss_info.state == GNSS_STATE_READY) {
317 int index = 0;
318 while(index < data_len) {
319 if(nmea_found) {
320 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800321 // Copy nmea_buff to data_buff
322 // Start with '$', but not nmea data, so copy to data_buff.
323 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
324 data_buff_len += nmea_buff_len;
325 data_buff[data_buff_len++] = data[index];
326
327 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800328 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800329 continue;
330 }
331
332 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800333 nmea_buff[nmea_buff_len++] = data[index];
334 if(nmea_buff[nmea_buff_len - 1] == '\n') {
335 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800336#if GNSS_DEBUG
337 log_save(nmea_log_fd, "/**/", 4);
338 log_save(nmea_log_fd, data_buff, data_buff_len);
339#endif
340 if(gnss_info.gnss_set_cb) {
341 gnss_info.gnss_set_cb(data_buff, data_buff_len);
342 }
b.liud0ba7152024-06-19 14:47:21 +0800343 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800344 }
345
b.liud0ba7152024-06-19 14:47:21 +0800346 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800347 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800348 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800349 } else if(nmea_buff_len > 0) {
350 nmea_buff[nmea_buff_len] = '\0';
351 LOGD("NO-NMEA:%s", nmea_buff);
352#if GNSS_DEBUG
353 log_save(nmea_log_fd, "/**/", 4);
354 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
355#endif
b.liud0ba7152024-06-19 14:47:21 +0800356 }
357
358 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800359 nmea_found = FALSE;
360 }
361 }
362 } else {
363 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800364 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800365 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800366 nmea_buff[nmea_buff_len++] = data[index];
367 } else {
368 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800369 }
370 }
371 index++;
372 }
373 } else {
374 LOGW("Unknown state : %d", gnss_info.state);
375 }
376}
377
378void* gnss_read_pthread(void* arg)
379{
380 LOGD("gnss_read_pthread enter.");
381 char buffer[GNSS_BUFF_SIZE];
382 int len = 0;
383 int ret = 0;
384 fd_set fdr, fdw;
385 int fd_max = 0;
386
387 FD_ZERO(&fdw);
388 FD_ZERO(&fdr);
389 FD_SET(gnss_info.fd, &fdr);
390 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
391 FD_SET(gnss_info.exit_fd[0], &fdr);
392 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800393 memset(nmea_buff, 0, sizeof(nmea_buff));
394 memset(data_buff, 0, sizeof(data_buff));
395 nmea_buff_len = 0;
396 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800397#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800398 if(nmea_log_enable) {
399 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
400 if(debug_fd < 0) {
401 LOGE("Open debug fd fail.");
402 }
403 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
404 if(nmea_log_fd < 0) {
405 LOGE("Open nmea fd fail.");
406 }
b.liu99c645d2024-06-20 10:52:15 +0800407 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800408 }
409#endif
410
b.liudbc3f4b2024-06-25 18:22:24 +0800411 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
412
b.liu8f231a12024-05-31 17:55:06 +0800413 while(gnss_info.state >= GNSS_STATE_OPEN) {
414 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
415 //LOGD("select - %d", ret);
416 if (ret < 0)
417 {
418 if (errno == EINTR)
419 {
420 continue;
421 }
422 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
423 break;
424 }
425 else if (ret == 0)
426 {
427 LOGE("select ret == 0");
428 break;
429 }
430
431 if (FD_ISSET(gnss_info.fd, &fdr))
432 {
433 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800434 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800435 if(len > 0) {
436 //log_hex("READ", buffer, len);
437
438#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800439 //LOGD("read data_len = %d", len);
440 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800441#endif
442
443 gnss_data_process(buffer, len);
444
445 } else if(len ==0 ){
446 LOGE("Read end : len = 0");
447 break;
448 } else {
449 if(EAGAIN == errno) {
450 usleep(50000);
451 continue;
452 } else {
453 LOGD("Read ret = -1 ,errno = %d", errno);
454 break;
455 }
456 }
457 }
458 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
459 {
460 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800461 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800462 if(len > 0) {
463 if(strcmp(buffer, "exit") == 0) {
464 LOGD("Get thread exit message.");
465 break;
466 }
467 }
468 }
469 else
470 {
471 LOGW("Unknown select event.");
472 continue;
473 }
474 }
475
476#if GNSS_DEBUG
477 if(debug_fd > 0) {
478 close(debug_fd);
479 debug_fd = -1;
480 }
481 if(nmea_log_fd > 0) {
482 close(nmea_log_fd);
483 nmea_log_fd = -1;
484 }
485#endif
486
487 gnss_info.state = GNSS_STATE_CLOSE;
488 LOGD("gnss_read_pthread exit.");
489 return NULL;
490}
491
492#if 0
493int gnss_write(int fd, const void *data, int data_len)
494{
495 int count = 0;
496 int len = 0;
497 while(1)
498 {
499 len = write(fd, data + count, data_len - count);
500 if (len > 0)
501 {
502 count += len;
503 }
504 else
505 {
506 LOGE("write() fail,ret = %d,errno = %d", len, errno);
507 break;
508 }
509
510 if (count == data_len)
511 break;
512 }
513
514 return count;
515}
516#else
b.liu778645e2024-06-21 16:47:42 +0800517int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800518{
b.liu778645e2024-06-21 16:47:42 +0800519 ssize_t size;
520 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800521 ssize_t size_written;
522 if(GNSS_BUFF_SIZE < buf_len)
523 {
524 return -1;
525 }
526 for(size = 0; size < buf_len;)
527 {
528 size_to_wr = buf_len - size;
529 if( size_to_wr > GNSS_BUFF_SIZE)
530 size_to_wr = GNSS_BUFF_SIZE;
531
b.liu778645e2024-06-21 16:47:42 +0800532 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800533 if (size_written==-1)
534 {
535 return -1;
536 }
537 size += size_written;
538 if(size_written != size_to_wr)
539 {
540 return size;
541 }
542 }
543 // LOGD("SEND %d / %d", size, buf_len);
544 return size;
545}
546#endif
547
548int gnss_init(uint32 print_port)
549{
550 if(gnss_info.state != GNSS_STATE_CLOSE) {
551 LOGW("GNSS not close:%d", gnss_info.state);
b.liudbc3f4b2024-06-25 18:22:24 +0800552 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800553 }
554
555 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800556 if(gnss_info.dl_befor_open) {
557 //if(gnss_info.auto_dl_fw) {
558 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800559 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800560 if(ret) {
561 LOGE("gnss_fw_dl() fail : %d", ret);
562 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800563 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800564 }
b.liu8f231a12024-05-31 17:55:06 +0800565
b.liu99c645d2024-06-20 10:52:15 +0800566 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
567 if(gnss_info.fd <= 0) {
568 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
569 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800570 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800571 }
572 if(pipe(gnss_info.exit_fd)) {
573 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800574 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800575 }
576 // GNSS is opened.
577 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800578
b.liu99c645d2024-06-20 10:52:15 +0800579#if 0
580 // Start gnss read thread.
581 pthread_attr_t thread_attr;
582 pthread_attr_init(&thread_attr);
583 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
584 {
585 LOGE("pthread_attr_setdetachstate() fail.");
586 goto main_exit;
587 }
b.liu8f231a12024-05-31 17:55:06 +0800588
b.liu99c645d2024-06-20 10:52:15 +0800589 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800590#else
b.liu99c645d2024-06-20 10:52:15 +0800591 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800592#endif
b.liu99c645d2024-06-20 10:52:15 +0800593 {
594 LOGE("pthread_create() fail.");
595 goto exit_with_close;
596 }
b.liu8f231a12024-05-31 17:55:06 +0800597
b.liu99c645d2024-06-20 10:52:15 +0800598 ret = gnss_info.gnss_dev_open();
599 if(ret) {
600 LOGE("gnss_dev_open() fail : %d", ret);
601 goto exit_with_thread_exit;
602 }
603 //}
604 } else {
605 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
606 if(gnss_info.fd <= 0) {
607 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
608 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800609 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800610 }
611 if(pipe(gnss_info.exit_fd)) {
612 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800613 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800614 }
615 // GNSS is opened.
616 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800617
b.liu99c645d2024-06-20 10:52:15 +0800618#if 0
619 // Start gnss read thread.
620 pthread_attr_t thread_attr;
621 pthread_attr_init(&thread_attr);
622 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
623 {
624 LOGE("pthread_attr_setdetachstate() fail.");
625 goto main_exit;
626 }
627
628 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
629#else
630 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
631#endif
632 {
633 LOGE("pthread_create() fail.");
634 goto exit_with_close;
635 }
636
637 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800638 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800639 LOGE("gnss_dev_open() fail : %d", ret);
640 goto exit_with_thread_exit;
641 }
b.liu8f231a12024-05-31 17:55:06 +0800642 }
643
644 // GNSS is ready, NMEA can print from uart.
645 gnss_info.state = GNSS_STATE_READY;
646 gnss_info.print_port = print_port;
647
648 LOGD("GNSS open success.");
649
650 return gnss_ports_open(gnss_info.print_port);
651
652exit_with_dev_close:
653 if(gnss_info.gnss_dev_close()) {
654 LOGE("gnss_dev_close() fail.");
655 }
656exit_with_thread_exit:
657 gnss_info.state = GNSS_STATE_CLOSING;
658 // Wait for read thread exit.
659 ret = pthread_join(gnss_info.read_pid, NULL);
660 if(ret){
661 LOGE("pthrad_join fail(%d)",ret);
662 }
663exit_with_close:
664 if(gnss_info.gnss_close(gnss_info.fd)) {
665 LOGE("gnss_close() fail.");
666 }
667 if(gnss_info.exit_fd[0] > 0) {
668 close(gnss_info.exit_fd[0]);
669 gnss_info.exit_fd[0] = -1;
670 }
671 if(gnss_info.exit_fd[1] > 0) {
672 close(gnss_info.exit_fd[1]);
673 gnss_info.exit_fd[1] = -1;
674 }
675 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800676 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800677}
678
679int gnss_deinit()
680{
681 if(gnss_info.state == GNSS_STATE_CLOSE) {
682 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +0800683 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800684 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
685 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +0800686 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800687 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
688 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +0800689 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800690 }
691
692 // Wait for read thread exit.
693 if(gnss_info.exit_fd[1] > 0) {
694 write(gnss_info.exit_fd[1], "exit", 4);
695 }
696
697 gnss_info.state = GNSS_STATE_CLOSING;
698 int ret = pthread_join(gnss_info.read_pid, NULL);
699 if(ret){
700 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +0800701 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800702 }
703
704 if(gnss_info.gnss_close(gnss_info.fd)) {
705 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800706 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800707 }
708
709 if(gnss_info.gnss_dev_close()) {
710 LOGE("gnss_dev_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800711 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800712 }
713
714 if(gnss_ports_close()) {
715 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800716 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800717 }
718
b.liud0ba7152024-06-19 14:47:21 +0800719 LOGD("gnss_ports_close() complete.");
720
b.liu8f231a12024-05-31 17:55:06 +0800721 gnss_info.fd = -1;
722 if(gnss_info.exit_fd[0] > 0) {
723 close(gnss_info.exit_fd[0]);
724 gnss_info.exit_fd[0] = -1;
725 }
726 if(gnss_info.exit_fd[1] > 0) {
727 close(gnss_info.exit_fd[1]);
728 gnss_info.exit_fd[1] = -1;
729 }
730 gnss_info.state = GNSS_STATE_CLOSE;
731 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +0800732 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800733}
734
735int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
736{
b.liud0ba7152024-06-19 14:47:21 +0800737 if(buf && buf_len > 0) {
738 if(cmd_rsp && cmd_rsp_len > 0) {
739 memset(cmd_rsp, 0, cmd_rsp_len);
740 }
b.liu8f231a12024-05-31 17:55:06 +0800741 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
742 } else {
b.liudbc3f4b2024-06-25 18:22:24 +0800743 return GNSS_ERR_UNKNOWN;
744 }
745}
746
747int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
748{
749 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
750 return GNSS_ERR_UNSUPPORT;
751 }
752
753 if(rsp && rsp_len > 0) {
754 memset(rsp, 0, rsp_len);
755 }
756
757 if(gnss_info.gnss_fw_dl) {
758 if(GNSS_ERR_OK != gnss_deinit()) {
759 LOGE("Close gnss fail.");
760 return GNSS_ERR_UNKNOWN;
761 } else {
762 LOGD("Start gnss fw dl.");
763 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
764 }
765 } else {
766 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800767 }
768}
769
770static void sig_process(int sig)
771{
772 LOGI("I got signal %d\n", sig);
773 if(gnss_deinit()) {
774 LOGE("gnss_deinit() fail, no exist...");
775 return;
776 }
777
778 switch(sig)
779 {
780 case SIGINT: // Ctrl + C
781 {
782 LOGI("Exit by SIGINT.\n");
783 exit(0);
784 }
785 case SIGQUIT: // Ctrl + \ (ÀàËÆ SIGINT £¬µ«Òª²úÉúcoreÎļþ)
786 {
787 LOGI("Exit by SIGQUIT.\n");
788 exit(0);
789 }
790 case SIGTERM:// ĬÈÏkill (ͬ SIGKILL £¬µ« SIGKILL ²»¿É²¶»ñ)
791 {
792 LOGI("Exit by SIGTERM.\n");
793 exit(0);
794 }
795 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP £¬µ« SIGSTOP ²»¿É²¶»ñ)
796 {
797 LOGI("Exit by SIGTSTP.\n");
798 exit(0);
799 }
800 case SIGSEGV: // Èç¿ÕÖ¸Õë
801 {
802 LOGI("Exit by SIGSEGV.\n");
803 exit(0);
804 }
805 default:
806 {
807 LOGI("Unknown sig:%d\n",sig);
808 break;
809 }
810 }
811}
812
813
814// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1
815int main(int argc, char *argv[])
816{
817 mbtk_log_init("radio", GNSS_TAG);
818
b.liubb590492024-06-13 16:42:08 +0800819#ifdef MBTK_DUMP_SUPPORT
820 mbtk_debug_open(NULL, TRUE);
821#endif
822
b.liu8f231a12024-05-31 17:55:06 +0800823 signal(SIGINT, sig_process);
824 signal(SIGQUIT, sig_process);
825 signal(SIGTERM, sig_process);
826
827 if(arg_check(argc, argv)) {
828 return -1;
829 }
830
831#ifdef GNSS_DEBUG
832 char buff[10];
833 memset(buff, 0, 10);
834 property_get(MBTK_PROP_GNSS_LOG, buff, "");
835 if(strlen(buff) > 0 && atoi(buff) > 0) {
836 nmea_log_enable = TRUE;
837 }
838#endif
839
840 memset(&gnss_info, 0, sizeof(gnss_info_t));
841 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
842 gnss_info.state = GNSS_STATE_CLOSE;
843 if(!strcmp(argv[1], GNSS_ID_6228)) {
844 gnss_info.gnss_id = GNSS_TYPE_6228;
845 gnss_info.auto_open = (bool)atoi(argv[3]);
846 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +0800847 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800848 gnss_info.gnss_dev_open = gnss_6228_dev_open;
849 gnss_info.gnss_dev_close = gnss_6228_dev_close;
850 gnss_info.gnss_open = gnss_6228_open;
851 gnss_info.gnss_close = gnss_6228_close;
852 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
853 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
854 gnss_info.gnss_set = gnss_6228_set;
855 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +0800856 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
857 gnss_info.gnss_id = GNSS_TYPE_8122;
858 gnss_info.auto_open = (bool)atoi(argv[3]);
859 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +0800860 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +0800861 gnss_info.gnss_dev_open = gnss_8122_dev_open;
862 gnss_info.gnss_dev_close = gnss_8122_dev_close;
863 gnss_info.gnss_open = gnss_8122_open;
864 gnss_info.gnss_close = gnss_8122_close;
865 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
866 gnss_info.gnss_dl_read_cb = NULL;
867 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +0800868 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +0800869 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
870 gnss_info.gnss_id = GNSS_TYPE_5311;
871 gnss_info.auto_open = (bool)atoi(argv[3]);
872 gnss_info.auto_dl_fw = TRUE;
873 gnss_info.dl_befor_open = TRUE;
874 gnss_info.gnss_dev_open = gnss_5311_dev_open;
875 gnss_info.gnss_dev_close = gnss_5311_dev_close;
876 gnss_info.gnss_open = gnss_5311_open;
877 gnss_info.gnss_close = gnss_5311_close;
878 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
879 gnss_info.gnss_dl_read_cb = NULL;
880 gnss_info.gnss_set = gnss_5311_set;
881 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu8f231a12024-05-31 17:55:06 +0800882 } else {
883 LOGE("No support : %s", argv[1]);
884 return -1;
885 }
886
887 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
888 // Auto open gnss.
889 if(gnss_info.auto_open) {
890 if(gnss_init(0)) { // No print to any port.
891 LOGE("gnss_init() fail.");
892 return -1;
893 }
894 }
895
896 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +0800897#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +0800898 if(gnss_ubus_init()) {
899 LOGD("main() run...");
900 uloop_run();
901 } else {
902 LOGE("gnss_ubus_init() fail.");
903 }
b.liu5f950c52024-06-15 20:13:12 +0800904#else
905 if(!gnss_ipc_service_start()) {
906 LOGD("main() run...");
907 while(1) {
908 sleep(24 * 60 * 60);
909 }
910 } else {
911 LOGE("gnss_ipc_service_start() fail.");
912 }
913#endif
b.liu8f231a12024-05-31 17:55:06 +0800914
915 LOGD("main() exit.");
916 return 0;
917}