blob: 5b9de7846ec6cbe0e1252ec823b9f40dab825e4c [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.liu9e8584b2024-11-06 19:21:28 +080023#include "mbtk_utils.h"
b.liu8f231a12024-05-31 17:55:06 +080024
25#define GNSS_DEBUG 1
b.liud0ba7152024-06-19 14:47:21 +080026#define GNSS_UBUS_ENABLE 1
b.liu8f231a12024-05-31 17:55:06 +080027
28#define GNSS_TAG "MBTK_GNSS"
29#define GNSS_BUFF_SIZE 2048
30#define MBTK_PROP_GNSS_LOG "persist.mbtk.gnss_log_enable"
31#define GNSS_PORT_PTY "/dev/tty_gnss_nmea"
32#define GNSS_PORT_USB_AT "/dev/ttyGS0"
33#define GNSS_PORT_USB_NMEA "/dev/ttymodem0"
34#define GNSS_PORT_UART_AT "/dev/ttyS1"
b.liue77ac3a2024-07-17 17:36:57 +080035#define GNSS_CLI_IND_MAX 10
b.liu8f231a12024-05-31 17:55:06 +080036
37#ifdef GNSS_DEBUG
38#define GNSS_NMEA_FILE_LOG "/tmp/mbtk_gnss_nmea.log"
b.liu8f231a12024-05-31 17:55:06 +080039#define GNSS_FILE_LOG "/tmp/mbtk_gnss.log"
b.liu99c645d2024-06-20 10:52:15 +080040#define GNSS_FILE_LOG_MAX 104857600 // 100MB
b.liu8f231a12024-05-31 17:55:06 +080041#endif
42
b.liua1b69262024-09-04 16:32:59 +080043#define MBTK_GNSS_PTY_AUTO_INIT 1
44
b.liubcf86c92024-08-19 19:48:28 +080045gnss_info_t gnss_info;
b.liu8f231a12024-05-31 17:55:06 +080046
b.liud0ba7152024-06-19 14:47:21 +080047#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080048struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080049#else
50int gnss_ipc_service_start();
51#endif
52
b.liu8f231a12024-05-31 17:55:06 +080053int gnss_init_config(int fd);
54
wangyouqiangfa897f82024-06-27 09:44:55 +080055static char nmea_buff[GNSS_BUFF_SIZE*4] = {0};
56static char data_buff[GNSS_BUFF_SIZE*4] = {0};
b.liud0ba7152024-06-19 14:47:21 +080057static uint32 nmea_buff_len = 0;
58static uint32 data_buff_len = 0;
b.liue77ac3a2024-07-17 17:36:57 +080059static gnss_ind_info_t ind_info[GNSS_CLI_IND_MAX];
b.liud0ba7152024-06-19 14:47:21 +080060
b.liu8f231a12024-05-31 17:55:06 +080061static bool nmea_found = FALSE;
62#ifdef GNSS_DEBUG
63static bool nmea_log_enable = FALSE;
64static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080065static int debug_fd = -1;
66static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080067#endif
yq.wang5c647e02024-08-10 00:01:11 -070068
b.liua1b69262024-09-04 16:32:59 +080069#if MBTK_GNSS_PTY_AUTO_INIT
70static bool gnss_pty_print_enable = FALSE;
71#endif
b.liu8f231a12024-05-31 17:55:06 +080072static int gnss_pty_master_fd = -1;
73static int gnss_pty_slave_fd = -1;
74static int gnss_usb_at_port_fd = -1;
75static int gnss_usb_nmea_port_fd = -1;
76static int gnss_uart_at_port_fd = -1;
77static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
78
b.liue77ac3a2024-07-17 17:36:57 +080079int gnss_write(int fd, const void* buf, int buf_len);
80
b.liu8f231a12024-05-31 17:55:06 +080081static void help()
82{
b.liu42f558e2024-07-18 14:06:49 +080083 LOGD("mbtk_gnssd <6228/8122/5311/N50DB> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080084}
85
86static int arg_check(int argc, char *argv[])
87{
88 if(argc != 4) {
b.liu4ae41182024-06-28 16:30:15 +080089 LOGE("argc = %d", argc);
b.liu8f231a12024-05-31 17:55:06 +080090 goto check_fail;
91 }
92
b.liu99c645d2024-06-20 10:52:15 +080093 // Only support 6228/8122/5311.
b.liu42f558e2024-07-18 14:06:49 +080094 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)
95 && strcmp(argv[1], GNSS_ID_N50DB)) {
b.liu4ae41182024-06-28 16:30:15 +080096 LOGE("argv[1] = %s", argv[1]);
b.liu8f231a12024-05-31 17:55:06 +080097 goto check_fail;
98 }
99
100 if(access(argv[2], R_OK | W_OK)) {
b.liu4ae41182024-06-28 16:30:15 +0800101 LOGE("access(%s) rw fail. ", argv[2]);
b.liu8f231a12024-05-31 17:55:06 +0800102 goto check_fail;
103 }
104
b.liuced8dd02024-06-28 13:28:29 +0800105#if 0
106 int init_mode = atoi(argv[3]);
107 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 +0800108 goto check_fail;
109 }
b.liuced8dd02024-06-28 13:28:29 +0800110#endif
b.liu8f231a12024-05-31 17:55:06 +0800111
112 return 0;
113check_fail:
114 help();
115 return -1;
116}
117
118static int gnss_ports_open(uint32 print_port)
119{
b.liuced8dd02024-06-28 13:28:29 +0800120 // TTY AT change.
121 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
122 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
b.liua1b69262024-09-04 16:32:59 +0800123#if MBTK_GNSS_PTY_AUTO_INIT
124 gnss_pty_print_enable = TRUE;
125#else
b.liuced8dd02024-06-28 13:28:29 +0800126 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
127 return GNSS_ERR_OPEN_DEV;
128 }
b.liua1b69262024-09-04 16:32:59 +0800129#endif
b.liuced8dd02024-06-28 13:28:29 +0800130 LOGD("Open PTY port success.");
131 } else { // Close
b.liua1b69262024-09-04 16:32:59 +0800132#if MBTK_GNSS_PTY_AUTO_INIT
133 gnss_pty_print_enable = FALSE;
134#else
b.liuced8dd02024-06-28 13:28:29 +0800135 if(gnss_pty_slave_fd > 0) {
136 close(gnss_pty_slave_fd);
137 gnss_pty_slave_fd = -1;
138 unlink(GNSS_PORT_PTY);
139 }
b.liua1b69262024-09-04 16:32:59 +0800140#endif
b.liuced8dd02024-06-28 13:28:29 +0800141 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800142 }
b.liu8f231a12024-05-31 17:55:06 +0800143 }
144
b.liuced8dd02024-06-28 13:28:29 +0800145 // USB AT change.
146 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
147 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
b.liu978f5432024-07-01 18:04:18 +0800148 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 +0800149 return GNSS_ERR_OPEN_DEV;
150 }
151 LOGD("Open USB AT port success.");
152 } else { // Close
153 if(gnss_usb_at_port_fd > 0) {
154 close(gnss_usb_at_port_fd);
155 gnss_usb_at_port_fd = -1;
156 }
157 LOGD("Close USB AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800158 }
b.liu8f231a12024-05-31 17:55:06 +0800159 }
160
b.liuced8dd02024-06-28 13:28:29 +0800161 // USB NMEA change.
162 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
163 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
b.liu978f5432024-07-01 18:04:18 +0800164 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 +0800165 return GNSS_ERR_OPEN_DEV;
166 }
167 LOGD("Open USB NMEA port success.");
168 } else { // Close
169 if(gnss_usb_nmea_port_fd > 0) {
170 close(gnss_usb_nmea_port_fd);
171 gnss_usb_nmea_port_fd = -1;
172 }
173 LOGD("Close USB NMEA port success.");
b.liu8f231a12024-05-31 17:55:06 +0800174 }
b.liu8f231a12024-05-31 17:55:06 +0800175 }
176
b.liuced8dd02024-06-28 13:28:29 +0800177 // Uart AT change.
178 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
179 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
180 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
181 return GNSS_ERR_OPEN_DEV;
182 }
183 LOGD("Open UART AT port success.");
184 } else { // Close
185 if(gnss_uart_at_port_fd > 0) {
186 close(gnss_uart_at_port_fd);
187 gnss_uart_at_port_fd = -1;
188 }
189 LOGD("Close UART AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800190 }
b.liu8f231a12024-05-31 17:55:06 +0800191 }
192
b.liuced8dd02024-06-28 13:28:29 +0800193 gnss_info.print_port = print_port;
194
b.liudbc3f4b2024-06-25 18:22:24 +0800195 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800196}
197
198static int gnss_ports_close()
199{
200 if(gnss_usb_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800201 tcflush(gnss_usb_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800202 close(gnss_usb_at_port_fd);
203 gnss_usb_at_port_fd = -1;
204 }
205
206 if(gnss_usb_nmea_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800207 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800208 close(gnss_usb_nmea_port_fd);
209 gnss_usb_nmea_port_fd = -1;
210 }
211
212 if(gnss_uart_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800213 tcflush(gnss_uart_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800214 close(gnss_uart_at_port_fd);
215 gnss_uart_at_port_fd = -1;
216 }
b.liua1b69262024-09-04 16:32:59 +0800217#if MBTK_GNSS_PTY_AUTO_INIT
218 gnss_pty_print_enable = FALSE;
219#else
b.liu8f231a12024-05-31 17:55:06 +0800220 if(gnss_pty_master_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800221 tcflush(gnss_pty_master_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800222 close(gnss_pty_master_fd);
223 gnss_pty_master_fd = -1;
224 }
225
226 if(gnss_pty_slave_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800227 tcflush(gnss_pty_slave_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800228 close(gnss_pty_slave_fd);
229 gnss_pty_slave_fd = -1;
230 unlink(GNSS_PORT_PTY);
231 }
b.liua1b69262024-09-04 16:32:59 +0800232#endif
b.liuced8dd02024-06-28 13:28:29 +0800233 gnss_info.print_port = 0;
234
b.liu8f231a12024-05-31 17:55:06 +0800235 return 0;
236}
237
b.liu8f231a12024-05-31 17:55:06 +0800238#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800239static void log_save(int fd, const char *data, int data_len)
240{
b.liu8f231a12024-05-31 17:55:06 +0800241 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800242 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
243 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
244 close(debug_fd);
245 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
246 if(debug_fd < 0) {
247 LOGE("Open debug fd fail.");
248 }
249 debug_fd_len = 0;
250
251 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800252 close(nmea_log_fd);
253 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
254 if(nmea_log_fd < 0) {
255 LOGE("Open debug fd fail.");
256 }
b.liu8f231a12024-05-31 17:55:06 +0800257 }
258
b.liu99c645d2024-06-20 10:52:15 +0800259 if(fd == nmea_log_fd) {
260 if(nmea_log_fd > 0) {
b.liu9e8584b2024-11-06 19:21:28 +0800261 mbtk_write(nmea_log_fd, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800262 debug_fd_len += data_len;
263 }
264 } else if(fd == debug_fd) {
265 if(debug_fd > 0) {
b.liu9e8584b2024-11-06 19:21:28 +0800266 mbtk_write(debug_fd, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800267 debug_fd_len += data_len;
268 }
b.liu8f231a12024-05-31 17:55:06 +0800269 }
270 }
b.liu99c645d2024-06-20 10:52:15 +0800271}
b.liu8f231a12024-05-31 17:55:06 +0800272#endif
273
b.liue77ac3a2024-07-17 17:36:57 +0800274static void ind_location_print(const char *data)
275{
276 int index = 0;
277 int buff_len = 0;
278 char buff[GNSS_BUFF_SIZE] = {0};
279 buff[0] = MBTK_IND_START_FLAG;
280 buff_len++;
281 memcpy(buff + 1, MBTK_IND_LOCATION_TAG, strlen(MBTK_IND_LOCATION_TAG));
282 buff_len += strlen(MBTK_IND_LOCATION_TAG);
283 memcpy(buff + strlen(buff), data, strlen(data));
284 buff_len += strlen(data);
285 buff[strlen(buff)] = MBTK_IND_END_FLAG;
286 buff_len++;
287
288 while(index < GNSS_CLI_IND_MAX) {
289 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_LOCATION)) {
290 gnss_write(ind_info[index].cli_fd, buff, buff_len);
291 }
292 index++;
293 }
294}
295
296static void ind_nmea_print(const char *data)
297{
298 int index = 0;
299 int buff_len = 0;
300 char buff[GNSS_BUFF_SIZE] = {0};
301 buff[0] = MBTK_IND_START_FLAG;
302 buff_len++;
303 memcpy(buff + 1, MBTK_IND_NMEA_TAG, strlen(MBTK_IND_NMEA_TAG));
304 buff_len += strlen(MBTK_IND_NMEA_TAG);
305 memcpy(buff + strlen(buff), data, strlen(data));
306 buff_len += strlen(data);
307 buff[strlen(buff)] = MBTK_IND_END_FLAG;
308 buff_len++;
309 while(index < GNSS_CLI_IND_MAX) {
310 if(ind_info[index].cli_fd > 0 && (ind_info[index].ind_flag & MBTK_GNSS_IND_NMEA)) {
311 gnss_write(ind_info[index].cli_fd, buff, buff_len);
312 }
313 index++;
314 }
315}
316
b.liu99c645d2024-06-20 10:52:15 +0800317static void nmea_print(const char *nmea, int nmea_len)
318{
yq.wang1ddd1fd2024-07-25 23:00:14 -0700319 int ret = -1;
b.liu8f231a12024-05-31 17:55:06 +0800320 if(gnss_usb_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700321 ret = write(gnss_usb_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800322 }
323
324 if(gnss_usb_nmea_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700325 ret = write(gnss_usb_nmea_port_fd, nmea, nmea_len);
yq.wang4b8ef892024-09-13 02:23:38 -0700326 if(ret < 0 && errno != EAGAIN) {
327 LOGE("gnss_port_fd write fail [errno = %d].", errno);
328 if(errno == EIO) {
329 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
330 close(gnss_usb_nmea_port_fd);
331 gnss_usb_nmea_port_fd = -1;
332 gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE);
333 }
334 }
b.liu8f231a12024-05-31 17:55:06 +0800335 }
336
337 if(gnss_uart_at_port_fd > 0) {
yq.wang1ddd1fd2024-07-25 23:00:14 -0700338 ret = write(gnss_uart_at_port_fd, nmea, nmea_len);
b.liu8f231a12024-05-31 17:55:06 +0800339 }
340
341 if(gnss_pty_master_fd > 0) {
b.liua1b69262024-09-04 16:32:59 +0800342#if MBTK_GNSS_PTY_AUTO_INIT
343 if(gnss_pty_print_enable) {
344 ret = write(gnss_pty_master_fd, nmea, nmea_len);
345 }
346#else
yq.wang1ddd1fd2024-07-25 23:00:14 -0700347 ret = write(gnss_pty_master_fd, nmea, nmea_len);
b.liua1b69262024-09-04 16:32:59 +0800348#endif
b.liu8f231a12024-05-31 17:55:06 +0800349 }
yq.wang937355d2024-07-26 01:24:42 -0700350 ind_nmea_print(nmea);
351 ind_location_print(nmea);
b.liu8f231a12024-05-31 17:55:06 +0800352}
353
354static unsigned char nmea_checksum(const char *nmea)
355{
356 const char *p = nmea;
357 unsigned char chs = 0;
358
359 while (*p == '$') // skip '$'
360 p++;
361 while (*p != '*' && *p != 0)
362 chs ^= *p++;
363
364 return chs;
365}
366
367static bool nmea_check(const char *nmea, int nmea_len)
368{
369 char **ptr = gnss_filter_info;
370 while(*ptr) {
371 if(strstr(nmea, *ptr)) {
372 break;
373 }
374 ptr++;
375 }
376
377 if(*ptr == NULL) {
378 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
379 return FALSE;
380 }
381
382 char *checksum_str = strstr(nmea, "*");
383 checksum_str++; // Jump '*'
384 char checksum_buf[3] = {0};
385 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
386 if(strncasecmp(checksum_buf, checksum_str, 2)) {
387 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
388 return FALSE;
389 }
390
391 return TRUE;
392}
393
394static void gnss_nmea_process(const char *data, int data_len)
395{
luojiand7960682024-08-02 16:50:01 +0800396// LOGD("gnss_nmea_process() : data_len - %d", data_len);
b.liu99c645d2024-06-20 10:52:15 +0800397#if 0
b.liu8f231a12024-05-31 17:55:06 +0800398 char nmea[GNSS_BUFF_SIZE] = {0};
399 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800400#else
401 const char *nmea = data;
402#endif
b.liu8f231a12024-05-31 17:55:06 +0800403
404 if(!nmea_check(nmea, data_len)) {
b.liu42f558e2024-07-18 14:06:49 +0800405 // No print "$HOSTSLEEP".
406 if(memcmp(nmea, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
407 LOGD("NO-NMEA:%s", nmea);
408 }
b.liu99c645d2024-06-20 10:52:15 +0800409#if GNSS_DEBUG
410 log_save(nmea_log_fd, "/**/", 4);
411 log_save(nmea_log_fd, nmea, data_len);
412#endif
413 if(gnss_info.gnss_set_cb)
414 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800415 return;
416 }
417
418#ifdef GNSS_DEBUG
419 if(nmea_log_enable) {
420 LOGD("NMEA[%d]:%s", data_len, nmea);
421 }
b.liu99c645d2024-06-20 10:52:15 +0800422
423 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800424#endif
425
yq.wang069ea922024-09-08 19:29:35 -0700426#if MBTK_GNSS_PARAM_PARSE
427 gnss_ind_nmea_parse(nmea, data_len);
428#endif
luojiand7960682024-08-02 16:50:01 +0800429
b.liu8f231a12024-05-31 17:55:06 +0800430 nmea_print(nmea, data_len);
431}
432
433#if 0
434static void gnss_cmd_rsp_process(const char *data, int data_len)
435{
436 char rsp[GNSS_BUFF_SIZE] = {0};
437 memcpy(rsp, data, data_len);
438 LOGD("RSP[%d]:%s", data_len, rsp);
439}
440#endif
441
442static bool nmea_char_check(char ch)
443{
444 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
yq.wang1ddd1fd2024-07-25 23:00:14 -0700445 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=' || ch == '-')
b.liu8f231a12024-05-31 17:55:06 +0800446 return TRUE;
447
448 return FALSE;
449}
450
451static void gnss_data_process(const char *data, int data_len)
452{
453 if(gnss_info.state == GNSS_STATE_OPEN) {
454 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
455 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
456 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800457 if(gnss_info.gnss_dl_read_cb) {
458 gnss_info.gnss_dl_read_cb(data, data_len);
459 }
b.liu8f231a12024-05-31 17:55:06 +0800460 } else if(gnss_info.state == GNSS_STATE_READY) {
461 int index = 0;
462 while(index < data_len) {
463 if(nmea_found) {
464 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800465 // Copy nmea_buff to data_buff
466 // Start with '$', but not nmea data, so copy to data_buff.
467 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
468 data_buff_len += nmea_buff_len;
469 data_buff[data_buff_len++] = data[index];
470
471 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800472 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800473 continue;
474 }
475
476 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800477 nmea_buff[nmea_buff_len++] = data[index];
478 if(nmea_buff[nmea_buff_len - 1] == '\n') {
479 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800480#if GNSS_DEBUG
481 log_save(nmea_log_fd, "/**/", 4);
482 log_save(nmea_log_fd, data_buff, data_buff_len);
483#endif
484 if(gnss_info.gnss_set_cb) {
485 gnss_info.gnss_set_cb(data_buff, data_buff_len);
486 }
b.liud0ba7152024-06-19 14:47:21 +0800487 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800488 }
489
b.liud0ba7152024-06-19 14:47:21 +0800490 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800491 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800492 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800493 } else if(nmea_buff_len > 0) {
494 nmea_buff[nmea_buff_len] = '\0';
b.liu42f558e2024-07-18 14:06:49 +0800495 if(memcmp(nmea_buff, "$HOSTSLEEP", strlen("$HOSTSLEEP"))) {
496 LOGD("NO-NMEA:%s", nmea_buff);
497 }
b.liu99c645d2024-06-20 10:52:15 +0800498#if GNSS_DEBUG
499 log_save(nmea_log_fd, "/**/", 4);
500 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
501#endif
b.liud0ba7152024-06-19 14:47:21 +0800502 }
503
504 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800505 nmea_found = FALSE;
506 }
507 }
508 } else {
509 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800510 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800511 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800512 nmea_buff[nmea_buff_len++] = data[index];
513 } else {
514 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800515 }
516 }
517 index++;
518 }
519 } else {
520 LOGW("Unknown state : %d", gnss_info.state);
521 }
522}
523
524void* gnss_read_pthread(void* arg)
525{
yq.wang069ea922024-09-08 19:29:35 -0700526#if MBTK_GNSS_TEST_LOG
527 gnss_test_log("gnss_read_pthread enter.");
528#endif
b.liu8f231a12024-05-31 17:55:06 +0800529 LOGD("gnss_read_pthread enter.");
yq.wang069ea922024-09-08 19:29:35 -0700530
b.liu8f231a12024-05-31 17:55:06 +0800531 char buffer[GNSS_BUFF_SIZE];
532 int len = 0;
533 int ret = 0;
534 fd_set fdr, fdw;
535 int fd_max = 0;
536
b.liu8f231a12024-05-31 17:55:06 +0800537 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800538 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800539 memset(nmea_buff, 0, sizeof(nmea_buff));
540 memset(data_buff, 0, sizeof(data_buff));
541 nmea_buff_len = 0;
542 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800543#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800544 if(nmea_log_enable) {
545 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
546 if(debug_fd < 0) {
547 LOGE("Open debug fd fail.");
548 }
549 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
550 if(nmea_log_fd < 0) {
551 LOGE("Open nmea fd fail.");
552 }
b.liu99c645d2024-06-20 10:52:15 +0800553 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800554 }
555#endif
556
yq.wang069ea922024-09-08 19:29:35 -0700557#if MBTK_GNSS_TEST_LOG
558 gnss_test_log("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
559#endif
b.liudbc3f4b2024-06-25 18:22:24 +0800560 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
561
b.liu8f231a12024-05-31 17:55:06 +0800562 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800563 FD_ZERO(&fdw);
564 FD_ZERO(&fdr);
565 FD_SET(gnss_info.fd, &fdr);
566 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800567 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
568 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800569 if(gnss_info.state < GNSS_STATE_OPEN) {
570 LOGD("State = %d, ret = %d", gnss_info.state, ret);
571 if(ret > 0) {
572 if (FD_ISSET(gnss_info.fd, &fdr)) {
573 LOGD("gnss_fd can read.");
574 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
575 LOGD("exit_fd can read.");
576 } else {
577 LOGW("Unknown select event.");
578 }
579 }
580 break;
581 }
582
b.liu8f231a12024-05-31 17:55:06 +0800583 if (ret < 0)
584 {
585 if (errno == EINTR)
586 {
587 continue;
588 }
yq.wang069ea922024-09-08 19:29:35 -0700589#if MBTK_GNSS_TEST_LOG
590 gnss_test_log("select error, errno = %d (%s)", errno, strerror(errno));
591#endif
b.liu8f231a12024-05-31 17:55:06 +0800592 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
593 break;
594 }
595 else if (ret == 0)
596 {
597 LOGE("select ret == 0");
598 break;
599 }
600
601 if (FD_ISSET(gnss_info.fd, &fdr))
602 {
603 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800604 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800605 if(len > 0) {
606 //log_hex("READ", buffer, len);
607
608#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800609 //LOGD("read data_len = %d", len);
610 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800611#endif
612
613 gnss_data_process(buffer, len);
614
615 } else if(len ==0 ){
616 LOGE("Read end : len = 0");
617 break;
618 } else {
619 if(EAGAIN == errno) {
620 usleep(50000);
621 continue;
622 } else {
623 LOGD("Read ret = -1 ,errno = %d", errno);
624 break;
625 }
626 }
627 }
628 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
629 {
b.liuece0db02024-06-25 18:39:09 +0800630 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800631 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800632 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800633 if(len > 0) {
634 if(strcmp(buffer, "exit") == 0) {
635 LOGD("Get thread exit message.");
636 break;
637 }
638 }
639 }
640 else
641 {
yq.wang069ea922024-09-08 19:29:35 -0700642#if MBTK_GNSS_TEST_LOG
643 gnss_test_log("Unknown select event.");
644#endif
b.liu8f231a12024-05-31 17:55:06 +0800645 LOGW("Unknown select event.");
646 continue;
647 }
648 }
649
650#if GNSS_DEBUG
651 if(debug_fd > 0) {
652 close(debug_fd);
653 debug_fd = -1;
654 }
655 if(nmea_log_fd > 0) {
656 close(nmea_log_fd);
657 nmea_log_fd = -1;
658 }
659#endif
660
661 gnss_info.state = GNSS_STATE_CLOSE;
662 LOGD("gnss_read_pthread exit.");
663 return NULL;
664}
665
666#if 0
667int gnss_write(int fd, const void *data, int data_len)
668{
669 int count = 0;
670 int len = 0;
671 while(1)
672 {
673 len = write(fd, data + count, data_len - count);
674 if (len > 0)
675 {
676 count += len;
677 }
678 else
679 {
680 LOGE("write() fail,ret = %d,errno = %d", len, errno);
681 break;
682 }
683
684 if (count == data_len)
685 break;
686 }
687
688 return count;
689}
690#else
b.liu778645e2024-06-21 16:47:42 +0800691int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800692{
b.liu778645e2024-06-21 16:47:42 +0800693 ssize_t size;
694 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800695 ssize_t size_written;
696 if(GNSS_BUFF_SIZE < buf_len)
697 {
698 return -1;
699 }
700 for(size = 0; size < buf_len;)
701 {
702 size_to_wr = buf_len - size;
703 if( size_to_wr > GNSS_BUFF_SIZE)
704 size_to_wr = GNSS_BUFF_SIZE;
705
b.liu778645e2024-06-21 16:47:42 +0800706 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800707 if (size_written==-1)
708 {
709 return -1;
710 }
711 size += size_written;
712 if(size_written != size_to_wr)
713 {
714 return size;
715 }
716 }
717 // LOGD("SEND %d / %d", size, buf_len);
718 return size;
719}
720#endif
721
722int gnss_init(uint32 print_port)
723{
yq.wang069ea922024-09-08 19:29:35 -0700724#if MBTK_GNSS_TEST_LOG
725 gnss_test_log("[gnss_init] gnss state [%d]", gnss_info.state);
726#endif
727
b.liu8f231a12024-05-31 17:55:06 +0800728 if(gnss_info.state != GNSS_STATE_CLOSE) {
729 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800730 if(gnss_info.state == GNSS_STATE_READY) {
731 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
732 if(gnss_info.print_port != print_port) {
733 return gnss_ports_open(print_port);
734 } else {
735 return GNSS_ERR_OK;
736 }
737 } else {
738 return GNSS_ERR_OK;
739 }
b.liu8f231a12024-05-31 17:55:06 +0800740 }
741
742 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800743 if(gnss_info.dl_befor_open) {
744 //if(gnss_info.auto_dl_fw) {
745 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800746 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800747 if(ret) {
748 LOGE("gnss_fw_dl() fail : %d", ret);
749 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800750 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800751 }
b.liu8f231a12024-05-31 17:55:06 +0800752
b.liu99c645d2024-06-20 10:52:15 +0800753 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
754 if(gnss_info.fd <= 0) {
755 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
756 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800757 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800758 }
759 if(pipe(gnss_info.exit_fd)) {
760 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800761 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800762 }
763 // GNSS is opened.
764 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800765
b.liu99c645d2024-06-20 10:52:15 +0800766#if 0
767 // Start gnss read thread.
768 pthread_attr_t thread_attr;
769 pthread_attr_init(&thread_attr);
770 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
771 {
772 LOGE("pthread_attr_setdetachstate() fail.");
773 goto main_exit;
774 }
b.liu8f231a12024-05-31 17:55:06 +0800775
b.liu99c645d2024-06-20 10:52:15 +0800776 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800777#else
b.liu99c645d2024-06-20 10:52:15 +0800778 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800779#endif
b.liu99c645d2024-06-20 10:52:15 +0800780 {
781 LOGE("pthread_create() fail.");
782 goto exit_with_close;
783 }
b.liu8f231a12024-05-31 17:55:06 +0800784
b.liu99c645d2024-06-20 10:52:15 +0800785 ret = gnss_info.gnss_dev_open();
786 if(ret) {
787 LOGE("gnss_dev_open() fail : %d", ret);
788 goto exit_with_thread_exit;
789 }
790 //}
791 } else {
792 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
793 if(gnss_info.fd <= 0) {
794 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
795 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800796 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800797 }
798 if(pipe(gnss_info.exit_fd)) {
799 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800800 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800801 }
802 // GNSS is opened.
803 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800804
b.liu99c645d2024-06-20 10:52:15 +0800805#if 0
806 // Start gnss read thread.
807 pthread_attr_t thread_attr;
808 pthread_attr_init(&thread_attr);
809 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
810 {
811 LOGE("pthread_attr_setdetachstate() fail.");
812 goto main_exit;
813 }
814
815 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
816#else
817 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
818#endif
819 {
820 LOGE("pthread_create() fail.");
821 goto exit_with_close;
822 }
823
824 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800825 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800826 LOGE("gnss_dev_open() fail : %d", ret);
827 goto exit_with_thread_exit;
828 }
b.liu8f231a12024-05-31 17:55:06 +0800829 }
830
831 // GNSS is ready, NMEA can print from uart.
832 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +0800833
834 LOGD("GNSS open success.");
835
yq.wang36222352024-11-06 03:31:24 -0800836 if(NULL != gnss_info.gnss_init_set)
837 {
838 gnss_info.gnss_init_set(gnss_info.fd);
839 }
yq.wang069ea922024-09-08 19:29:35 -0700840#if MBTK_GNSS_TEST_LOG
841 gnss_test_log("gnss open success.");
842#endif
843
b.liuced8dd02024-06-28 13:28:29 +0800844 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +0800845
b.liu8f231a12024-05-31 17:55:06 +0800846exit_with_thread_exit:
847 gnss_info.state = GNSS_STATE_CLOSING;
848 // Wait for read thread exit.
849 ret = pthread_join(gnss_info.read_pid, NULL);
850 if(ret){
851 LOGE("pthrad_join fail(%d)",ret);
852 }
853exit_with_close:
854 if(gnss_info.gnss_close(gnss_info.fd)) {
855 LOGE("gnss_close() fail.");
856 }
857 if(gnss_info.exit_fd[0] > 0) {
858 close(gnss_info.exit_fd[0]);
859 gnss_info.exit_fd[0] = -1;
860 }
861 if(gnss_info.exit_fd[1] > 0) {
862 close(gnss_info.exit_fd[1]);
863 gnss_info.exit_fd[1] = -1;
864 }
865 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800866 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800867}
868
869int gnss_deinit()
870{
yq.wang069ea922024-09-08 19:29:35 -0700871#if MBTK_GNSS_TEST_LOG
872 gnss_test_log("[gnss_deinit] gnss state [%d]", gnss_info.state);
873#endif
874
b.liu8f231a12024-05-31 17:55:06 +0800875 if(gnss_info.state == GNSS_STATE_CLOSE) {
876 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +0800877 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800878 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
879 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +0800880 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800881 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
882 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +0800883 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800884 }
885
b.liu978f5432024-07-01 18:04:18 +0800886 if(gnss_info.gnss_dev_close(gnss_info.fd)) {
887 LOGE("gnss_dev_close() fail.");
888 return GNSS_ERR_UNKNOWN;
889 }
890
b.liu8f231a12024-05-31 17:55:06 +0800891 // Wait for read thread exit.
892 if(gnss_info.exit_fd[1] > 0) {
b.liu9e8584b2024-11-06 19:21:28 +0800893 mbtk_write(gnss_info.exit_fd[1], "exit", 4);
b.liu8f231a12024-05-31 17:55:06 +0800894 }
895
896 gnss_info.state = GNSS_STATE_CLOSING;
yq.wang069ea922024-09-08 19:29:35 -0700897
898#if MBTK_GNSS_TEST_LOG
899 gnss_test_log("wait gnss pthread exit...");
900#endif
b.liu8f231a12024-05-31 17:55:06 +0800901 int ret = pthread_join(gnss_info.read_pid, NULL);
902 if(ret){
903 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +0800904 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800905 }
906
907 if(gnss_info.gnss_close(gnss_info.fd)) {
908 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800909 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800910 }
911
b.liu8f231a12024-05-31 17:55:06 +0800912 if(gnss_ports_close()) {
913 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800914 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800915 }
916
yq.wang069ea922024-09-08 19:29:35 -0700917#if MBTK_GNSS_TEST_LOG
918 gnss_test_log("gnss_ports_close() complete.");
919#endif
b.liud0ba7152024-06-19 14:47:21 +0800920 LOGD("gnss_ports_close() complete.");
921
b.liu8f231a12024-05-31 17:55:06 +0800922 gnss_info.fd = -1;
923 if(gnss_info.exit_fd[0] > 0) {
924 close(gnss_info.exit_fd[0]);
925 gnss_info.exit_fd[0] = -1;
926 }
927 if(gnss_info.exit_fd[1] > 0) {
928 close(gnss_info.exit_fd[1]);
929 gnss_info.exit_fd[1] = -1;
930 }
931 gnss_info.state = GNSS_STATE_CLOSE;
yq.wang069ea922024-09-08 19:29:35 -0700932#if MBTK_GNSS_TEST_LOG
933 gnss_test_log("gnss close success.");
934#endif
b.liu8f231a12024-05-31 17:55:06 +0800935 LOGD("GNSS close success.");
yq.wang069ea922024-09-08 19:29:35 -0700936
b.liudbc3f4b2024-06-25 18:22:24 +0800937 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800938}
939
940int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
941{
b.liud0ba7152024-06-19 14:47:21 +0800942 if(buf && buf_len > 0) {
943 if(cmd_rsp && cmd_rsp_len > 0) {
944 memset(cmd_rsp, 0, cmd_rsp_len);
945 }
b.liu8f231a12024-05-31 17:55:06 +0800946 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
947 } else {
b.liudbc3f4b2024-06-25 18:22:24 +0800948 return GNSS_ERR_UNKNOWN;
949 }
950}
951
952int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
953{
b.liu42f558e2024-07-18 14:06:49 +0800954 // Only 8122 support download fw.
b.liudbc3f4b2024-06-25 18:22:24 +0800955 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
956 return GNSS_ERR_UNSUPPORT;
957 }
958
959 if(rsp && rsp_len > 0) {
960 memset(rsp, 0, rsp_len);
961 }
962
963 if(gnss_info.gnss_fw_dl) {
964 if(GNSS_ERR_OK != gnss_deinit()) {
965 LOGE("Close gnss fail.");
966 return GNSS_ERR_UNKNOWN;
967 } else {
968 LOGD("Start gnss fw dl.");
969 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
970 }
971 } else {
b.liu42f558e2024-07-18 14:06:49 +0800972 return GNSS_ERR_UNSUPPORT;
b.liu8f231a12024-05-31 17:55:06 +0800973 }
974}
975
yq.wang99db6f52024-09-12 01:58:48 -0700976int gnss_agnss_get_eph(const void* param)
977{
978 if(gnss_info.gnss_agnss_get_eph)
979 {
980 return gnss_info.gnss_agnss_get_eph(param);
981 }
982 else
983 {
984 return GNSS_ERR_UNSUPPORT;
985 }
986
987 return GNSS_ERR_OK;
988}
989
990int gnss_agnss_inject(void)
991{
992 if(gnss_info.state != GNSS_STATE_READY)
993 {
994 LOGE("gnss not ready");
995 return GNSS_ERR_UNKNOWN;
996 }
b.liu9e8584b2024-11-06 19:21:28 +0800997
yq.wang99db6f52024-09-12 01:58:48 -0700998 if(gnss_info.gnss_agnss_inject)
999 {
1000 return gnss_info.gnss_agnss_inject(gnss_info.fd);
1001 }
1002 else
1003 {
1004 return GNSS_ERR_UNSUPPORT;
1005 }
b.liu9e8584b2024-11-06 19:21:28 +08001006
yq.wang99db6f52024-09-12 01:58:48 -07001007 return GNSS_ERR_OK;
1008}
1009
b.liue77ac3a2024-07-17 17:36:57 +08001010int gnss_ind_set(int fd, int ind_type)
1011{
1012 int index = 0;
1013 if(ind_type) { // Add IND flag.
1014 while(index < GNSS_CLI_IND_MAX) {
1015 if(ind_info[index].cli_fd == fd)
1016 break;
1017 index++;
1018 }
1019
1020 if(index == GNSS_CLI_IND_MAX) { // Add flag
1021 index = 0;
1022 while(index < GNSS_CLI_IND_MAX) {
1023 if(ind_info[index].cli_fd <= 0)
1024 break;
1025 index++;
1026 }
yq.wang1ddd1fd2024-07-25 23:00:14 -07001027 if(index == GNSS_CLI_IND_MAX)
1028 {
1029 LOGE("ind flag is full.");
1030 return GNSS_ERR_CLI_FULL;
1031 }
b.liue77ac3a2024-07-17 17:36:57 +08001032 ind_info[index].cli_fd = fd;
1033 ind_info[index].ind_flag = (uint32)ind_type;
b.liubcf86c92024-08-19 19:48:28 +08001034 } else { // Change flag
b.liue77ac3a2024-07-17 17:36:57 +08001035 ind_info[index].cli_fd = fd;
1036 ind_info[index].ind_flag = (uint32)ind_type;
1037 }
1038 } else { // Clear IND flag.
1039 while(index < GNSS_CLI_IND_MAX) {
1040 if(ind_info[index].cli_fd == fd)
1041 break;
1042 index++;
1043 }
1044
1045 if(index == GNSS_CLI_IND_MAX) {
1046 return GNSS_ERR_ARG;
b.liubcf86c92024-08-19 19:48:28 +08001047 }
b.liue77ac3a2024-07-17 17:36:57 +08001048 ind_info[index].cli_fd = 0;
1049 ind_info[index].ind_flag = 0;
1050 }
1051
1052 return GNSS_ERR_OK;
1053}
1054
b.liu8f231a12024-05-31 17:55:06 +08001055static void sig_process(int sig)
1056{
1057 LOGI("I got signal %d\n", sig);
1058 if(gnss_deinit()) {
1059 LOGE("gnss_deinit() fail, no exist...");
1060 return;
1061 }
1062
1063 switch(sig)
1064 {
1065 case SIGINT: // Ctrl + C
1066 {
1067 LOGI("Exit by SIGINT.\n");
1068 exit(0);
1069 }
luojiand7960682024-08-02 16:50:01 +08001070 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 +08001071 {
1072 LOGI("Exit by SIGQUIT.\n");
1073 exit(0);
1074 }
luojiand7960682024-08-02 16:50:01 +08001075 case SIGTERM:// Ĭ\C8\CFkill (ͬ SIGKILL \A3\AC\B5\AB SIGKILL \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001076 {
1077 LOGI("Exit by SIGTERM.\n");
1078 exit(0);
1079 }
luojiand7960682024-08-02 16:50:01 +08001080 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP \A3\AC\B5\AB SIGSTOP \B2\BB\BFɲ\B6\BB\F1)
b.liu8f231a12024-05-31 17:55:06 +08001081 {
1082 LOGI("Exit by SIGTSTP.\n");
1083 exit(0);
1084 }
luojiand7960682024-08-02 16:50:01 +08001085 case SIGSEGV: // \C8\E7\BF\D5Ö¸\D5\EB
b.liu8f231a12024-05-31 17:55:06 +08001086 {
1087 LOGI("Exit by SIGSEGV.\n");
1088 exit(0);
1089 }
1090 default:
1091 {
1092 LOGI("Unknown sig:%d\n",sig);
1093 break;
1094 }
1095 }
1096}
1097
1098
b.liuced8dd02024-06-28 13:28:29 +08001099// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +08001100int main(int argc, char *argv[])
1101{
1102 mbtk_log_init("radio", GNSS_TAG);
1103
b.liubcf86c92024-08-19 19:48:28 +08001104 MBTK_SOURCE_INFO_PRINT("mbtk_gnssd");
1105
b.liubb590492024-06-13 16:42:08 +08001106#ifdef MBTK_DUMP_SUPPORT
1107 mbtk_debug_open(NULL, TRUE);
1108#endif
1109
b.liu8f231a12024-05-31 17:55:06 +08001110 signal(SIGINT, sig_process);
1111 signal(SIGQUIT, sig_process);
1112 signal(SIGTERM, sig_process);
1113
1114 if(arg_check(argc, argv)) {
1115 return -1;
1116 }
1117
1118#ifdef GNSS_DEBUG
1119 char buff[10];
1120 memset(buff, 0, 10);
1121 property_get(MBTK_PROP_GNSS_LOG, buff, "");
1122 if(strlen(buff) > 0 && atoi(buff) > 0) {
1123 nmea_log_enable = TRUE;
1124 }
1125#endif
1126
1127 memset(&gnss_info, 0, sizeof(gnss_info_t));
1128 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
1129 gnss_info.state = GNSS_STATE_CLOSE;
1130 if(!strcmp(argv[1], GNSS_ID_6228)) {
1131 gnss_info.gnss_id = GNSS_TYPE_6228;
1132 gnss_info.auto_open = (bool)atoi(argv[3]);
1133 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +08001134 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +08001135 gnss_info.gnss_dev_open = gnss_6228_dev_open;
1136 gnss_info.gnss_dev_close = gnss_6228_dev_close;
1137 gnss_info.gnss_open = gnss_6228_open;
1138 gnss_info.gnss_close = gnss_6228_close;
yq.wang36222352024-11-06 03:31:24 -08001139 gnss_info.gnss_init_set = NULL;
b.liu8f231a12024-05-31 17:55:06 +08001140 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
1141 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
1142 gnss_info.gnss_set = gnss_6228_set;
1143 gnss_info.gnss_set_cb = gnss_6228_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001144 gnss_info.gnss_agnss_get_eph = NULL;
1145 gnss_info.gnss_agnss_inject = NULL;
b.liuf9fbfa12024-06-14 15:53:59 +08001146 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
1147 gnss_info.gnss_id = GNSS_TYPE_8122;
1148 gnss_info.auto_open = (bool)atoi(argv[3]);
1149 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +08001150 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +08001151 gnss_info.gnss_dev_open = gnss_8122_dev_open;
1152 gnss_info.gnss_dev_close = gnss_8122_dev_close;
1153 gnss_info.gnss_open = gnss_8122_open;
1154 gnss_info.gnss_close = gnss_8122_close;
yq.wang36222352024-11-06 03:31:24 -08001155 gnss_info.gnss_init_set = gnss_8122_init_set;
b.liuf9fbfa12024-06-14 15:53:59 +08001156 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
1157 gnss_info.gnss_dl_read_cb = NULL;
1158 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +08001159 gnss_info.gnss_set_cb = gnss_8122_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001160 gnss_info.gnss_agnss_get_eph = gnss_8122_agnss_get_eph;
1161 gnss_info.gnss_agnss_inject = gnss_8122_agnss_inject;
b.liu99c645d2024-06-20 10:52:15 +08001162 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
1163 gnss_info.gnss_id = GNSS_TYPE_5311;
1164 gnss_info.auto_open = (bool)atoi(argv[3]);
1165 gnss_info.auto_dl_fw = TRUE;
1166 gnss_info.dl_befor_open = TRUE;
1167 gnss_info.gnss_dev_open = gnss_5311_dev_open;
1168 gnss_info.gnss_dev_close = gnss_5311_dev_close;
1169 gnss_info.gnss_open = gnss_5311_open;
1170 gnss_info.gnss_close = gnss_5311_close;
yq.wang36222352024-11-06 03:31:24 -08001171 gnss_info.gnss_init_set = NULL;
b.liu99c645d2024-06-20 10:52:15 +08001172 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
1173 gnss_info.gnss_dl_read_cb = NULL;
1174 gnss_info.gnss_set = gnss_5311_set;
1175 gnss_info.gnss_set_cb = gnss_5311_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001176 gnss_info.gnss_agnss_get_eph = NULL;
1177 gnss_info.gnss_agnss_inject = NULL;
b.liu42f558e2024-07-18 14:06:49 +08001178 } else if(!strcmp(argv[1], GNSS_ID_N50DB)) {
1179 gnss_info.gnss_id = GNSS_TYPE_N50DB;
1180 gnss_info.auto_open = (bool)atoi(argv[3]);
1181 gnss_info.auto_dl_fw = FALSE;
1182 gnss_info.dl_befor_open = FALSE;
1183 gnss_info.gnss_dev_open = gnss_n50db_dev_open;
1184 gnss_info.gnss_dev_close = gnss_n50db_dev_close;
1185 gnss_info.gnss_open = gnss_n50db_open;
1186 gnss_info.gnss_close = gnss_n50db_close;
yq.wang36222352024-11-06 03:31:24 -08001187 gnss_info.gnss_init_set = NULL;
b.liu42f558e2024-07-18 14:06:49 +08001188 gnss_info.gnss_fw_dl = gnss_n50db_fw_dl;
1189 gnss_info.gnss_dl_read_cb = NULL;
1190 gnss_info.gnss_set = gnss_n50db_set;
1191 gnss_info.gnss_set_cb = gnss_n50db_set_cb;
yq.wang99db6f52024-09-12 01:58:48 -07001192 gnss_info.gnss_agnss_get_eph = NULL;
1193 gnss_info.gnss_agnss_inject = NULL;
b.liu8f231a12024-05-31 17:55:06 +08001194 } else {
1195 LOGE("No support : %s", argv[1]);
1196 return -1;
1197 }
1198
1199 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
1200 // Auto open gnss.
1201 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +08001202 int init_mode = atoi(argv[3]);
1203 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
1204 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +08001205 }
b.liuced8dd02024-06-28 13:28:29 +08001206 if(gnss_init((uint32)init_mode)) {
1207 LOGE("gnss_init() fail.");
1208 // return -1;
1209 }
1210 } else {
1211 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +08001212 }
1213
b.liua1b69262024-09-04 16:32:59 +08001214#if MBTK_GNSS_PTY_AUTO_INIT
1215 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
1216 LOGE("gnss_pty_open() fail.");
1217 return -1;
1218 }
1219#endif
1220
yq.wang069ea922024-09-08 19:29:35 -07001221#if MBTK_GNSS_TEST_LOG
1222 gnss_test_log("gnss init success.");
1223#endif
b.liu8f231a12024-05-31 17:55:06 +08001224 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +08001225#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +08001226 if(gnss_ubus_init()) {
1227 LOGD("main() run...");
1228 uloop_run();
1229 } else {
1230 LOGE("gnss_ubus_init() fail.");
1231 }
b.liu5f950c52024-06-15 20:13:12 +08001232#else
1233 if(!gnss_ipc_service_start()) {
1234 LOGD("main() run...");
1235 while(1) {
1236 sleep(24 * 60 * 60);
1237 }
1238 } else {
1239 LOGE("gnss_ipc_service_start() fail.");
1240 }
1241#endif
b.liu8f231a12024-05-31 17:55:06 +08001242
1243 LOGD("main() exit.");
1244 return 0;
1245}