blob: cfceb1ad5d025e74489c0a2d0d587b86fbf7b2a3 [file] [log] [blame]
b.liu8f231a12024-05-31 17:55:06 +08001#include <stdio.h>
2#include <stdlib.h>
3#include <unistd.h>
4#include <errno.h>
5#include <pthread.h>
6#include <fcntl.h>
7#include <libubox/ustream.h>
8#include <libubus.h>
9#include <signal.h>
10#include <cutils/properties.h>
b.liu778645e2024-06-21 16:47:42 +080011#include <ctype.h>
b.liu8f231a12024-05-31 17:55:06 +080012
13#include "mbtk_type.h"
14#include "mbtk_log.h"
15#include "gnss_info.h"
b.liu778645e2024-06-21 16:47:42 +080016#include "gnss_utils.h"
b.liu8f231a12024-05-31 17:55:06 +080017#include "gnss_6228.h"
b.liuf9fbfa12024-06-14 15:53:59 +080018#include "gnss_hd8122.h"
b.liu99c645d2024-06-20 10:52:15 +080019#include "gnss_asr5311.h"
20
b.liu8f231a12024-05-31 17:55:06 +080021
22#define GNSS_DEBUG 1
b.liud0ba7152024-06-19 14:47:21 +080023#define GNSS_UBUS_ENABLE 1
b.liu8f231a12024-05-31 17:55:06 +080024
25#define GNSS_TAG "MBTK_GNSS"
26#define GNSS_BUFF_SIZE 2048
27#define MBTK_PROP_GNSS_LOG "persist.mbtk.gnss_log_enable"
28#define GNSS_PORT_PTY "/dev/tty_gnss_nmea"
29#define GNSS_PORT_USB_AT "/dev/ttyGS0"
30#define GNSS_PORT_USB_NMEA "/dev/ttymodem0"
31#define GNSS_PORT_UART_AT "/dev/ttyS1"
32
33#ifdef GNSS_DEBUG
34#define GNSS_NMEA_FILE_LOG "/tmp/mbtk_gnss_nmea.log"
b.liu8f231a12024-05-31 17:55:06 +080035#define GNSS_FILE_LOG "/tmp/mbtk_gnss.log"
b.liu99c645d2024-06-20 10:52:15 +080036#define GNSS_FILE_LOG_MAX 104857600 // 100MB
b.liu8f231a12024-05-31 17:55:06 +080037#endif
38
39gnss_info_t gnss_info;
40
b.liud0ba7152024-06-19 14:47:21 +080041#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +080042struct ubus_context *gnss_ubus_init(void);
b.liu5f950c52024-06-15 20:13:12 +080043#else
44int gnss_ipc_service_start();
45#endif
46
b.liu8f231a12024-05-31 17:55:06 +080047int gnss_init_config(int fd);
48
wangyouqiangfa897f82024-06-27 09:44:55 +080049static char nmea_buff[GNSS_BUFF_SIZE*4] = {0};
50static char data_buff[GNSS_BUFF_SIZE*4] = {0};
b.liud0ba7152024-06-19 14:47:21 +080051static uint32 nmea_buff_len = 0;
52static uint32 data_buff_len = 0;
53
b.liu8f231a12024-05-31 17:55:06 +080054static bool nmea_found = FALSE;
55#ifdef GNSS_DEBUG
56static bool nmea_log_enable = FALSE;
57static int nmea_log_fd = -1;
b.liu99c645d2024-06-20 10:52:15 +080058static int debug_fd = -1;
59static int debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +080060#endif
61static int gnss_pty_master_fd = -1;
62static int gnss_pty_slave_fd = -1;
63static int gnss_usb_at_port_fd = -1;
64static int gnss_usb_nmea_port_fd = -1;
65static int gnss_uart_at_port_fd = -1;
66static char *gnss_filter_info[] = {"RMC", "VTG", "GGA", "GSA", "GSV", "GLL", "ZDA", "GST", "TXT", "DHV", "DTM", NULL};
67
68static void help()
69{
b.liu99c645d2024-06-20 10:52:15 +080070 LOGD("mbtk_gnssd <6228/8122/5311> <gnss_dev> <0/1>");
b.liu8f231a12024-05-31 17:55:06 +080071}
72
73static int arg_check(int argc, char *argv[])
74{
75 if(argc != 4) {
b.liu4ae41182024-06-28 16:30:15 +080076 LOGE("argc = %d", argc);
b.liu8f231a12024-05-31 17:55:06 +080077 goto check_fail;
78 }
79
b.liu99c645d2024-06-20 10:52:15 +080080 // Only support 6228/8122/5311.
81 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 +080082 LOGE("argv[1] = %s", argv[1]);
b.liu8f231a12024-05-31 17:55:06 +080083 goto check_fail;
84 }
85
86 if(access(argv[2], R_OK | W_OK)) {
b.liu4ae41182024-06-28 16:30:15 +080087 LOGE("access(%s) rw fail. ", argv[2]);
b.liu8f231a12024-05-31 17:55:06 +080088 goto check_fail;
89 }
90
b.liuced8dd02024-06-28 13:28:29 +080091#if 0
92 int init_mode = atoi(argv[3]);
93 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 +080094 goto check_fail;
95 }
b.liuced8dd02024-06-28 13:28:29 +080096#endif
b.liu8f231a12024-05-31 17:55:06 +080097
98 return 0;
99check_fail:
100 help();
101 return -1;
102}
103
104static int gnss_ports_open(uint32 print_port)
105{
b.liuced8dd02024-06-28 13:28:29 +0800106 // TTY AT change.
107 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
108 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
109 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
110 return GNSS_ERR_OPEN_DEV;
111 }
112 LOGD("Open PTY port success.");
113 } else { // Close
114 if(gnss_pty_slave_fd > 0) {
115 close(gnss_pty_slave_fd);
116 gnss_pty_slave_fd = -1;
117 unlink(GNSS_PORT_PTY);
118 }
119 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800120 }
b.liu8f231a12024-05-31 17:55:06 +0800121 }
122
b.liuced8dd02024-06-28 13:28:29 +0800123 // USB AT change.
124 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
125 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
126 if((gnss_usb_at_port_fd = gnss_port_open(GNSS_PORT_USB_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
127 return GNSS_ERR_OPEN_DEV;
128 }
129 LOGD("Open USB AT port success.");
130 } else { // Close
131 if(gnss_usb_at_port_fd > 0) {
132 close(gnss_usb_at_port_fd);
133 gnss_usb_at_port_fd = -1;
134 }
135 LOGD("Close USB AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800136 }
b.liu8f231a12024-05-31 17:55:06 +0800137 }
138
b.liuced8dd02024-06-28 13:28:29 +0800139 // USB NMEA change.
140 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
141 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
142 if((gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
143 return GNSS_ERR_OPEN_DEV;
144 }
145 LOGD("Open USB NMEA port success.");
146 } else { // Close
147 if(gnss_usb_nmea_port_fd > 0) {
148 close(gnss_usb_nmea_port_fd);
149 gnss_usb_nmea_port_fd = -1;
150 }
151 LOGD("Close USB NMEA port success.");
b.liu8f231a12024-05-31 17:55:06 +0800152 }
b.liu8f231a12024-05-31 17:55:06 +0800153 }
154
b.liuced8dd02024-06-28 13:28:29 +0800155 // Uart AT change.
156 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
157 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
158 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
159 return GNSS_ERR_OPEN_DEV;
160 }
161 LOGD("Open UART AT port success.");
162 } else { // Close
163 if(gnss_uart_at_port_fd > 0) {
164 close(gnss_uart_at_port_fd);
165 gnss_uart_at_port_fd = -1;
166 }
167 LOGD("Close UART AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800168 }
b.liu8f231a12024-05-31 17:55:06 +0800169 }
170
b.liuced8dd02024-06-28 13:28:29 +0800171 gnss_info.print_port = print_port;
172
b.liudbc3f4b2024-06-25 18:22:24 +0800173 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800174}
175
176static int gnss_ports_close()
177{
178 if(gnss_usb_at_port_fd > 0) {
179 close(gnss_usb_at_port_fd);
180 gnss_usb_at_port_fd = -1;
181 }
182
183 if(gnss_usb_nmea_port_fd > 0) {
184 close(gnss_usb_nmea_port_fd);
185 gnss_usb_nmea_port_fd = -1;
186 }
187
188 if(gnss_uart_at_port_fd > 0) {
189 close(gnss_uart_at_port_fd);
190 gnss_uart_at_port_fd = -1;
191 }
192
193 if(gnss_pty_master_fd > 0) {
194 close(gnss_pty_master_fd);
195 gnss_pty_master_fd = -1;
196 }
197
198 if(gnss_pty_slave_fd > 0) {
199 close(gnss_pty_slave_fd);
200 gnss_pty_slave_fd = -1;
201 unlink(GNSS_PORT_PTY);
202 }
203
b.liuced8dd02024-06-28 13:28:29 +0800204 gnss_info.print_port = 0;
205
b.liu8f231a12024-05-31 17:55:06 +0800206 return 0;
207}
208
b.liu8f231a12024-05-31 17:55:06 +0800209#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800210static void log_save(int fd, const char *data, int data_len)
211{
b.liu8f231a12024-05-31 17:55:06 +0800212 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800213 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
214 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
215 close(debug_fd);
216 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
217 if(debug_fd < 0) {
218 LOGE("Open debug fd fail.");
219 }
220 debug_fd_len = 0;
221
222 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800223 close(nmea_log_fd);
224 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
225 if(nmea_log_fd < 0) {
226 LOGE("Open debug fd fail.");
227 }
b.liu8f231a12024-05-31 17:55:06 +0800228 }
229
b.liu99c645d2024-06-20 10:52:15 +0800230 if(fd == nmea_log_fd) {
231 if(nmea_log_fd > 0) {
232 write(nmea_log_fd, data, data_len);
233 debug_fd_len += data_len;
234 }
235 } else if(fd == debug_fd) {
236 if(debug_fd > 0) {
237 write(debug_fd, data, data_len);
238 debug_fd_len += data_len;
239 }
b.liu8f231a12024-05-31 17:55:06 +0800240 }
241 }
b.liu99c645d2024-06-20 10:52:15 +0800242}
b.liu8f231a12024-05-31 17:55:06 +0800243#endif
244
b.liu99c645d2024-06-20 10:52:15 +0800245static void nmea_print(const char *nmea, int nmea_len)
246{
b.liu8f231a12024-05-31 17:55:06 +0800247 if(gnss_usb_at_port_fd > 0) {
248 write(gnss_usb_at_port_fd, nmea, nmea_len);
249 }
250
251 if(gnss_usb_nmea_port_fd > 0) {
252 write(gnss_usb_nmea_port_fd, nmea, nmea_len);
253 }
254
255 if(gnss_uart_at_port_fd > 0) {
256 write(gnss_uart_at_port_fd, nmea, nmea_len);
257 }
258
259 if(gnss_pty_master_fd > 0) {
260 write(gnss_pty_master_fd, nmea, nmea_len);
261 }
262}
263
264static unsigned char nmea_checksum(const char *nmea)
265{
266 const char *p = nmea;
267 unsigned char chs = 0;
268
269 while (*p == '$') // skip '$'
270 p++;
271 while (*p != '*' && *p != 0)
272 chs ^= *p++;
273
274 return chs;
275}
276
277static bool nmea_check(const char *nmea, int nmea_len)
278{
279 char **ptr = gnss_filter_info;
280 while(*ptr) {
281 if(strstr(nmea, *ptr)) {
282 break;
283 }
284 ptr++;
285 }
286
287 if(*ptr == NULL) {
288 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
289 return FALSE;
290 }
291
292 char *checksum_str = strstr(nmea, "*");
293 checksum_str++; // Jump '*'
294 char checksum_buf[3] = {0};
295 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
296 if(strncasecmp(checksum_buf, checksum_str, 2)) {
297 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
298 return FALSE;
299 }
300
301 return TRUE;
302}
303
304static void gnss_nmea_process(const char *data, int data_len)
305{
b.liu99c645d2024-06-20 10:52:15 +0800306 // LOGD("gnss_nmea_process() : data_len - %d", data_len);
307#if 0
b.liu8f231a12024-05-31 17:55:06 +0800308 char nmea[GNSS_BUFF_SIZE] = {0};
309 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800310#else
311 const char *nmea = data;
312#endif
b.liu8f231a12024-05-31 17:55:06 +0800313
314 if(!nmea_check(nmea, data_len)) {
b.liu99c645d2024-06-20 10:52:15 +0800315 LOGD("NO-NMEA:%s", nmea);
316#if GNSS_DEBUG
317 log_save(nmea_log_fd, "/**/", 4);
318 log_save(nmea_log_fd, nmea, data_len);
319#endif
320 if(gnss_info.gnss_set_cb)
321 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800322 return;
323 }
324
325#ifdef GNSS_DEBUG
326 if(nmea_log_enable) {
327 LOGD("NMEA[%d]:%s", data_len, nmea);
328 }
b.liu99c645d2024-06-20 10:52:15 +0800329
330 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800331#endif
332
333 nmea_print(nmea, data_len);
334}
335
336#if 0
337static void gnss_cmd_rsp_process(const char *data, int data_len)
338{
339 char rsp[GNSS_BUFF_SIZE] = {0};
340 memcpy(rsp, data, data_len);
341 LOGD("RSP[%d]:%s", data_len, rsp);
342}
343#endif
344
345static bool nmea_char_check(char ch)
346{
347 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
b.liu99c645d2024-06-20 10:52:15 +0800348 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=')
b.liu8f231a12024-05-31 17:55:06 +0800349 return TRUE;
350
351 return FALSE;
352}
353
354static void gnss_data_process(const char *data, int data_len)
355{
356 if(gnss_info.state == GNSS_STATE_OPEN) {
357 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
358 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
359 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800360 if(gnss_info.gnss_dl_read_cb) {
361 gnss_info.gnss_dl_read_cb(data, data_len);
362 }
b.liu8f231a12024-05-31 17:55:06 +0800363 } else if(gnss_info.state == GNSS_STATE_READY) {
364 int index = 0;
365 while(index < data_len) {
366 if(nmea_found) {
367 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800368 // Copy nmea_buff to data_buff
369 // Start with '$', but not nmea data, so copy to data_buff.
370 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
371 data_buff_len += nmea_buff_len;
372 data_buff[data_buff_len++] = data[index];
373
374 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800375 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800376 continue;
377 }
378
379 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800380 nmea_buff[nmea_buff_len++] = data[index];
381 if(nmea_buff[nmea_buff_len - 1] == '\n') {
382 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800383#if GNSS_DEBUG
384 log_save(nmea_log_fd, "/**/", 4);
385 log_save(nmea_log_fd, data_buff, data_buff_len);
386#endif
387 if(gnss_info.gnss_set_cb) {
388 gnss_info.gnss_set_cb(data_buff, data_buff_len);
389 }
b.liud0ba7152024-06-19 14:47:21 +0800390 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800391 }
392
b.liud0ba7152024-06-19 14:47:21 +0800393 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800394 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800395 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800396 } else if(nmea_buff_len > 0) {
397 nmea_buff[nmea_buff_len] = '\0';
398 LOGD("NO-NMEA:%s", nmea_buff);
399#if GNSS_DEBUG
400 log_save(nmea_log_fd, "/**/", 4);
401 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
402#endif
b.liud0ba7152024-06-19 14:47:21 +0800403 }
404
405 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800406 nmea_found = FALSE;
407 }
408 }
409 } else {
410 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800411 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800412 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800413 nmea_buff[nmea_buff_len++] = data[index];
414 } else {
415 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800416 }
417 }
418 index++;
419 }
420 } else {
421 LOGW("Unknown state : %d", gnss_info.state);
422 }
423}
424
425void* gnss_read_pthread(void* arg)
426{
427 LOGD("gnss_read_pthread enter.");
428 char buffer[GNSS_BUFF_SIZE];
429 int len = 0;
430 int ret = 0;
431 fd_set fdr, fdw;
432 int fd_max = 0;
433
b.liu8f231a12024-05-31 17:55:06 +0800434 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800435 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800436 memset(nmea_buff, 0, sizeof(nmea_buff));
437 memset(data_buff, 0, sizeof(data_buff));
438 nmea_buff_len = 0;
439 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800440#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800441 if(nmea_log_enable) {
442 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
443 if(debug_fd < 0) {
444 LOGE("Open debug fd fail.");
445 }
446 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
447 if(nmea_log_fd < 0) {
448 LOGE("Open nmea fd fail.");
449 }
b.liu99c645d2024-06-20 10:52:15 +0800450 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800451 }
452#endif
453
b.liudbc3f4b2024-06-25 18:22:24 +0800454 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
455
b.liu8f231a12024-05-31 17:55:06 +0800456 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800457 FD_ZERO(&fdw);
458 FD_ZERO(&fdr);
459 FD_SET(gnss_info.fd, &fdr);
460 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800461 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
462 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800463 if(gnss_info.state < GNSS_STATE_OPEN) {
464 LOGD("State = %d, ret = %d", gnss_info.state, ret);
465 if(ret > 0) {
466 if (FD_ISSET(gnss_info.fd, &fdr)) {
467 LOGD("gnss_fd can read.");
468 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
469 LOGD("exit_fd can read.");
470 } else {
471 LOGW("Unknown select event.");
472 }
473 }
474 break;
475 }
476
b.liu8f231a12024-05-31 17:55:06 +0800477 if (ret < 0)
478 {
479 if (errno == EINTR)
480 {
481 continue;
482 }
483 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
484 break;
485 }
486 else if (ret == 0)
487 {
488 LOGE("select ret == 0");
489 break;
490 }
491
492 if (FD_ISSET(gnss_info.fd, &fdr))
493 {
494 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800495 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800496 if(len > 0) {
497 //log_hex("READ", buffer, len);
498
499#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800500 //LOGD("read data_len = %d", len);
501 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800502#endif
503
504 gnss_data_process(buffer, len);
505
506 } else if(len ==0 ){
507 LOGE("Read end : len = 0");
508 break;
509 } else {
510 if(EAGAIN == errno) {
511 usleep(50000);
512 continue;
513 } else {
514 LOGD("Read ret = -1 ,errno = %d", errno);
515 break;
516 }
517 }
518 }
519 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
520 {
b.liuece0db02024-06-25 18:39:09 +0800521 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800522 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800523 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800524 if(len > 0) {
525 if(strcmp(buffer, "exit") == 0) {
526 LOGD("Get thread exit message.");
527 break;
528 }
529 }
530 }
531 else
532 {
533 LOGW("Unknown select event.");
534 continue;
535 }
536 }
537
538#if GNSS_DEBUG
539 if(debug_fd > 0) {
540 close(debug_fd);
541 debug_fd = -1;
542 }
543 if(nmea_log_fd > 0) {
544 close(nmea_log_fd);
545 nmea_log_fd = -1;
546 }
547#endif
548
549 gnss_info.state = GNSS_STATE_CLOSE;
550 LOGD("gnss_read_pthread exit.");
551 return NULL;
552}
553
554#if 0
555int gnss_write(int fd, const void *data, int data_len)
556{
557 int count = 0;
558 int len = 0;
559 while(1)
560 {
561 len = write(fd, data + count, data_len - count);
562 if (len > 0)
563 {
564 count += len;
565 }
566 else
567 {
568 LOGE("write() fail,ret = %d,errno = %d", len, errno);
569 break;
570 }
571
572 if (count == data_len)
573 break;
574 }
575
576 return count;
577}
578#else
b.liu778645e2024-06-21 16:47:42 +0800579int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800580{
b.liu778645e2024-06-21 16:47:42 +0800581 ssize_t size;
582 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800583 ssize_t size_written;
584 if(GNSS_BUFF_SIZE < buf_len)
585 {
586 return -1;
587 }
588 for(size = 0; size < buf_len;)
589 {
590 size_to_wr = buf_len - size;
591 if( size_to_wr > GNSS_BUFF_SIZE)
592 size_to_wr = GNSS_BUFF_SIZE;
593
b.liu778645e2024-06-21 16:47:42 +0800594 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800595 if (size_written==-1)
596 {
597 return -1;
598 }
599 size += size_written;
600 if(size_written != size_to_wr)
601 {
602 return size;
603 }
604 }
605 // LOGD("SEND %d / %d", size, buf_len);
606 return size;
607}
608#endif
609
610int gnss_init(uint32 print_port)
611{
612 if(gnss_info.state != GNSS_STATE_CLOSE) {
613 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800614 if(gnss_info.state == GNSS_STATE_READY) {
615 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
616 if(gnss_info.print_port != print_port) {
617 return gnss_ports_open(print_port);
618 } else {
619 return GNSS_ERR_OK;
620 }
621 } else {
622 return GNSS_ERR_OK;
623 }
b.liu8f231a12024-05-31 17:55:06 +0800624 }
625
626 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800627 if(gnss_info.dl_befor_open) {
628 //if(gnss_info.auto_dl_fw) {
629 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800630 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800631 if(ret) {
632 LOGE("gnss_fw_dl() fail : %d", ret);
633 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800634 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800635 }
b.liu8f231a12024-05-31 17:55:06 +0800636
b.liu99c645d2024-06-20 10:52:15 +0800637 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
638 if(gnss_info.fd <= 0) {
639 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
640 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800641 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800642 }
643 if(pipe(gnss_info.exit_fd)) {
644 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800645 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800646 }
647 // GNSS is opened.
648 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800649
b.liu99c645d2024-06-20 10:52:15 +0800650#if 0
651 // Start gnss read thread.
652 pthread_attr_t thread_attr;
653 pthread_attr_init(&thread_attr);
654 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
655 {
656 LOGE("pthread_attr_setdetachstate() fail.");
657 goto main_exit;
658 }
b.liu8f231a12024-05-31 17:55:06 +0800659
b.liu99c645d2024-06-20 10:52:15 +0800660 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800661#else
b.liu99c645d2024-06-20 10:52:15 +0800662 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800663#endif
b.liu99c645d2024-06-20 10:52:15 +0800664 {
665 LOGE("pthread_create() fail.");
666 goto exit_with_close;
667 }
b.liu8f231a12024-05-31 17:55:06 +0800668
b.liu99c645d2024-06-20 10:52:15 +0800669 ret = gnss_info.gnss_dev_open();
670 if(ret) {
671 LOGE("gnss_dev_open() fail : %d", ret);
672 goto exit_with_thread_exit;
673 }
674 //}
675 } else {
676 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
677 if(gnss_info.fd <= 0) {
678 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
679 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800680 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800681 }
682 if(pipe(gnss_info.exit_fd)) {
683 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800684 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800685 }
686 // GNSS is opened.
687 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800688
b.liu99c645d2024-06-20 10:52:15 +0800689#if 0
690 // Start gnss read thread.
691 pthread_attr_t thread_attr;
692 pthread_attr_init(&thread_attr);
693 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
694 {
695 LOGE("pthread_attr_setdetachstate() fail.");
696 goto main_exit;
697 }
698
699 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
700#else
701 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
702#endif
703 {
704 LOGE("pthread_create() fail.");
705 goto exit_with_close;
706 }
707
708 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800709 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800710 LOGE("gnss_dev_open() fail : %d", ret);
711 goto exit_with_thread_exit;
712 }
b.liu8f231a12024-05-31 17:55:06 +0800713 }
714
715 // GNSS is ready, NMEA can print from uart.
716 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +0800717
718 LOGD("GNSS open success.");
719
b.liuced8dd02024-06-28 13:28:29 +0800720 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +0800721
722exit_with_dev_close:
723 if(gnss_info.gnss_dev_close()) {
724 LOGE("gnss_dev_close() fail.");
725 }
726exit_with_thread_exit:
727 gnss_info.state = GNSS_STATE_CLOSING;
728 // Wait for read thread exit.
729 ret = pthread_join(gnss_info.read_pid, NULL);
730 if(ret){
731 LOGE("pthrad_join fail(%d)",ret);
732 }
733exit_with_close:
734 if(gnss_info.gnss_close(gnss_info.fd)) {
735 LOGE("gnss_close() fail.");
736 }
737 if(gnss_info.exit_fd[0] > 0) {
738 close(gnss_info.exit_fd[0]);
739 gnss_info.exit_fd[0] = -1;
740 }
741 if(gnss_info.exit_fd[1] > 0) {
742 close(gnss_info.exit_fd[1]);
743 gnss_info.exit_fd[1] = -1;
744 }
745 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800746 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800747}
748
749int gnss_deinit()
750{
751 if(gnss_info.state == GNSS_STATE_CLOSE) {
752 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +0800753 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800754 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
755 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +0800756 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800757 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
758 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +0800759 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800760 }
761
762 // Wait for read thread exit.
763 if(gnss_info.exit_fd[1] > 0) {
764 write(gnss_info.exit_fd[1], "exit", 4);
765 }
766
767 gnss_info.state = GNSS_STATE_CLOSING;
768 int ret = pthread_join(gnss_info.read_pid, NULL);
769 if(ret){
770 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +0800771 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800772 }
773
774 if(gnss_info.gnss_close(gnss_info.fd)) {
775 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800776 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800777 }
778
779 if(gnss_info.gnss_dev_close()) {
780 LOGE("gnss_dev_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800781 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800782 }
783
784 if(gnss_ports_close()) {
785 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800786 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800787 }
788
b.liud0ba7152024-06-19 14:47:21 +0800789 LOGD("gnss_ports_close() complete.");
790
b.liu8f231a12024-05-31 17:55:06 +0800791 gnss_info.fd = -1;
792 if(gnss_info.exit_fd[0] > 0) {
793 close(gnss_info.exit_fd[0]);
794 gnss_info.exit_fd[0] = -1;
795 }
796 if(gnss_info.exit_fd[1] > 0) {
797 close(gnss_info.exit_fd[1]);
798 gnss_info.exit_fd[1] = -1;
799 }
800 gnss_info.state = GNSS_STATE_CLOSE;
801 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +0800802 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800803}
804
805int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
806{
b.liud0ba7152024-06-19 14:47:21 +0800807 if(buf && buf_len > 0) {
808 if(cmd_rsp && cmd_rsp_len > 0) {
809 memset(cmd_rsp, 0, cmd_rsp_len);
810 }
b.liu8f231a12024-05-31 17:55:06 +0800811 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
812 } else {
b.liudbc3f4b2024-06-25 18:22:24 +0800813 return GNSS_ERR_UNKNOWN;
814 }
815}
816
817int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
818{
819 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
820 return GNSS_ERR_UNSUPPORT;
821 }
822
823 if(rsp && rsp_len > 0) {
824 memset(rsp, 0, rsp_len);
825 }
826
827 if(gnss_info.gnss_fw_dl) {
828 if(GNSS_ERR_OK != gnss_deinit()) {
829 LOGE("Close gnss fail.");
830 return GNSS_ERR_UNKNOWN;
831 } else {
832 LOGD("Start gnss fw dl.");
833 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
834 }
835 } else {
836 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800837 }
838}
839
840static void sig_process(int sig)
841{
842 LOGI("I got signal %d\n", sig);
843 if(gnss_deinit()) {
844 LOGE("gnss_deinit() fail, no exist...");
845 return;
846 }
847
848 switch(sig)
849 {
850 case SIGINT: // Ctrl + C
851 {
852 LOGI("Exit by SIGINT.\n");
853 exit(0);
854 }
855 case SIGQUIT: // Ctrl + \ (ÀàËÆ SIGINT £¬µ«Òª²úÉúcoreÎļþ)
856 {
857 LOGI("Exit by SIGQUIT.\n");
858 exit(0);
859 }
860 case SIGTERM:// ĬÈÏkill (ͬ SIGKILL £¬µ« SIGKILL ²»¿É²¶»ñ)
861 {
862 LOGI("Exit by SIGTERM.\n");
863 exit(0);
864 }
865 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP £¬µ« SIGSTOP ²»¿É²¶»ñ)
866 {
867 LOGI("Exit by SIGTSTP.\n");
868 exit(0);
869 }
870 case SIGSEGV: // Èç¿ÕÖ¸Õë
871 {
872 LOGI("Exit by SIGSEGV.\n");
873 exit(0);
874 }
875 default:
876 {
877 LOGI("Unknown sig:%d\n",sig);
878 break;
879 }
880 }
881}
882
883
b.liuced8dd02024-06-28 13:28:29 +0800884// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +0800885int main(int argc, char *argv[])
886{
887 mbtk_log_init("radio", GNSS_TAG);
888
b.liubb590492024-06-13 16:42:08 +0800889#ifdef MBTK_DUMP_SUPPORT
890 mbtk_debug_open(NULL, TRUE);
891#endif
892
b.liu8f231a12024-05-31 17:55:06 +0800893 signal(SIGINT, sig_process);
894 signal(SIGQUIT, sig_process);
895 signal(SIGTERM, sig_process);
896
897 if(arg_check(argc, argv)) {
898 return -1;
899 }
900
901#ifdef GNSS_DEBUG
902 char buff[10];
903 memset(buff, 0, 10);
904 property_get(MBTK_PROP_GNSS_LOG, buff, "");
905 if(strlen(buff) > 0 && atoi(buff) > 0) {
906 nmea_log_enable = TRUE;
907 }
908#endif
909
910 memset(&gnss_info, 0, sizeof(gnss_info_t));
911 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
912 gnss_info.state = GNSS_STATE_CLOSE;
913 if(!strcmp(argv[1], GNSS_ID_6228)) {
914 gnss_info.gnss_id = GNSS_TYPE_6228;
915 gnss_info.auto_open = (bool)atoi(argv[3]);
916 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +0800917 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800918 gnss_info.gnss_dev_open = gnss_6228_dev_open;
919 gnss_info.gnss_dev_close = gnss_6228_dev_close;
920 gnss_info.gnss_open = gnss_6228_open;
921 gnss_info.gnss_close = gnss_6228_close;
922 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
923 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
924 gnss_info.gnss_set = gnss_6228_set;
925 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +0800926 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
927 gnss_info.gnss_id = GNSS_TYPE_8122;
928 gnss_info.auto_open = (bool)atoi(argv[3]);
929 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +0800930 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +0800931 gnss_info.gnss_dev_open = gnss_8122_dev_open;
932 gnss_info.gnss_dev_close = gnss_8122_dev_close;
933 gnss_info.gnss_open = gnss_8122_open;
934 gnss_info.gnss_close = gnss_8122_close;
935 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
936 gnss_info.gnss_dl_read_cb = NULL;
937 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +0800938 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +0800939 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
940 gnss_info.gnss_id = GNSS_TYPE_5311;
941 gnss_info.auto_open = (bool)atoi(argv[3]);
942 gnss_info.auto_dl_fw = TRUE;
943 gnss_info.dl_befor_open = TRUE;
944 gnss_info.gnss_dev_open = gnss_5311_dev_open;
945 gnss_info.gnss_dev_close = gnss_5311_dev_close;
946 gnss_info.gnss_open = gnss_5311_open;
947 gnss_info.gnss_close = gnss_5311_close;
948 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
949 gnss_info.gnss_dl_read_cb = NULL;
950 gnss_info.gnss_set = gnss_5311_set;
951 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu8f231a12024-05-31 17:55:06 +0800952 } else {
953 LOGE("No support : %s", argv[1]);
954 return -1;
955 }
956
957 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
958 // Auto open gnss.
959 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +0800960 int init_mode = atoi(argv[3]);
961 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
962 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +0800963 }
b.liuced8dd02024-06-28 13:28:29 +0800964 if(gnss_init((uint32)init_mode)) {
965 LOGE("gnss_init() fail.");
966 // return -1;
967 }
968 } else {
969 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +0800970 }
971
972 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +0800973#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +0800974 if(gnss_ubus_init()) {
975 LOGD("main() run...");
976 uloop_run();
977 } else {
978 LOGE("gnss_ubus_init() fail.");
979 }
b.liu5f950c52024-06-15 20:13:12 +0800980#else
981 if(!gnss_ipc_service_start()) {
982 LOGD("main() run...");
983 while(1) {
984 sleep(24 * 60 * 60);
985 }
986 } else {
987 LOGE("gnss_ipc_service_start() fail.");
988 }
989#endif
b.liu8f231a12024-05-31 17:55:06 +0800990
991 LOGD("main() exit.");
992 return 0;
993}