blob: 5109126fe71269a985d921d55eca2b3e0dba7b02 [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"
21
b.liu8f231a12024-05-31 17:55:06 +080022
23#define GNSS_DEBUG 1
b.liud0ba7152024-06-19 14:47:21 +080024#define GNSS_UBUS_ENABLE 1
b.liu8f231a12024-05-31 17:55:06 +080025
26#define GNSS_TAG "MBTK_GNSS"
27#define GNSS_BUFF_SIZE 2048
28#define MBTK_PROP_GNSS_LOG "persist.mbtk.gnss_log_enable"
29#define GNSS_PORT_PTY "/dev/tty_gnss_nmea"
30#define GNSS_PORT_USB_AT "/dev/ttyGS0"
31#define GNSS_PORT_USB_NMEA "/dev/ttymodem0"
32#define GNSS_PORT_UART_AT "/dev/ttyS1"
33
34#ifdef GNSS_DEBUG
35#define GNSS_NMEA_FILE_LOG "/tmp/mbtk_gnss_nmea.log"
b.liu8f231a12024-05-31 17:55:06 +080036#define GNSS_FILE_LOG "/tmp/mbtk_gnss.log"
b.liu99c645d2024-06-20 10:52:15 +080037#define GNSS_FILE_LOG_MAX 104857600 // 100MB
b.liu8f231a12024-05-31 17:55:06 +080038#endif
39
40gnss_info_t gnss_info;
41
b.liud0ba7152024-06-19 14:47:21 +080042#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080043struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080044#else
45int gnss_ipc_service_start();
46#endif
47
b.liu8f231a12024-05-31 17:55:06 +080048int gnss_init_config(int fd);
49
wangyouqiangfa897f82024-06-27 09:44:55 +080050static char nmea_buff[GNSS_BUFF_SIZE*4] = {0};
51static char data_buff[GNSS_BUFF_SIZE*4] = {0};
b.liud0ba7152024-06-19 14:47:21 +080052static uint32 nmea_buff_len = 0;
53static uint32 data_buff_len = 0;
54
b.liu8f231a12024-05-31 17:55:06 +080055static bool nmea_found = FALSE;
56#ifdef GNSS_DEBUG
57static bool nmea_log_enable = FALSE;
58static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080059static int debug_fd = -1;
60static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080061#endif
62static int gnss_pty_master_fd = -1;
63static int gnss_pty_slave_fd = -1;
64static int gnss_usb_at_port_fd = -1;
65static int gnss_usb_nmea_port_fd = -1;
66static int gnss_uart_at_port_fd = -1;
67static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
68
69static void help()
70{
b.liu99c645d2024-06-20 10:52:15 +080071 LOGD("mbtk_gnssd <6228/8122/5311> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080072}
73
74static int arg_check(int argc, char *argv[])
75{
76 if(argc != 4) {
b.liu4ae41182024-06-28 16:30:15 +080077 LOGE("argc = %d", argc);
b.liu8f231a12024-05-31 17:55:06 +080078 goto check_fail;
79 }
80
b.liu99c645d2024-06-20 10:52:15 +080081 // Only support 6228/8122/5311.
82 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)) {
b.liu4ae41182024-06-28 16:30:15 +080083 LOGE("argv[1] = %s", argv[1]);
b.liu8f231a12024-05-31 17:55:06 +080084 goto check_fail;
85 }
86
87 if(access(argv[2], R_OK | W_OK)) {
b.liu4ae41182024-06-28 16:30:15 +080088 LOGE("access(%s) rw fail. ", argv[2]);
b.liu8f231a12024-05-31 17:55:06 +080089 goto check_fail;
90 }
91
b.liuced8dd02024-06-28 13:28:29 +080092#if 0
93 int init_mode = atoi(argv[3]);
94 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 +080095 goto check_fail;
96 }
b.liuced8dd02024-06-28 13:28:29 +080097#endif
b.liu8f231a12024-05-31 17:55:06 +080098
99 return 0;
100check_fail:
101 help();
102 return -1;
103}
104
105static int gnss_ports_open(uint32 print_port)
106{
b.liuced8dd02024-06-28 13:28:29 +0800107 // TTY AT change.
108 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
109 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
110 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
111 return GNSS_ERR_OPEN_DEV;
112 }
113 LOGD("Open PTY port success.");
114 } else { // Close
115 if(gnss_pty_slave_fd > 0) {
116 close(gnss_pty_slave_fd);
117 gnss_pty_slave_fd = -1;
118 unlink(GNSS_PORT_PTY);
119 }
120 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800121 }
b.liu8f231a12024-05-31 17:55:06 +0800122 }
123
b.liuced8dd02024-06-28 13:28:29 +0800124 // USB AT change.
125 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
126 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
b.liu978f5432024-07-01 18:04:18 +0800127 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 +0800128 return GNSS_ERR_OPEN_DEV;
129 }
130 LOGD("Open USB AT port success.");
131 } else { // Close
132 if(gnss_usb_at_port_fd > 0) {
133 close(gnss_usb_at_port_fd);
134 gnss_usb_at_port_fd = -1;
135 }
136 LOGD("Close USB AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800137 }
b.liu8f231a12024-05-31 17:55:06 +0800138 }
139
b.liuced8dd02024-06-28 13:28:29 +0800140 // USB NMEA change.
141 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
142 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
b.liu978f5432024-07-01 18:04:18 +0800143 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 +0800144 return GNSS_ERR_OPEN_DEV;
145 }
146 LOGD("Open USB NMEA port success.");
147 } else { // Close
148 if(gnss_usb_nmea_port_fd > 0) {
149 close(gnss_usb_nmea_port_fd);
150 gnss_usb_nmea_port_fd = -1;
151 }
152 LOGD("Close USB NMEA port success.");
b.liu8f231a12024-05-31 17:55:06 +0800153 }
b.liu8f231a12024-05-31 17:55:06 +0800154 }
155
b.liuced8dd02024-06-28 13:28:29 +0800156 // Uart AT change.
157 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
158 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
159 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
160 return GNSS_ERR_OPEN_DEV;
161 }
162 LOGD("Open UART AT port success.");
163 } else { // Close
164 if(gnss_uart_at_port_fd > 0) {
165 close(gnss_uart_at_port_fd);
166 gnss_uart_at_port_fd = -1;
167 }
168 LOGD("Close UART AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800169 }
b.liu8f231a12024-05-31 17:55:06 +0800170 }
171
b.liuced8dd02024-06-28 13:28:29 +0800172 gnss_info.print_port = print_port;
173
b.liudbc3f4b2024-06-25 18:22:24 +0800174 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800175}
176
177static int gnss_ports_close()
178{
179 if(gnss_usb_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800180 tcflush(gnss_usb_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800181 close(gnss_usb_at_port_fd);
182 gnss_usb_at_port_fd = -1;
183 }
184
185 if(gnss_usb_nmea_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800186 tcflush(gnss_usb_nmea_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800187 close(gnss_usb_nmea_port_fd);
188 gnss_usb_nmea_port_fd = -1;
189 }
190
191 if(gnss_uart_at_port_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800192 tcflush(gnss_uart_at_port_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800193 close(gnss_uart_at_port_fd);
194 gnss_uart_at_port_fd = -1;
195 }
196
197 if(gnss_pty_master_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800198 tcflush(gnss_pty_master_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800199 close(gnss_pty_master_fd);
200 gnss_pty_master_fd = -1;
201 }
202
203 if(gnss_pty_slave_fd > 0) {
b.liu978f5432024-07-01 18:04:18 +0800204 tcflush(gnss_pty_slave_fd, TCIOFLUSH);
b.liu8f231a12024-05-31 17:55:06 +0800205 close(gnss_pty_slave_fd);
206 gnss_pty_slave_fd = -1;
207 unlink(GNSS_PORT_PTY);
208 }
209
b.liuced8dd02024-06-28 13:28:29 +0800210 gnss_info.print_port = 0;
211
b.liu8f231a12024-05-31 17:55:06 +0800212 return 0;
213}
214
b.liu8f231a12024-05-31 17:55:06 +0800215#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800216static void log_save(int fd, const char *data, int data_len)
217{
b.liu8f231a12024-05-31 17:55:06 +0800218 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800219 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
220 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
221 close(debug_fd);
222 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
223 if(debug_fd < 0) {
224 LOGE("Open debug fd fail.");
225 }
226 debug_fd_len = 0;
227
228 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800229 close(nmea_log_fd);
230 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
231 if(nmea_log_fd < 0) {
232 LOGE("Open debug fd fail.");
233 }
b.liu8f231a12024-05-31 17:55:06 +0800234 }
235
b.liu99c645d2024-06-20 10:52:15 +0800236 if(fd == nmea_log_fd) {
237 if(nmea_log_fd > 0) {
238 write(nmea_log_fd, data, data_len);
239 debug_fd_len += data_len;
240 }
241 } else if(fd == debug_fd) {
242 if(debug_fd > 0) {
243 write(debug_fd, data, data_len);
244 debug_fd_len += data_len;
245 }
b.liu8f231a12024-05-31 17:55:06 +0800246 }
247 }
b.liu99c645d2024-06-20 10:52:15 +0800248}
b.liu8f231a12024-05-31 17:55:06 +0800249#endif
250
b.liu99c645d2024-06-20 10:52:15 +0800251static void nmea_print(const char *nmea, int nmea_len)
252{
b.liu8f231a12024-05-31 17:55:06 +0800253 if(gnss_usb_at_port_fd > 0) {
254 write(gnss_usb_at_port_fd, nmea, nmea_len);
255 }
256
257 if(gnss_usb_nmea_port_fd > 0) {
258 write(gnss_usb_nmea_port_fd, nmea, nmea_len);
259 }
260
261 if(gnss_uart_at_port_fd > 0) {
262 write(gnss_uart_at_port_fd, nmea, nmea_len);
263 }
264
265 if(gnss_pty_master_fd > 0) {
266 write(gnss_pty_master_fd, nmea, nmea_len);
267 }
268}
269
270static unsigned char nmea_checksum(const char *nmea)
271{
272 const char *p = nmea;
273 unsigned char chs = 0;
274
275 while (*p == '$') // skip '$'
276 p++;
277 while (*p != '*' && *p != 0)
278 chs ^= *p++;
279
280 return chs;
281}
282
283static bool nmea_check(const char *nmea, int nmea_len)
284{
285 char **ptr = gnss_filter_info;
286 while(*ptr) {
287 if(strstr(nmea, *ptr)) {
288 break;
289 }
290 ptr++;
291 }
292
293 if(*ptr == NULL) {
294 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
295 return FALSE;
296 }
297
298 char *checksum_str = strstr(nmea, "*");
299 checksum_str++; // Jump '*'
300 char checksum_buf[3] = {0};
301 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
302 if(strncasecmp(checksum_buf, checksum_str, 2)) {
303 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
304 return FALSE;
305 }
306
307 return TRUE;
308}
309
310static void gnss_nmea_process(const char *data, int data_len)
311{
b.liu99c645d2024-06-20 10:52:15 +0800312 // LOGD("gnss_nmea_process() : data_len - %d", data_len);
313#if 0
b.liu8f231a12024-05-31 17:55:06 +0800314 char nmea[GNSS_BUFF_SIZE] = {0};
315 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800316#else
317 const char *nmea = data;
318#endif
b.liu8f231a12024-05-31 17:55:06 +0800319
320 if(!nmea_check(nmea, data_len)) {
b.liu99c645d2024-06-20 10:52:15 +0800321 LOGD("NO-NMEA:%s", nmea);
322#if GNSS_DEBUG
323 log_save(nmea_log_fd, "/**/", 4);
324 log_save(nmea_log_fd, nmea, data_len);
325#endif
326 if(gnss_info.gnss_set_cb)
327 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800328 return;
329 }
330
331#ifdef GNSS_DEBUG
332 if(nmea_log_enable) {
333 LOGD("NMEA[%d]:%s", data_len, nmea);
334 }
b.liu99c645d2024-06-20 10:52:15 +0800335
336 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800337#endif
338
339 nmea_print(nmea, data_len);
340}
341
342#if 0
343static void gnss_cmd_rsp_process(const char *data, int data_len)
344{
345 char rsp[GNSS_BUFF_SIZE] = {0};
346 memcpy(rsp, data, data_len);
347 LOGD("RSP[%d]:%s", data_len, rsp);
348}
349#endif
350
351static bool nmea_char_check(char ch)
352{
353 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
b.liu99c645d2024-06-20 10:52:15 +0800354 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=')
b.liu8f231a12024-05-31 17:55:06 +0800355 return TRUE;
356
357 return FALSE;
358}
359
360static void gnss_data_process(const char *data, int data_len)
361{
362 if(gnss_info.state == GNSS_STATE_OPEN) {
363 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
364 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
365 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800366 if(gnss_info.gnss_dl_read_cb) {
367 gnss_info.gnss_dl_read_cb(data, data_len);
368 }
b.liu8f231a12024-05-31 17:55:06 +0800369 } else if(gnss_info.state == GNSS_STATE_READY) {
370 int index = 0;
371 while(index < data_len) {
372 if(nmea_found) {
373 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800374 // Copy nmea_buff to data_buff
375 // Start with '$', but not nmea data, so copy to data_buff.
376 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
377 data_buff_len += nmea_buff_len;
378 data_buff[data_buff_len++] = data[index];
379
380 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800381 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800382 continue;
383 }
384
385 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800386 nmea_buff[nmea_buff_len++] = data[index];
387 if(nmea_buff[nmea_buff_len - 1] == '\n') {
388 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800389#if GNSS_DEBUG
390 log_save(nmea_log_fd, "/**/", 4);
391 log_save(nmea_log_fd, data_buff, data_buff_len);
392#endif
393 if(gnss_info.gnss_set_cb) {
394 gnss_info.gnss_set_cb(data_buff, data_buff_len);
395 }
b.liud0ba7152024-06-19 14:47:21 +0800396 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800397 }
398
b.liud0ba7152024-06-19 14:47:21 +0800399 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800400 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800401 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800402 } else if(nmea_buff_len > 0) {
403 nmea_buff[nmea_buff_len] = '\0';
404 LOGD("NO-NMEA:%s", nmea_buff);
405#if GNSS_DEBUG
406 log_save(nmea_log_fd, "/**/", 4);
407 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
408#endif
b.liud0ba7152024-06-19 14:47:21 +0800409 }
410
411 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800412 nmea_found = FALSE;
413 }
414 }
415 } else {
416 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800417 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800418 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800419 nmea_buff[nmea_buff_len++] = data[index];
420 } else {
421 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800422 }
423 }
424 index++;
425 }
426 } else {
427 LOGW("Unknown state : %d", gnss_info.state);
428 }
429}
430
431void* gnss_read_pthread(void* arg)
432{
433 LOGD("gnss_read_pthread enter.");
434 char buffer[GNSS_BUFF_SIZE];
435 int len = 0;
436 int ret = 0;
437 fd_set fdr, fdw;
438 int fd_max = 0;
439
b.liu8f231a12024-05-31 17:55:06 +0800440 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800441 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800442 memset(nmea_buff, 0, sizeof(nmea_buff));
443 memset(data_buff, 0, sizeof(data_buff));
444 nmea_buff_len = 0;
445 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800446#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800447 if(nmea_log_enable) {
448 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
449 if(debug_fd < 0) {
450 LOGE("Open debug fd fail.");
451 }
452 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
453 if(nmea_log_fd < 0) {
454 LOGE("Open nmea fd fail.");
455 }
b.liu99c645d2024-06-20 10:52:15 +0800456 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800457 }
458#endif
459
b.liudbc3f4b2024-06-25 18:22:24 +0800460 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
461
b.liu8f231a12024-05-31 17:55:06 +0800462 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800463 FD_ZERO(&fdw);
464 FD_ZERO(&fdr);
465 FD_SET(gnss_info.fd, &fdr);
466 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800467 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
468 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800469 if(gnss_info.state < GNSS_STATE_OPEN) {
470 LOGD("State = %d, ret = %d", gnss_info.state, ret);
471 if(ret > 0) {
472 if (FD_ISSET(gnss_info.fd, &fdr)) {
473 LOGD("gnss_fd can read.");
474 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
475 LOGD("exit_fd can read.");
476 } else {
477 LOGW("Unknown select event.");
478 }
479 }
480 break;
481 }
482
b.liu8f231a12024-05-31 17:55:06 +0800483 if (ret < 0)
484 {
485 if (errno == EINTR)
486 {
487 continue;
488 }
489 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
490 break;
491 }
492 else if (ret == 0)
493 {
494 LOGE("select ret == 0");
495 break;
496 }
497
498 if (FD_ISSET(gnss_info.fd, &fdr))
499 {
500 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800501 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800502 if(len > 0) {
503 //log_hex("READ", buffer, len);
504
505#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800506 //LOGD("read data_len = %d", len);
507 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800508#endif
509
510 gnss_data_process(buffer, len);
511
512 } else if(len ==0 ){
513 LOGE("Read end : len = 0");
514 break;
515 } else {
516 if(EAGAIN == errno) {
517 usleep(50000);
518 continue;
519 } else {
520 LOGD("Read ret = -1 ,errno = %d", errno);
521 break;
522 }
523 }
524 }
525 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
526 {
b.liuece0db02024-06-25 18:39:09 +0800527 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800528 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800529 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800530 if(len > 0) {
531 if(strcmp(buffer, "exit") == 0) {
532 LOGD("Get thread exit message.");
533 break;
534 }
535 }
536 }
537 else
538 {
539 LOGW("Unknown select event.");
540 continue;
541 }
542 }
543
544#if GNSS_DEBUG
545 if(debug_fd > 0) {
546 close(debug_fd);
547 debug_fd = -1;
548 }
549 if(nmea_log_fd > 0) {
550 close(nmea_log_fd);
551 nmea_log_fd = -1;
552 }
553#endif
554
555 gnss_info.state = GNSS_STATE_CLOSE;
556 LOGD("gnss_read_pthread exit.");
557 return NULL;
558}
559
560#if 0
561int gnss_write(int fd, const void *data, int data_len)
562{
563 int count = 0;
564 int len = 0;
565 while(1)
566 {
567 len = write(fd, data + count, data_len - count);
568 if (len > 0)
569 {
570 count += len;
571 }
572 else
573 {
574 LOGE("write() fail,ret = %d,errno = %d", len, errno);
575 break;
576 }
577
578 if (count == data_len)
579 break;
580 }
581
582 return count;
583}
584#else
b.liu778645e2024-06-21 16:47:42 +0800585int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800586{
b.liu778645e2024-06-21 16:47:42 +0800587 ssize_t size;
588 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800589 ssize_t size_written;
590 if(GNSS_BUFF_SIZE < buf_len)
591 {
592 return -1;
593 }
594 for(size = 0; size < buf_len;)
595 {
596 size_to_wr = buf_len - size;
597 if( size_to_wr > GNSS_BUFF_SIZE)
598 size_to_wr = GNSS_BUFF_SIZE;
599
b.liu778645e2024-06-21 16:47:42 +0800600 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800601 if (size_written==-1)
602 {
603 return -1;
604 }
605 size += size_written;
606 if(size_written != size_to_wr)
607 {
608 return size;
609 }
610 }
611 // LOGD("SEND %d / %d", size, buf_len);
612 return size;
613}
614#endif
615
616int gnss_init(uint32 print_port)
617{
618 if(gnss_info.state != GNSS_STATE_CLOSE) {
619 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800620 if(gnss_info.state == GNSS_STATE_READY) {
621 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
622 if(gnss_info.print_port != print_port) {
623 return gnss_ports_open(print_port);
624 } else {
625 return GNSS_ERR_OK;
626 }
627 } else {
628 return GNSS_ERR_OK;
629 }
b.liu8f231a12024-05-31 17:55:06 +0800630 }
631
632 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800633 if(gnss_info.dl_befor_open) {
634 //if(gnss_info.auto_dl_fw) {
635 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800636 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800637 if(ret) {
638 LOGE("gnss_fw_dl() fail : %d", ret);
639 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800640 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800641 }
b.liu8f231a12024-05-31 17:55:06 +0800642
b.liu99c645d2024-06-20 10:52:15 +0800643 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
644 if(gnss_info.fd <= 0) {
645 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
646 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800647 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800648 }
649 if(pipe(gnss_info.exit_fd)) {
650 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800651 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800652 }
653 // GNSS is opened.
654 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800655
b.liu99c645d2024-06-20 10:52:15 +0800656#if 0
657 // Start gnss read thread.
658 pthread_attr_t thread_attr;
659 pthread_attr_init(&thread_attr);
660 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
661 {
662 LOGE("pthread_attr_setdetachstate() fail.");
663 goto main_exit;
664 }
b.liu8f231a12024-05-31 17:55:06 +0800665
b.liu99c645d2024-06-20 10:52:15 +0800666 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800667#else
b.liu99c645d2024-06-20 10:52:15 +0800668 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800669#endif
b.liu99c645d2024-06-20 10:52:15 +0800670 {
671 LOGE("pthread_create() fail.");
672 goto exit_with_close;
673 }
b.liu8f231a12024-05-31 17:55:06 +0800674
b.liu99c645d2024-06-20 10:52:15 +0800675 ret = gnss_info.gnss_dev_open();
676 if(ret) {
677 LOGE("gnss_dev_open() fail : %d", ret);
678 goto exit_with_thread_exit;
679 }
680 //}
681 } else {
682 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
683 if(gnss_info.fd <= 0) {
684 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
685 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800686 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800687 }
688 if(pipe(gnss_info.exit_fd)) {
689 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800690 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800691 }
692 // GNSS is opened.
693 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800694
b.liu99c645d2024-06-20 10:52:15 +0800695#if 0
696 // Start gnss read thread.
697 pthread_attr_t thread_attr;
698 pthread_attr_init(&thread_attr);
699 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
700 {
701 LOGE("pthread_attr_setdetachstate() fail.");
702 goto main_exit;
703 }
704
705 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
706#else
707 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
708#endif
709 {
710 LOGE("pthread_create() fail.");
711 goto exit_with_close;
712 }
713
714 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800715 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800716 LOGE("gnss_dev_open() fail : %d", ret);
717 goto exit_with_thread_exit;
718 }
b.liu8f231a12024-05-31 17:55:06 +0800719 }
720
721 // GNSS is ready, NMEA can print from uart.
722 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +0800723
724 LOGD("GNSS open success.");
725
b.liuced8dd02024-06-28 13:28:29 +0800726 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +0800727
b.liu8f231a12024-05-31 17:55:06 +0800728exit_with_thread_exit:
729 gnss_info.state = GNSS_STATE_CLOSING;
730 // Wait for read thread exit.
731 ret = pthread_join(gnss_info.read_pid, NULL);
732 if(ret){
733 LOGE("pthrad_join fail(%d)",ret);
734 }
735exit_with_close:
736 if(gnss_info.gnss_close(gnss_info.fd)) {
737 LOGE("gnss_close() fail.");
738 }
739 if(gnss_info.exit_fd[0] > 0) {
740 close(gnss_info.exit_fd[0]);
741 gnss_info.exit_fd[0] = -1;
742 }
743 if(gnss_info.exit_fd[1] > 0) {
744 close(gnss_info.exit_fd[1]);
745 gnss_info.exit_fd[1] = -1;
746 }
747 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800748 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800749}
750
751int gnss_deinit()
752{
753 if(gnss_info.state == GNSS_STATE_CLOSE) {
754 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +0800755 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800756 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
757 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +0800758 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800759 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
760 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +0800761 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800762 }
763
b.liu978f5432024-07-01 18:04:18 +0800764 if(gnss_info.gnss_dev_close(gnss_info.fd)) {
765 LOGE("gnss_dev_close() fail.");
766 return GNSS_ERR_UNKNOWN;
767 }
768
b.liu8f231a12024-05-31 17:55:06 +0800769 // Wait for read thread exit.
770 if(gnss_info.exit_fd[1] > 0) {
771 write(gnss_info.exit_fd[1], "exit", 4);
772 }
773
774 gnss_info.state = GNSS_STATE_CLOSING;
775 int ret = pthread_join(gnss_info.read_pid, NULL);
776 if(ret){
777 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +0800778 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800779 }
780
781 if(gnss_info.gnss_close(gnss_info.fd)) {
782 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800783 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800784 }
785
b.liu8f231a12024-05-31 17:55:06 +0800786 if(gnss_ports_close()) {
787 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800788 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800789 }
790
b.liud0ba7152024-06-19 14:47:21 +0800791 LOGD("gnss_ports_close() complete.");
792
b.liu8f231a12024-05-31 17:55:06 +0800793 gnss_info.fd = -1;
794 if(gnss_info.exit_fd[0] > 0) {
795 close(gnss_info.exit_fd[0]);
796 gnss_info.exit_fd[0] = -1;
797 }
798 if(gnss_info.exit_fd[1] > 0) {
799 close(gnss_info.exit_fd[1]);
800 gnss_info.exit_fd[1] = -1;
801 }
802 gnss_info.state = GNSS_STATE_CLOSE;
803 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +0800804 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800805}
806
807int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
808{
b.liud0ba7152024-06-19 14:47:21 +0800809 if(buf && buf_len > 0) {
810 if(cmd_rsp && cmd_rsp_len > 0) {
811 memset(cmd_rsp, 0, cmd_rsp_len);
812 }
b.liu8f231a12024-05-31 17:55:06 +0800813 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
814 } else {
b.liudbc3f4b2024-06-25 18:22:24 +0800815 return GNSS_ERR_UNKNOWN;
816 }
817}
818
819int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
820{
821 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
822 return GNSS_ERR_UNSUPPORT;
823 }
824
825 if(rsp && rsp_len > 0) {
826 memset(rsp, 0, rsp_len);
827 }
828
829 if(gnss_info.gnss_fw_dl) {
830 if(GNSS_ERR_OK != gnss_deinit()) {
831 LOGE("Close gnss fail.");
832 return GNSS_ERR_UNKNOWN;
833 } else {
834 LOGD("Start gnss fw dl.");
835 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
836 }
837 } else {
838 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800839 }
840}
841
842static void sig_process(int sig)
843{
844 LOGI("I got signal %d\n", sig);
845 if(gnss_deinit()) {
846 LOGE("gnss_deinit() fail, no exist...");
847 return;
848 }
849
850 switch(sig)
851 {
852 case SIGINT: // Ctrl + C
853 {
854 LOGI("Exit by SIGINT.\n");
855 exit(0);
856 }
857 case SIGQUIT: // Ctrl + \ (ÀàËÆ SIGINT £¬µ«Òª²úÉúcoreÎļþ)
858 {
859 LOGI("Exit by SIGQUIT.\n");
860 exit(0);
861 }
862 case SIGTERM:// ĬÈÏkill (ͬ SIGKILL £¬µ« SIGKILL ²»¿É²¶»ñ)
863 {
864 LOGI("Exit by SIGTERM.\n");
865 exit(0);
866 }
867 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP £¬µ« SIGSTOP ²»¿É²¶»ñ)
868 {
869 LOGI("Exit by SIGTSTP.\n");
870 exit(0);
871 }
872 case SIGSEGV: // Èç¿ÕÖ¸Õë
873 {
874 LOGI("Exit by SIGSEGV.\n");
875 exit(0);
876 }
877 default:
878 {
879 LOGI("Unknown sig:%d\n",sig);
880 break;
881 }
882 }
883}
884
885
b.liuced8dd02024-06-28 13:28:29 +0800886// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +0800887int main(int argc, char *argv[])
888{
889 mbtk_log_init("radio", GNSS_TAG);
890
b.liubb590492024-06-13 16:42:08 +0800891#ifdef MBTK_DUMP_SUPPORT
892 mbtk_debug_open(NULL, TRUE);
893#endif
894
b.liu8f231a12024-05-31 17:55:06 +0800895 signal(SIGINT, sig_process);
896 signal(SIGQUIT, sig_process);
897 signal(SIGTERM, sig_process);
898
899 if(arg_check(argc, argv)) {
900 return -1;
901 }
902
903#ifdef GNSS_DEBUG
904 char buff[10];
905 memset(buff, 0, 10);
906 property_get(MBTK_PROP_GNSS_LOG, buff, "");
907 if(strlen(buff) > 0 && atoi(buff) > 0) {
908 nmea_log_enable = TRUE;
909 }
910#endif
911
912 memset(&gnss_info, 0, sizeof(gnss_info_t));
913 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
914 gnss_info.state = GNSS_STATE_CLOSE;
915 if(!strcmp(argv[1], GNSS_ID_6228)) {
916 gnss_info.gnss_id = GNSS_TYPE_6228;
917 gnss_info.auto_open = (bool)atoi(argv[3]);
918 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +0800919 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800920 gnss_info.gnss_dev_open = gnss_6228_dev_open;
921 gnss_info.gnss_dev_close = gnss_6228_dev_close;
922 gnss_info.gnss_open = gnss_6228_open;
923 gnss_info.gnss_close = gnss_6228_close;
924 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
925 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
926 gnss_info.gnss_set = gnss_6228_set;
927 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +0800928 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
929 gnss_info.gnss_id = GNSS_TYPE_8122;
930 gnss_info.auto_open = (bool)atoi(argv[3]);
931 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +0800932 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +0800933 gnss_info.gnss_dev_open = gnss_8122_dev_open;
934 gnss_info.gnss_dev_close = gnss_8122_dev_close;
935 gnss_info.gnss_open = gnss_8122_open;
936 gnss_info.gnss_close = gnss_8122_close;
937 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
938 gnss_info.gnss_dl_read_cb = NULL;
939 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +0800940 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +0800941 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
942 gnss_info.gnss_id = GNSS_TYPE_5311;
943 gnss_info.auto_open = (bool)atoi(argv[3]);
944 gnss_info.auto_dl_fw = TRUE;
945 gnss_info.dl_befor_open = TRUE;
946 gnss_info.gnss_dev_open = gnss_5311_dev_open;
947 gnss_info.gnss_dev_close = gnss_5311_dev_close;
948 gnss_info.gnss_open = gnss_5311_open;
949 gnss_info.gnss_close = gnss_5311_close;
950 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
951 gnss_info.gnss_dl_read_cb = NULL;
952 gnss_info.gnss_set = gnss_5311_set;
953 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu8f231a12024-05-31 17:55:06 +0800954 } else {
955 LOGE("No support : %s", argv[1]);
956 return -1;
957 }
958
959 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
960 // Auto open gnss.
961 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +0800962 int init_mode = atoi(argv[3]);
963 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
964 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +0800965 }
b.liuced8dd02024-06-28 13:28:29 +0800966 if(gnss_init((uint32)init_mode)) {
967 LOGE("gnss_init() fail.");
968 // return -1;
969 }
970 } else {
971 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +0800972 }
973
974 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +0800975#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +0800976 if(gnss_ubus_init()) {
977 LOGD("main() run...");
978 uloop_run();
979 } else {
980 LOGE("gnss_ubus_init() fail.");
981 }
b.liu5f950c52024-06-15 20:13:12 +0800982#else
983 if(!gnss_ipc_service_start()) {
984 LOGD("main() run...");
985 while(1) {
986 sleep(24 * 60 * 60);
987 }
988 } else {
989 LOGE("gnss_ipc_service_start() fail.");
990 }
991#endif
b.liu8f231a12024-05-31 17:55:06 +0800992
993 LOGD("main() exit.");
994 return 0;
995}