blob: 0fc37d0acbba865459aa33e78dd03cf87f4257d3 [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"
yq.wang069ea922024-09-08 19:29:35 -070022#include "gnss_log.h"
b.liu8f231a12024-05-31 17:55:06 +080023
24#define GNSS_DEBUG 1
b.liud0ba7152024-06-19 14:47:21 +080025#define GNSS_UBUS_ENABLE 1
b.liu8f231a12024-05-31 17:55:06 +080026
27#define GNSS_TAG "MBTK_GNSS"
28#define GNSS_BUFF_SIZE 2048
29#define MBTK_PROP_GNSS_LOG "persist.mbtk.gnss_log_enable"
30#define GNSS_PORT_PTY "/dev/tty_gnss_nmea"
31#define GNSS_PORT_USB_AT "/dev/ttyGS0"
32#define GNSS_PORT_USB_NMEA "/dev/ttymodem0"
33#define GNSS_PORT_UART_AT "/dev/ttyS1"
b.liue77ac3a2024-07-17 17:36:57 +080034#define GNSS_CLI_IND_MAX 10
b.liu8f231a12024-05-31 17:55:06 +080035
36#ifdef GNSS_DEBUG
37#define GNSS_NMEA_FILE_LOG "/tmp/mbtk_gnss_nmea.log"
b.liu8f231a12024-05-31 17:55:06 +080038#define GNSS_FILE_LOG "/tmp/mbtk_gnss.log"
b.liu99c645d2024-06-20 10:52:15 +080039#define GNSS_FILE_LOG_MAX 104857600 // 100MB
b.liu8f231a12024-05-31 17:55:06 +080040#endif
41
b.liua1b69262024-09-04 16:32:59 +080042#define MBTK_GNSS_PTY_AUTO_INIT 1
43
b.liubcf86c92024-08-19 19:48:28 +080044gnss_info_t gnss_info;
b.liu8f231a12024-05-31 17:55:06 +080045
b.liud0ba7152024-06-19 14:47:21 +080046#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080047struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080048#else
49int gnss_ipc_service_start();
50#endif
51
b.liu8f231a12024-05-31 17:55:06 +080052int gnss_init_config(int fd);
53
wangyouqiangfa897f82024-06-27 09:44:55 +080054static char nmea_buff[GNSS_BUFF_SIZE*4] = {0};
55static char data_buff[GNSS_BUFF_SIZE*4] = {0};
b.liud0ba7152024-06-19 14:47:21 +080056static uint32 nmea_buff_len = 0;
57static uint32 data_buff_len = 0;
b.liue77ac3a2024-07-17 17:36:57 +080058static gnss_ind_info_t ind_info[GNSS_CLI_IND_MAX];
b.liud0ba7152024-06-19 14:47:21 +080059
b.liu8f231a12024-05-31 17:55:06 +080060static bool nmea_found = FALSE;
61#ifdef GNSS_DEBUG
62static bool nmea_log_enable = FALSE;
63static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080064static int debug_fd = -1;
65static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080066#endif
yq.wang5c647e02024-08-10 00:01:11 -070067
b.liua1b69262024-09-04 16:32:59 +080068#if MBTK_GNSS_PTY_AUTO_INIT
69static bool gnss_pty_print_enable = FALSE;
70#endif
b.liu8f231a12024-05-31 17:55:06 +080071static int gnss_pty_master_fd = -1;
72static int gnss_pty_slave_fd = -1;
73static int gnss_usb_at_port_fd = -1;
74static int gnss_usb_nmea_port_fd = -1;
75static int gnss_uart_at_port_fd = -1;
76static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
77
b.liue77ac3a2024-07-17 17:36:57 +080078int gnss_write(int fd, const void* buf, int buf_len);
79
b.liu8f231a12024-05-31 17:55:06 +080080static void help()
81{
b.liu42f558e2024-07-18 14:06:49 +080082 LOGD("mbtk_gnssd <6228/8122/5311/N50DB> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080083}
84
85static int arg_check(int argc, char *argv[])
86{
87 if(argc != 4) {
b.liu4ae41182024-06-28 16:30:15 +080088 LOGE("argc = %d", argc);
b.liu8f231a12024-05-31 17:55:06 +080089 goto check_fail;
90 }
91
b.liu99c645d2024-06-20 10:52:15 +080092 // Only support 6228/8122/5311.
b.liu42f558e2024-07-18 14:06:49 +080093 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)
94 && strcmp(argv[1], GNSS_ID_N50DB)) {
b.liu4ae41182024-06-28 16:30:15 +080095 LOGE("argv[1] = %s", argv[1]);
b.liu8f231a12024-05-31 17:55:06 +080096 goto check_fail;
97 }
98
99 if(access(argv[2], R_OK | W_OK)) {
b.liu4ae41182024-06-28 16:30:15 +0800100 LOGE("access(%s) rw fail. ", argv[2]);
b.liu8f231a12024-05-31 17:55:06 +0800101 goto check_fail;
102 }
103
b.liuced8dd02024-06-28 13:28:29 +0800104#if 0
105 int init_mode = atoi(argv[3]);
106 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 +0800107 goto check_fail;
108 }
b.liuced8dd02024-06-28 13:28:29 +0800109#endif
b.liu8f231a12024-05-31 17:55:06 +0800110
111 return 0;
112check_fail:
113 help();
114 return -1;
115}
116
117static int gnss_ports_open(uint32 print_port)
118{
b.liuced8dd02024-06-28 13:28:29 +0800119 // TTY AT change.
120 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
121 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
b.liua1b69262024-09-04 16:32:59 +0800122#if MBTK_GNSS_PTY_AUTO_INIT
123 gnss_pty_print_enable = TRUE;
124#else
b.liuced8dd02024-06-28 13:28:29 +0800125 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
126 return GNSS_ERR_OPEN_DEV;
127 }
b.liua1b69262024-09-04 16:32:59 +0800128#endif
b.liuced8dd02024-06-28 13:28:29 +0800129 LOGD("Open PTY port success.");
130 } else { // Close
b.liua1b69262024-09-04 16:32:59 +0800131#if MBTK_GNSS_PTY_AUTO_INIT
132 gnss_pty_print_enable = FALSE;
133#else
b.liuced8dd02024-06-28 13:28:29 +0800134 if(gnss_pty_slave_fd > 0) {
135 close(gnss_pty_slave_fd);
136 gnss_pty_slave_fd = -1;
137 unlink(GNSS_PORT_PTY);
138 }
b.liua1b69262024-09-04 16:32:59 +0800139#endif
b.liuced8dd02024-06-28 13:28:29 +0800140 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800141 }
b.liu8f231a12024-05-31 17:55:06 +0800142 }
143
b.liuced8dd02024-06-28 13:28:29 +0800144 // USB AT change.
145 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
146 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
b.liu978f5432024-07-01 18:04:18 +0800147 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 +0800148 return GNSS_ERR_OPEN_DEV;
149 }
150 LOGD("Open USB AT port success.");
151 } else { // Close
152 if(gnss_usb_at_port_fd > 0) {
153 close(gnss_usb_at_port_fd);
154 gnss_usb_at_port_fd = -1;
155 }
156 LOGD("Close USB AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800157 }
b.liu8f231a12024-05-31 17:55:06 +0800158 }
159
b.liuced8dd02024-06-28 13:28:29 +0800160 // USB NMEA change.
161 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
162 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
b.liu978f5432024-07-01 18:04:18 +0800163 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 +0800164 return GNSS_ERR_OPEN_DEV;
165 }
166 LOGD("Open USB NMEA port success.");
167 } else { // Close
168 if(gnss_usb_nmea_port_fd > 0) {
169 close(gnss_usb_nmea_port_fd);
170 gnss_usb_nmea_port_fd = -1;
171 }
172 LOGD("Close USB NMEA port success.");
b.liu8f231a12024-05-31 17:55:06 +0800173 }
b.liu8f231a12024-05-31 17:55:06 +0800174 }
175
b.liuced8dd02024-06-28 13:28:29 +0800176 // Uart AT change.
177 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
178 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
179 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
180 return GNSS_ERR_OPEN_DEV;
181 }
182 LOGD("Open UART AT port success.");
183 } else { // Close
184 if(gnss_uart_at_port_fd > 0) {
185 close(gnss_uart_at_port_fd);
186 gnss_uart_at_port_fd = -1;
187 }
188 LOGD("Close UART AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800189 }
b.liu8f231a12024-05-31 17:55:06 +0800190 }
191
b.liuced8dd02024-06-28 13:28:29 +0800192 gnss_info.print_port = print_port;
193
b.liudbc3f4b2024-06-25 18:22:24 +0800194 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800195}
196
197static int gnss_ports_close()
198{
199 if(gnss_usb_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800200 tcflush(gnss_usb_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800201 close(gnss_usb_at_port_fd);
202 gnss_usb_at_port_fd = -1;
203 }
204
205 if(gnss_usb_nmea_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800206 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800207 close(gnss_usb_nmea_port_fd);
208 gnss_usb_nmea_port_fd = -1;
209 }
210
211 if(gnss_uart_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800212 tcflush(gnss_uart_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800213 close(gnss_uart_at_port_fd);
214 gnss_uart_at_port_fd = -1;
215 }
b.liua1b69262024-09-04 16:32:59 +0800216#if MBTK_GNSS_PTY_AUTO_INIT
217 gnss_pty_print_enable = FALSE;
218#else
b.liu8f231a12024-05-31 17:55:06 +0800219 if(gnss_pty_master_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800220 tcflush(gnss_pty_master_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800221 close(gnss_pty_master_fd);
222 gnss_pty_master_fd = -1;
223 }
224
225 if(gnss_pty_slave_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800226 tcflush(gnss_pty_slave_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800227 close(gnss_pty_slave_fd);
228 gnss_pty_slave_fd = -1;
229 unlink(GNSS_PORT_PTY);
230 }
b.liua1b69262024-09-04 16:32:59 +0800231#endif
b.liuced8dd02024-06-28 13:28:29 +0800232 gnss_info.print_port = 0;
233
b.liu8f231a12024-05-31 17:55:06 +0800234 return 0;
235}
236
b.liu8f231a12024-05-31 17:55:06 +0800237#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800238static void log_save(int fd, const char *data, int data_len)
239{
b.liu8f231a12024-05-31 17:55:06 +0800240 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800241 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
242 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
243 close(debug_fd);
244 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
245 if(debug_fd < 0) {
246 LOGE("Open debug fd fail.");
247 }
248 debug_fd_len = 0;
249
250 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800251 close(nmea_log_fd);
252 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
253 if(nmea_log_fd < 0) {
254 LOGE("Open debug fd fail.");
255 }
b.liu8f231a12024-05-31 17:55:06 +0800256 }
257
b.liu99c645d2024-06-20 10:52:15 +0800258 if(fd == nmea_log_fd) {
259 if(nmea_log_fd > 0) {
260 write(nmea_log_fd, data, data_len);
261 debug_fd_len += data_len;
262 }
263 } else if(fd == debug_fd) {
264 if(debug_fd > 0) {
265 write(debug_fd, data, data_len);
266 debug_fd_len += data_len;
267 }
b.liu8f231a12024-05-31 17:55:06 +0800268 }
269 }
b.liu99c645d2024-06-20 10:52:15 +0800270}
b.liu8f231a12024-05-31 17:55:06 +0800271#endif
272
b.liue77ac3a2024-07-17 17:36:57 +0800273static void ind_location_print(const char *data)
274{
275 int index = 0;
276 int buff_len = 0;
277 char buff[GNSS_BUFF_SIZE] = {0};
278 buff[0] = MBTK_IND_START_FLAG;
279 buff_len++;
280 memcpy(buff + 1, MBTK_IND_LOCATION_TAG, strlen(MBTK_IND_LOCATION_TAG));
281 buff_len += strlen(MBTK_IND_LOCATION_TAG);
282 memcpy(buff + strlen(buff), data, strlen(data));
283 buff_len += strlen(data);
284 buff[strlen(buff)] = MBTK_IND_END_FLAG;
285 buff_len++;
286
287 while(index < GNSS_CLI_IND_MAX) {
288 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_LOCATION)) {
289 gnss_write(ind_info[index].cli_fd, buff, buff_len);
290 }
291 index++;
292 }
293}
294
295static void ind_nmea_print(const char *data)
296{
297 int index = 0;
298 int buff_len = 0;
299 char buff[GNSS_BUFF_SIZE] = {0};
300 buff[0] = MBTK_IND_START_FLAG;
301 buff_len++;
302 memcpy(buff + 1, MBTK_IND_NMEA_TAG, strlen(MBTK_IND_NMEA_TAG));
303 buff_len += strlen(MBTK_IND_NMEA_TAG);
304 memcpy(buff + strlen(buff), data, strlen(data));
305 buff_len += strlen(data);
306 buff[strlen(buff)] = MBTK_IND_END_FLAG;
307 buff_len++;
308 while(index < GNSS_CLI_IND_MAX) {
309 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_NMEA)) {
310 gnss_write(ind_info[index].cli_fd, buff, buff_len);
311 }
312 index++;
313 }
314}
315
b.liu99c645d2024-06-20 10:52:15 +0800316static void nmea_print(const char *nmea, int nmea_len)
317{
yq.wang1ddd1fd2024-07-25 23:00:14 -0700318 int ret = -1;
b.liu8f231a12024-05-31 17:55:06 +0800319 if(gnss_usb_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700320 ret = write(gnss_usb_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800321 }
322
323 if(gnss_usb_nmea_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700324 ret = write(gnss_usb_nmea_port_fd, nmea, nmea_len);
yq.wang4b8ef892024-09-13 02:23:38 -0700325 if(ret < 0 && errno != EAGAIN) {
326 LOGE("gnss_port_fd write fail [errno = %d].", errno);
327 if(errno == EIO) {
328 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
329 close(gnss_usb_nmea_port_fd);
330 gnss_usb_nmea_port_fd = -1;
331 gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE);
332 }
333 }
b.liu8f231a12024-05-31 17:55:06 +0800334 }
335
336 if(gnss_uart_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700337 ret = write(gnss_uart_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800338 }
339
340 if(gnss_pty_master_fd > 0) {
b.liua1b69262024-09-04 16:32:59 +0800341#if MBTK_GNSS_PTY_AUTO_INIT
342 if(gnss_pty_print_enable) {
343 ret = write(gnss_pty_master_fd, nmea, nmea_len);
344 }
345#else
yq.wang1ddd1fd2024-07-25 23:00:14 -0700346 ret = write(gnss_pty_master_fd, nmea, nmea_len);
b.liua1b69262024-09-04 16:32:59 +0800347#endif
b.liu8f231a12024-05-31 17:55:06 +0800348 }
yq.wang937355d2024-07-26 01:24:42 -0700349 ind_nmea_print(nmea);
350 ind_location_print(nmea);
b.liu8f231a12024-05-31 17:55:06 +0800351}
352
353static unsigned char nmea_checksum(const char *nmea)
354{
355 const char *p = nmea;
356 unsigned char chs = 0;
357
358 while (*p == '$') // skip '$'
359 p++;
360 while (*p != '*' && *p != 0)
361 chs ^= *p++;
362
363 return chs;
364}
365
366static bool nmea_check(const char *nmea, int nmea_len)
367{
368 char **ptr = gnss_filter_info;
369 while(*ptr) {
370 if(strstr(nmea, *ptr)) {
371 break;
372 }
373 ptr++;
374 }
375
376 if(*ptr == NULL) {
377 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
378 return FALSE;
379 }
380
381 char *checksum_str = strstr(nmea, "*");
382 checksum_str++; // Jump '*'
383 char checksum_buf[3] = {0};
384 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
385 if(strncasecmp(checksum_buf, checksum_str, 2)) {
386 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
387 return FALSE;
388 }
389
390 return TRUE;
391}
392
393static void gnss_nmea_process(const char *data, int data_len)
394{
luojiand7960682024-08-02 16:50:01 +0800395// LOGD("gnss_nmea_process() : data_len - %d", data_len);
b.liu99c645d2024-06-20 10:52:15 +0800396#if 0
b.liu8f231a12024-05-31 17:55:06 +0800397 char nmea[GNSS_BUFF_SIZE] = {0};
398 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800399#else
400 const char *nmea = data;
401#endif
b.liu8f231a12024-05-31 17:55:06 +0800402
403 if(!nmea_check(nmea, data_len)) {
b.liu42f558e2024-07-18 14:06:49 +0800404 // No print "$HOSTSLEEP".
405 if(memcmp(nmea, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
406 LOGD("NO-NMEA:%s", nmea);
407 }
b.liu99c645d2024-06-20 10:52:15 +0800408#if GNSS_DEBUG
409 log_save(nmea_log_fd, "/**/", 4);
410 log_save(nmea_log_fd, nmea, data_len);
411#endif
412 if(gnss_info.gnss_set_cb)
413 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800414 return;
415 }
416
417#ifdef GNSS_DEBUG
418 if(nmea_log_enable) {
419 LOGD("NMEA[%d]:%s", data_len, nmea);
420 }
b.liu99c645d2024-06-20 10:52:15 +0800421
422 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800423#endif
424
yq.wang069ea922024-09-08 19:29:35 -0700425#if MBTK_GNSS_PARAM_PARSE
426 gnss_ind_nmea_parse(nmea, data_len);
427#endif
luojiand7960682024-08-02 16:50:01 +0800428
b.liu8f231a12024-05-31 17:55:06 +0800429 nmea_print(nmea, data_len);
430}
431
432#if 0
433static void gnss_cmd_rsp_process(const char *data, int data_len)
434{
435 char rsp[GNSS_BUFF_SIZE] = {0};
436 memcpy(rsp, data, data_len);
437 LOGD("RSP[%d]:%s", data_len, rsp);
438}
439#endif
440
441static bool nmea_char_check(char ch)
442{
443 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
yq.wang1ddd1fd2024-07-25 23:00:14 -0700444 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=' || ch == '-')
b.liu8f231a12024-05-31 17:55:06 +0800445 return TRUE;
446
447 return FALSE;
448}
449
450static void gnss_data_process(const char *data, int data_len)
451{
452 if(gnss_info.state == GNSS_STATE_OPEN) {
453 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
454 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
455 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800456 if(gnss_info.gnss_dl_read_cb) {
457 gnss_info.gnss_dl_read_cb(data, data_len);
458 }
b.liu8f231a12024-05-31 17:55:06 +0800459 } else if(gnss_info.state == GNSS_STATE_READY) {
460 int index = 0;
461 while(index < data_len) {
462 if(nmea_found) {
463 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800464 // Copy nmea_buff to data_buff
465 // Start with '$', but not nmea data, so copy to data_buff.
466 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
467 data_buff_len += nmea_buff_len;
468 data_buff[data_buff_len++] = data[index];
469
470 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800471 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800472 continue;
473 }
474
475 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800476 nmea_buff[nmea_buff_len++] = data[index];
477 if(nmea_buff[nmea_buff_len - 1] == '\n') {
478 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800479#if GNSS_DEBUG
480 log_save(nmea_log_fd, "/**/", 4);
481 log_save(nmea_log_fd, data_buff, data_buff_len);
482#endif
483 if(gnss_info.gnss_set_cb) {
484 gnss_info.gnss_set_cb(data_buff, data_buff_len);
485 }
b.liud0ba7152024-06-19 14:47:21 +0800486 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800487 }
488
b.liud0ba7152024-06-19 14:47:21 +0800489 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800490 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800491 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800492 } else if(nmea_buff_len > 0) {
493 nmea_buff[nmea_buff_len] = '\0';
b.liu42f558e2024-07-18 14:06:49 +0800494 if(memcmp(nmea_buff, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
495 LOGD("NO-NMEA:%s", nmea_buff);
496 }
b.liu99c645d2024-06-20 10:52:15 +0800497#if GNSS_DEBUG
498 log_save(nmea_log_fd, "/**/", 4);
499 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
500#endif
b.liud0ba7152024-06-19 14:47:21 +0800501 }
502
503 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800504 nmea_found = FALSE;
505 }
506 }
507 } else {
508 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800509 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800510 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800511 nmea_buff[nmea_buff_len++] = data[index];
512 } else {
513 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800514 }
515 }
516 index++;
517 }
518 } else {
519 LOGW("Unknown state : %d", gnss_info.state);
520 }
521}
522
523void* gnss_read_pthread(void* arg)
524{
yq.wang069ea922024-09-08 19:29:35 -0700525#if MBTK_GNSS_TEST_LOG
526 gnss_test_log("gnss_read_pthread enter.");
527#endif
b.liu8f231a12024-05-31 17:55:06 +0800528 LOGD("gnss_read_pthread enter.");
yq.wang069ea922024-09-08 19:29:35 -0700529
b.liu8f231a12024-05-31 17:55:06 +0800530 char buffer[GNSS_BUFF_SIZE];
531 int len = 0;
532 int ret = 0;
533 fd_set fdr, fdw;
534 int fd_max = 0;
535
b.liu8f231a12024-05-31 17:55:06 +0800536 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800537 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800538 memset(nmea_buff, 0, sizeof(nmea_buff));
539 memset(data_buff, 0, sizeof(data_buff));
540 nmea_buff_len = 0;
541 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800542#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800543 if(nmea_log_enable) {
544 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
545 if(debug_fd < 0) {
546 LOGE("Open debug fd fail.");
547 }
548 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
549 if(nmea_log_fd < 0) {
550 LOGE("Open nmea fd fail.");
551 }
b.liu99c645d2024-06-20 10:52:15 +0800552 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800553 }
554#endif
555
yq.wang069ea922024-09-08 19:29:35 -0700556#if MBTK_GNSS_TEST_LOG
557 gnss_test_log("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
558#endif
b.liudbc3f4b2024-06-25 18:22:24 +0800559 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
560
b.liu8f231a12024-05-31 17:55:06 +0800561 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800562 FD_ZERO(&fdw);
563 FD_ZERO(&fdr);
564 FD_SET(gnss_info.fd, &fdr);
565 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800566 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
567 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800568 if(gnss_info.state < GNSS_STATE_OPEN) {
569 LOGD("State = %d, ret = %d", gnss_info.state, ret);
570 if(ret > 0) {
571 if (FD_ISSET(gnss_info.fd, &fdr)) {
572 LOGD("gnss_fd can read.");
573 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
574 LOGD("exit_fd can read.");
575 } else {
576 LOGW("Unknown select event.");
577 }
578 }
579 break;
580 }
581
b.liu8f231a12024-05-31 17:55:06 +0800582 if (ret < 0)
583 {
584 if (errno == EINTR)
585 {
586 continue;
587 }
yq.wang069ea922024-09-08 19:29:35 -0700588#if MBTK_GNSS_TEST_LOG
589 gnss_test_log("select error, errno = %d (%s)", errno, strerror(errno));
590#endif
b.liu8f231a12024-05-31 17:55:06 +0800591 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
592 break;
593 }
594 else if (ret == 0)
595 {
596 LOGE("select ret == 0");
597 break;
598 }
599
600 if (FD_ISSET(gnss_info.fd, &fdr))
601 {
602 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800603 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800604 if(len > 0) {
605 //log_hex("READ", buffer, len);
606
607#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800608 //LOGD("read data_len = %d", len);
609 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800610#endif
611
612 gnss_data_process(buffer, len);
613
614 } else if(len ==0 ){
615 LOGE("Read end : len = 0");
616 break;
617 } else {
618 if(EAGAIN == errno) {
619 usleep(50000);
620 continue;
621 } else {
622 LOGD("Read ret = -1 ,errno = %d", errno);
623 break;
624 }
625 }
626 }
627 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
628 {
b.liuece0db02024-06-25 18:39:09 +0800629 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800630 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800631 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800632 if(len > 0) {
633 if(strcmp(buffer, "exit") == 0) {
634 LOGD("Get thread exit message.");
635 break;
636 }
637 }
638 }
639 else
640 {
yq.wang069ea922024-09-08 19:29:35 -0700641#if MBTK_GNSS_TEST_LOG
642 gnss_test_log("Unknown select event.");
643#endif
b.liu8f231a12024-05-31 17:55:06 +0800644 LOGW("Unknown select event.");
645 continue;
646 }
647 }
648
649#if GNSS_DEBUG
650 if(debug_fd > 0) {
651 close(debug_fd);
652 debug_fd = -1;
653 }
654 if(nmea_log_fd > 0) {
655 close(nmea_log_fd);
656 nmea_log_fd = -1;
657 }
658#endif
659
660 gnss_info.state = GNSS_STATE_CLOSE;
661 LOGD("gnss_read_pthread exit.");
662 return NULL;
663}
664
665#if 0
666int gnss_write(int fd, const void *data, int data_len)
667{
668 int count = 0;
669 int len = 0;
670 while(1)
671 {
672 len = write(fd, data + count, data_len - count);
673 if (len > 0)
674 {
675 count += len;
676 }
677 else
678 {
679 LOGE("write() fail,ret = %d,errno = %d", len, errno);
680 break;
681 }
682
683 if (count == data_len)
684 break;
685 }
686
687 return count;
688}
689#else
b.liu778645e2024-06-21 16:47:42 +0800690int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800691{
b.liu778645e2024-06-21 16:47:42 +0800692 ssize_t size;
693 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800694 ssize_t size_written;
695 if(GNSS_BUFF_SIZE < buf_len)
696 {
697 return -1;
698 }
699 for(size = 0; size < buf_len;)
700 {
701 size_to_wr = buf_len - size;
702 if( size_to_wr > GNSS_BUFF_SIZE)
703 size_to_wr = GNSS_BUFF_SIZE;
704
b.liu778645e2024-06-21 16:47:42 +0800705 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800706 if (size_written==-1)
707 {
708 return -1;
709 }
710 size += size_written;
711 if(size_written != size_to_wr)
712 {
713 return size;
714 }
715 }
716 // LOGD("SEND %d / %d", size, buf_len);
717 return size;
718}
719#endif
720
721int gnss_init(uint32 print_port)
722{
yq.wang069ea922024-09-08 19:29:35 -0700723#if MBTK_GNSS_TEST_LOG
724 gnss_test_log("[gnss_init] gnss state [%d]", gnss_info.state);
725#endif
726
b.liu8f231a12024-05-31 17:55:06 +0800727 if(gnss_info.state != GNSS_STATE_CLOSE) {
728 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800729 if(gnss_info.state == GNSS_STATE_READY) {
730 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
731 if(gnss_info.print_port != print_port) {
732 return gnss_ports_open(print_port);
733 } else {
734 return GNSS_ERR_OK;
735 }
736 } else {
737 return GNSS_ERR_OK;
738 }
b.liu8f231a12024-05-31 17:55:06 +0800739 }
740
741 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800742 if(gnss_info.dl_befor_open) {
743 //if(gnss_info.auto_dl_fw) {
744 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800745 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800746 if(ret) {
747 LOGE("gnss_fw_dl() fail : %d", ret);
748 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800749 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800750 }
b.liu8f231a12024-05-31 17:55:06 +0800751
b.liu99c645d2024-06-20 10:52:15 +0800752 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
753 if(gnss_info.fd <= 0) {
754 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
755 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800756 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800757 }
758 if(pipe(gnss_info.exit_fd)) {
759 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800760 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800761 }
762 // GNSS is opened.
763 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800764
b.liu99c645d2024-06-20 10:52:15 +0800765#if 0
766 // Start gnss read thread.
767 pthread_attr_t thread_attr;
768 pthread_attr_init(&thread_attr);
769 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
770 {
771 LOGE("pthread_attr_setdetachstate() fail.");
772 goto main_exit;
773 }
b.liu8f231a12024-05-31 17:55:06 +0800774
b.liu99c645d2024-06-20 10:52:15 +0800775 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800776#else
b.liu99c645d2024-06-20 10:52:15 +0800777 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800778#endif
b.liu99c645d2024-06-20 10:52:15 +0800779 {
780 LOGE("pthread_create() fail.");
781 goto exit_with_close;
782 }
b.liu8f231a12024-05-31 17:55:06 +0800783
b.liu99c645d2024-06-20 10:52:15 +0800784 ret = gnss_info.gnss_dev_open();
785 if(ret) {
786 LOGE("gnss_dev_open() fail : %d", ret);
787 goto exit_with_thread_exit;
788 }
789 //}
790 } else {
791 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
792 if(gnss_info.fd <= 0) {
793 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
794 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800795 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800796 }
797 if(pipe(gnss_info.exit_fd)) {
798 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800799 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800800 }
801 // GNSS is opened.
802 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800803
b.liu99c645d2024-06-20 10:52:15 +0800804#if 0
805 // Start gnss read thread.
806 pthread_attr_t thread_attr;
807 pthread_attr_init(&thread_attr);
808 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
809 {
810 LOGE("pthread_attr_setdetachstate() fail.");
811 goto main_exit;
812 }
813
814 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
815#else
816 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
817#endif
818 {
819 LOGE("pthread_create() fail.");
820 goto exit_with_close;
821 }
822
823 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800824 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800825 LOGE("gnss_dev_open() fail : %d", ret);
826 goto exit_with_thread_exit;
827 }
b.liu8f231a12024-05-31 17:55:06 +0800828 }
829
830 // GNSS is ready, NMEA can print from uart.
831 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +0800832
833 LOGD("GNSS open success.");
834
yq.wang36222352024-11-06 03:31:24 -0800835 if(NULL != gnss_info.gnss_init_set)
836 {
837 gnss_info.gnss_init_set(gnss_info.fd);
838 }
yq.wang069ea922024-09-08 19:29:35 -0700839#if MBTK_GNSS_TEST_LOG
840 gnss_test_log("gnss open success.");
841#endif
842
b.liuced8dd02024-06-28 13:28:29 +0800843 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +0800844
b.liu8f231a12024-05-31 17:55:06 +0800845exit_with_thread_exit:
846 gnss_info.state = GNSS_STATE_CLOSING;
847 // Wait for read thread exit.
848 ret = pthread_join(gnss_info.read_pid, NULL);
849 if(ret){
850 LOGE("pthrad_join fail(%d)",ret);
851 }
852exit_with_close:
853 if(gnss_info.gnss_close(gnss_info.fd)) {
854 LOGE("gnss_close() fail.");
855 }
856 if(gnss_info.exit_fd[0] > 0) {
857 close(gnss_info.exit_fd[0]);
858 gnss_info.exit_fd[0] = -1;
859 }
860 if(gnss_info.exit_fd[1] > 0) {
861 close(gnss_info.exit_fd[1]);
862 gnss_info.exit_fd[1] = -1;
863 }
864 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800865 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800866}
867
868int gnss_deinit()
869{
yq.wang069ea922024-09-08 19:29:35 -0700870#if MBTK_GNSS_TEST_LOG
871 gnss_test_log("[gnss_deinit] gnss state [%d]", gnss_info.state);
872#endif
873
b.liu8f231a12024-05-31 17:55:06 +0800874 if(gnss_info.state == GNSS_STATE_CLOSE) {
875 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +0800876 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800877 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
878 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +0800879 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800880 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
881 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +0800882 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800883 }
884
b.liu978f5432024-07-01 18:04:18 +0800885 if(gnss_info.gnss_dev_close(gnss_info.fd)) {
886 LOGE("gnss_dev_close() fail.");
887 return GNSS_ERR_UNKNOWN;
888 }
889
b.liu8f231a12024-05-31 17:55:06 +0800890 // Wait for read thread exit.
891 if(gnss_info.exit_fd[1] > 0) {
892 write(gnss_info.exit_fd[1], "exit", 4);
893 }
894
895 gnss_info.state = GNSS_STATE_CLOSING;
yq.wang069ea922024-09-08 19:29:35 -0700896
897#if MBTK_GNSS_TEST_LOG
898 gnss_test_log("wait gnss pthread exit...");
899#endif
b.liu8f231a12024-05-31 17:55:06 +0800900 int ret = pthread_join(gnss_info.read_pid, NULL);
901 if(ret){
902 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +0800903 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800904 }
905
906 if(gnss_info.gnss_close(gnss_info.fd)) {
907 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800908 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800909 }
910
b.liu8f231a12024-05-31 17:55:06 +0800911 if(gnss_ports_close()) {
912 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800913 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800914 }
915
yq.wang069ea922024-09-08 19:29:35 -0700916#if MBTK_GNSS_TEST_LOG
917 gnss_test_log("gnss_ports_close() complete.");
918#endif
b.liud0ba7152024-06-19 14:47:21 +0800919 LOGD("gnss_ports_close() complete.");
920
b.liu8f231a12024-05-31 17:55:06 +0800921 gnss_info.fd = -1;
922 if(gnss_info.exit_fd[0] > 0) {
923 close(gnss_info.exit_fd[0]);
924 gnss_info.exit_fd[0] = -1;
925 }
926 if(gnss_info.exit_fd[1] > 0) {
927 close(gnss_info.exit_fd[1]);
928 gnss_info.exit_fd[1] = -1;
929 }
930 gnss_info.state = GNSS_STATE_CLOSE;
yq.wang069ea922024-09-08 19:29:35 -0700931#if MBTK_GNSS_TEST_LOG
932 gnss_test_log("gnss close success.");
933#endif
b.liu8f231a12024-05-31 17:55:06 +0800934 LOGD("GNSS close success.");
yq.wang069ea922024-09-08 19:29:35 -0700935
b.liudbc3f4b2024-06-25 18:22:24 +0800936 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800937}
938
939int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
940{
b.liud0ba7152024-06-19 14:47:21 +0800941 if(buf && buf_len > 0) {
942 if(cmd_rsp && cmd_rsp_len > 0) {
943 memset(cmd_rsp, 0, cmd_rsp_len);
944 }
b.liu8f231a12024-05-31 17:55:06 +0800945 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
946 } else {
b.liudbc3f4b2024-06-25 18:22:24 +0800947 return GNSS_ERR_UNKNOWN;
948 }
949}
950
951int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
952{
b.liu42f558e2024-07-18 14:06:49 +0800953 // Only 8122 support download fw.
b.liudbc3f4b2024-06-25 18:22:24 +0800954 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
955 return GNSS_ERR_UNSUPPORT;
956 }
957
958 if(rsp && rsp_len > 0) {
959 memset(rsp, 0, rsp_len);
960 }
961
962 if(gnss_info.gnss_fw_dl) {
963 if(GNSS_ERR_OK != gnss_deinit()) {
964 LOGE("Close gnss fail.");
965 return GNSS_ERR_UNKNOWN;
966 } else {
967 LOGD("Start gnss fw dl.");
968 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
969 }
970 } else {
b.liu42f558e2024-07-18 14:06:49 +0800971 return GNSS_ERR_UNSUPPORT;
b.liu8f231a12024-05-31 17:55:06 +0800972 }
973}
974
yq.wang99db6f52024-09-12 01:58:48 -0700975int gnss_agnss_get_eph(const void* param)
976{
977 if(gnss_info.gnss_agnss_get_eph)
978 {
979 return gnss_info.gnss_agnss_get_eph(param);
980 }
981 else
982 {
983 return GNSS_ERR_UNSUPPORT;
984 }
985
986 return GNSS_ERR_OK;
987}
988
989int gnss_agnss_inject(void)
990{
991 if(gnss_info.state != GNSS_STATE_READY)
992 {
993 LOGE("gnss not ready");
994 return GNSS_ERR_UNKNOWN;
995 }
996
997 if(gnss_info.gnss_agnss_inject)
998 {
999 return gnss_info.gnss_agnss_inject(gnss_info.fd);
1000 }
1001 else
1002 {
1003 return GNSS_ERR_UNSUPPORT;
1004 }
1005
1006 return GNSS_ERR_OK;
1007}
1008
b.liue77ac3a2024-07-17 17:36:57 +08001009int gnss_ind_set(int fd, int ind_type)
1010{
1011 int index = 0;
1012 if(ind_type) { // Add IND flag.
1013 while(index < GNSS_CLI_IND_MAX) {
1014 if(ind_info[index].cli_fd == fd)
1015 break;
1016 index++;
1017 }
1018
1019 if(index == GNSS_CLI_IND_MAX) { // Add flag
1020 index = 0;
1021 while(index < GNSS_CLI_IND_MAX) {
1022 if(ind_info[index].cli_fd <= 0)
1023 break;
1024 index++;
1025 }
yq.wang1ddd1fd2024-07-25 23:00:14 -07001026 if(index == GNSS_CLI_IND_MAX)
1027 {
1028 LOGE("ind flag is full.");
1029 return GNSS_ERR_CLI_FULL;
1030 }
b.liue77ac3a2024-07-17 17:36:57 +08001031 ind_info[index].cli_fd = fd;
1032 ind_info[index].ind_flag = (uint32)ind_type;
b.liubcf86c92024-08-19 19:48:28 +08001033 } else { // Change flag
b.liue77ac3a2024-07-17 17:36:57 +08001034 ind_info[index].cli_fd = fd;
1035 ind_info[index].ind_flag = (uint32)ind_type;
1036 }
1037 } else { // Clear IND flag.
1038 while(index < GNSS_CLI_IND_MAX) {
1039 if(ind_info[index].cli_fd == fd)
1040 break;
1041 index++;
1042 }
1043
1044 if(index == GNSS_CLI_IND_MAX) {
1045 return GNSS_ERR_ARG;
b.liubcf86c92024-08-19 19:48:28 +08001046 }
b.liue77ac3a2024-07-17 17:36:57 +08001047 ind_info[index].cli_fd = 0;
1048 ind_info[index].ind_flag = 0;
1049 }
1050
1051 return GNSS_ERR_OK;
1052}
1053
b.liu8f231a12024-05-31 17:55:06 +08001054static void sig_process(int sig)
1055{
1056 LOGI("I got signal %d\n", sig);
1057 if(gnss_deinit()) {
1058 LOGE("gnss_deinit() fail, no exist...");
1059 return;
1060 }
1061
1062 switch(sig)
1063 {
1064 case SIGINT: // Ctrl + C
1065 {
1066 LOGI("Exit by SIGINT.\n");
1067 exit(0);
1068 }
luojiand7960682024-08-02 16:50:01 +08001069 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 +08001070 {
1071 LOGI("Exit by SIGQUIT.\n");
1072 exit(0);
1073 }
luojiand7960682024-08-02 16:50:01 +08001074 case SIGTERM:// Ĭ\C8\CFkill (ͬ SIGKILL \A3\AC\B5\AB SIGKILL \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001075 {
1076 LOGI("Exit by SIGTERM.\n");
1077 exit(0);
1078 }
luojiand7960682024-08-02 16:50:01 +08001079 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP \A3\AC\B5\AB SIGSTOP \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001080 {
1081 LOGI("Exit by SIGTSTP.\n");
1082 exit(0);
1083 }
luojiand7960682024-08-02 16:50:01 +08001084 case SIGSEGV: // \C8\E7\BF\D5Ö¸\D5\EB
b.liu8f231a12024-05-31 17:55:06 +08001085 {
1086 LOGI("Exit by SIGSEGV.\n");
1087 exit(0);
1088 }
1089 default:
1090 {
1091 LOGI("Unknown sig:%d\n",sig);
1092 break;
1093 }
1094 }
1095}
1096
1097
b.liuced8dd02024-06-28 13:28:29 +08001098// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +08001099int main(int argc, char *argv[])
1100{
1101 mbtk_log_init("radio", GNSS_TAG);
1102
b.liubcf86c92024-08-19 19:48:28 +08001103 MBTK_SOURCE_INFO_PRINT("mbtk_gnssd");
1104
b.liubb590492024-06-13 16:42:08 +08001105#ifdef MBTK_DUMP_SUPPORT
1106 mbtk_debug_open(NULL, TRUE);
1107#endif
1108
b.liu8f231a12024-05-31 17:55:06 +08001109 signal(SIGINT, sig_process);
1110 signal(SIGQUIT, sig_process);
1111 signal(SIGTERM, sig_process);
1112
1113 if(arg_check(argc, argv)) {
1114 return -1;
1115 }
1116
1117#ifdef GNSS_DEBUG
1118 char buff[10];
1119 memset(buff, 0, 10);
1120 property_get(MBTK_PROP_GNSS_LOG, buff, "");
1121 if(strlen(buff) > 0 && atoi(buff) > 0) {
1122 nmea_log_enable = TRUE;
1123 }
1124#endif
1125
1126 memset(&gnss_info, 0, sizeof(gnss_info_t));
1127 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
1128 gnss_info.state = GNSS_STATE_CLOSE;
1129 if(!strcmp(argv[1], GNSS_ID_6228)) {
1130 gnss_info.gnss_id = GNSS_TYPE_6228;
1131 gnss_info.auto_open = (bool)atoi(argv[3]);
1132 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +08001133 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +08001134 gnss_info.gnss_dev_open = gnss_6228_dev_open;
1135 gnss_info.gnss_dev_close = gnss_6228_dev_close;
1136 gnss_info.gnss_open = gnss_6228_open;
1137 gnss_info.gnss_close = gnss_6228_close;
yq.wang36222352024-11-06 03:31:24 -08001138 gnss_info.gnss_init_set = NULL;
b.liu8f231a12024-05-31 17:55:06 +08001139 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
1140 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
1141 gnss_info.gnss_set = gnss_6228_set;
1142 gnss_info.gnss_set_cb = gnss_6228_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001143 gnss_info.gnss_agnss_get_eph = NULL;
1144 gnss_info.gnss_agnss_inject = NULL;
b.liuf9fbfa12024-06-14 15:53:59 +08001145 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
1146 gnss_info.gnss_id = GNSS_TYPE_8122;
1147 gnss_info.auto_open = (bool)atoi(argv[3]);
1148 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +08001149 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +08001150 gnss_info.gnss_dev_open = gnss_8122_dev_open;
1151 gnss_info.gnss_dev_close = gnss_8122_dev_close;
1152 gnss_info.gnss_open = gnss_8122_open;
1153 gnss_info.gnss_close = gnss_8122_close;
yq.wang36222352024-11-06 03:31:24 -08001154 gnss_info.gnss_init_set = gnss_8122_init_set;
b.liuf9fbfa12024-06-14 15:53:59 +08001155 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
1156 gnss_info.gnss_dl_read_cb = NULL;
1157 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +08001158 gnss_info.gnss_set_cb = gnss_8122_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001159 gnss_info.gnss_agnss_get_eph = gnss_8122_agnss_get_eph;
1160 gnss_info.gnss_agnss_inject = gnss_8122_agnss_inject;
b.liu99c645d2024-06-20 10:52:15 +08001161 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
1162 gnss_info.gnss_id = GNSS_TYPE_5311;
1163 gnss_info.auto_open = (bool)atoi(argv[3]);
1164 gnss_info.auto_dl_fw = TRUE;
1165 gnss_info.dl_befor_open = TRUE;
1166 gnss_info.gnss_dev_open = gnss_5311_dev_open;
1167 gnss_info.gnss_dev_close = gnss_5311_dev_close;
1168 gnss_info.gnss_open = gnss_5311_open;
1169 gnss_info.gnss_close = gnss_5311_close;
yq.wang36222352024-11-06 03:31:24 -08001170 gnss_info.gnss_init_set = NULL;
b.liu99c645d2024-06-20 10:52:15 +08001171 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
1172 gnss_info.gnss_dl_read_cb = NULL;
1173 gnss_info.gnss_set = gnss_5311_set;
1174 gnss_info.gnss_set_cb = gnss_5311_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001175 gnss_info.gnss_agnss_get_eph = NULL;
1176 gnss_info.gnss_agnss_inject = NULL;
b.liu42f558e2024-07-18 14:06:49 +08001177 } else if(!strcmp(argv[1], GNSS_ID_N50DB)) {
1178 gnss_info.gnss_id = GNSS_TYPE_N50DB;
1179 gnss_info.auto_open = (bool)atoi(argv[3]);
1180 gnss_info.auto_dl_fw = FALSE;
1181 gnss_info.dl_befor_open = FALSE;
1182 gnss_info.gnss_dev_open = gnss_n50db_dev_open;
1183 gnss_info.gnss_dev_close = gnss_n50db_dev_close;
1184 gnss_info.gnss_open = gnss_n50db_open;
1185 gnss_info.gnss_close = gnss_n50db_close;
yq.wang36222352024-11-06 03:31:24 -08001186 gnss_info.gnss_init_set = NULL;
b.liu42f558e2024-07-18 14:06:49 +08001187 gnss_info.gnss_fw_dl = gnss_n50db_fw_dl;
1188 gnss_info.gnss_dl_read_cb = NULL;
1189 gnss_info.gnss_set = gnss_n50db_set;
1190 gnss_info.gnss_set_cb = gnss_n50db_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001191 gnss_info.gnss_agnss_get_eph = NULL;
1192 gnss_info.gnss_agnss_inject = NULL;
b.liu8f231a12024-05-31 17:55:06 +08001193 } else {
1194 LOGE("No support : %s", argv[1]);
1195 return -1;
1196 }
1197
1198 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
1199 // Auto open gnss.
1200 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +08001201 int init_mode = atoi(argv[3]);
1202 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
1203 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +08001204 }
b.liuced8dd02024-06-28 13:28:29 +08001205 if(gnss_init((uint32)init_mode)) {
1206 LOGE("gnss_init() fail.");
1207 // return -1;
1208 }
1209 } else {
1210 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +08001211 }
1212
b.liua1b69262024-09-04 16:32:59 +08001213#if MBTK_GNSS_PTY_AUTO_INIT
1214 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
1215 LOGE("gnss_pty_open() fail.");
1216 return -1;
1217 }
1218#endif
1219
yq.wang069ea922024-09-08 19:29:35 -07001220#if MBTK_GNSS_TEST_LOG
1221 gnss_test_log("gnss init success.");
1222#endif
b.liu8f231a12024-05-31 17:55:06 +08001223 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +08001224#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +08001225 if(gnss_ubus_init()) {
1226 LOGD("main() run...");
1227 uloop_run();
1228 } else {
1229 LOGE("gnss_ubus_init() fail.");
1230 }
b.liu5f950c52024-06-15 20:13:12 +08001231#else
1232 if(!gnss_ipc_service_start()) {
1233 LOGD("main() run...");
1234 while(1) {
1235 sleep(24 * 60 * 60);
1236 }
1237 } else {
1238 LOGE("gnss_ipc_service_start() fail.");
1239 }
1240#endif
b.liu8f231a12024-05-31 17:55:06 +08001241
1242 LOGD("main() exit.");
1243 return 0;
1244}