blob: 19668554037a3537270ebdb4828a11eba05b5b4a [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) {
76 goto check_fail;
77 }
78
b.liu99c645d2024-06-20 10:52:15 +080079 // Only support 6228/8122/5311.
80 if(strcmp(argv[1], GNSS_ID_6228) && strcmp(argv[1], GNSS_ID_8122) && strcmp(argv[1], GNSS_ID_5311)) {
b.liu8f231a12024-05-31 17:55:06 +080081 goto check_fail;
82 }
83
84 if(access(argv[2], R_OK | W_OK)) {
85 goto check_fail;
86 }
87
b.liuced8dd02024-06-28 13:28:29 +080088#if 0
89 int init_mode = atoi(argv[3]);
90 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 +080091 goto check_fail;
92 }
b.liuced8dd02024-06-28 13:28:29 +080093#endif
b.liu8f231a12024-05-31 17:55:06 +080094
95 return 0;
96check_fail:
97 help();
98 return -1;
99}
100
101static int gnss_ports_open(uint32 print_port)
102{
b.liuced8dd02024-06-28 13:28:29 +0800103 // TTY AT change.
104 if((gnss_info.print_port & GNSS_PRINT_PORT_TTY_AT) != (print_port & GNSS_PRINT_PORT_TTY_AT)) {
105 if(print_port & GNSS_PRINT_PORT_TTY_AT) { // Open
106 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
107 return GNSS_ERR_OPEN_DEV;
108 }
109 LOGD("Open PTY port success.");
110 } else { // Close
111 if(gnss_pty_slave_fd > 0) {
112 close(gnss_pty_slave_fd);
113 gnss_pty_slave_fd = -1;
114 unlink(GNSS_PORT_PTY);
115 }
116 LOGD("Close PTY port success.");
b.liu8f231a12024-05-31 17:55:06 +0800117 }
b.liu8f231a12024-05-31 17:55:06 +0800118 }
119
b.liuced8dd02024-06-28 13:28:29 +0800120 // USB AT change.
121 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_AT) != (print_port & GNSS_PRINT_PORT_USB_AT)) {
122 if(print_port & GNSS_PRINT_PORT_USB_AT) { // Open
123 if((gnss_usb_at_port_fd = gnss_port_open(GNSS_PORT_USB_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
124 return GNSS_ERR_OPEN_DEV;
125 }
126 LOGD("Open USB AT port success.");
127 } else { // Close
128 if(gnss_usb_at_port_fd > 0) {
129 close(gnss_usb_at_port_fd);
130 gnss_usb_at_port_fd = -1;
131 }
132 LOGD("Close USB AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800133 }
b.liu8f231a12024-05-31 17:55:06 +0800134 }
135
b.liuced8dd02024-06-28 13:28:29 +0800136 // USB NMEA change.
137 if((gnss_info.print_port & GNSS_PRINT_PORT_USB_NMEA) != (print_port & GNSS_PRINT_PORT_USB_NMEA)) {
138 if(print_port & GNSS_PRINT_PORT_USB_NMEA) { // Open
139 if((gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
140 return GNSS_ERR_OPEN_DEV;
141 }
142 LOGD("Open USB NMEA port success.");
143 } else { // Close
144 if(gnss_usb_nmea_port_fd > 0) {
145 close(gnss_usb_nmea_port_fd);
146 gnss_usb_nmea_port_fd = -1;
147 }
148 LOGD("Close USB NMEA port success.");
b.liu8f231a12024-05-31 17:55:06 +0800149 }
b.liu8f231a12024-05-31 17:55:06 +0800150 }
151
b.liuced8dd02024-06-28 13:28:29 +0800152 // Uart AT change.
153 if((gnss_info.print_port & GNSS_PRINT_PORT_UART1) != (print_port & GNSS_PRINT_PORT_UART1)) {
154 if(print_port & GNSS_PRINT_PORT_UART1) { // Open
155 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
156 return GNSS_ERR_OPEN_DEV;
157 }
158 LOGD("Open UART AT port success.");
159 } else { // Close
160 if(gnss_uart_at_port_fd > 0) {
161 close(gnss_uart_at_port_fd);
162 gnss_uart_at_port_fd = -1;
163 }
164 LOGD("Close UART AT port success.");
b.liu8f231a12024-05-31 17:55:06 +0800165 }
b.liu8f231a12024-05-31 17:55:06 +0800166 }
167
b.liuced8dd02024-06-28 13:28:29 +0800168 gnss_info.print_port = print_port;
169
b.liudbc3f4b2024-06-25 18:22:24 +0800170 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800171}
172
173static int gnss_ports_close()
174{
175 if(gnss_usb_at_port_fd > 0) {
176 close(gnss_usb_at_port_fd);
177 gnss_usb_at_port_fd = -1;
178 }
179
180 if(gnss_usb_nmea_port_fd > 0) {
181 close(gnss_usb_nmea_port_fd);
182 gnss_usb_nmea_port_fd = -1;
183 }
184
185 if(gnss_uart_at_port_fd > 0) {
186 close(gnss_uart_at_port_fd);
187 gnss_uart_at_port_fd = -1;
188 }
189
190 if(gnss_pty_master_fd > 0) {
191 close(gnss_pty_master_fd);
192 gnss_pty_master_fd = -1;
193 }
194
195 if(gnss_pty_slave_fd > 0) {
196 close(gnss_pty_slave_fd);
197 gnss_pty_slave_fd = -1;
198 unlink(GNSS_PORT_PTY);
199 }
200
b.liuced8dd02024-06-28 13:28:29 +0800201 gnss_info.print_port = 0;
202
b.liu8f231a12024-05-31 17:55:06 +0800203 return 0;
204}
205
b.liu8f231a12024-05-31 17:55:06 +0800206#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800207static void log_save(int fd, const char *data, int data_len)
208{
b.liu8f231a12024-05-31 17:55:06 +0800209 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800210 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
211 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
212 close(debug_fd);
213 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
214 if(debug_fd < 0) {
215 LOGE("Open debug fd fail.");
216 }
217 debug_fd_len = 0;
218
219 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800220 close(nmea_log_fd);
221 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
222 if(nmea_log_fd < 0) {
223 LOGE("Open debug fd fail.");
224 }
b.liu8f231a12024-05-31 17:55:06 +0800225 }
226
b.liu99c645d2024-06-20 10:52:15 +0800227 if(fd == nmea_log_fd) {
228 if(nmea_log_fd > 0) {
229 write(nmea_log_fd, data, data_len);
230 debug_fd_len += data_len;
231 }
232 } else if(fd == debug_fd) {
233 if(debug_fd > 0) {
234 write(debug_fd, data, data_len);
235 debug_fd_len += data_len;
236 }
b.liu8f231a12024-05-31 17:55:06 +0800237 }
238 }
b.liu99c645d2024-06-20 10:52:15 +0800239}
b.liu8f231a12024-05-31 17:55:06 +0800240#endif
241
b.liu99c645d2024-06-20 10:52:15 +0800242static void nmea_print(const char *nmea, int nmea_len)
243{
b.liu8f231a12024-05-31 17:55:06 +0800244 if(gnss_usb_at_port_fd > 0) {
245 write(gnss_usb_at_port_fd, nmea, nmea_len);
246 }
247
248 if(gnss_usb_nmea_port_fd > 0) {
249 write(gnss_usb_nmea_port_fd, nmea, nmea_len);
250 }
251
252 if(gnss_uart_at_port_fd > 0) {
253 write(gnss_uart_at_port_fd, nmea, nmea_len);
254 }
255
256 if(gnss_pty_master_fd > 0) {
257 write(gnss_pty_master_fd, nmea, nmea_len);
258 }
259}
260
261static unsigned char nmea_checksum(const char *nmea)
262{
263 const char *p = nmea;
264 unsigned char chs = 0;
265
266 while (*p == '$') // skip '$'
267 p++;
268 while (*p != '*' && *p != 0)
269 chs ^= *p++;
270
271 return chs;
272}
273
274static bool nmea_check(const char *nmea, int nmea_len)
275{
276 char **ptr = gnss_filter_info;
277 while(*ptr) {
278 if(strstr(nmea, *ptr)) {
279 break;
280 }
281 ptr++;
282 }
283
284 if(*ptr == NULL) {
285 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
286 return FALSE;
287 }
288
289 char *checksum_str = strstr(nmea, "*");
290 checksum_str++; // Jump '*'
291 char checksum_buf[3] = {0};
292 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
293 if(strncasecmp(checksum_buf, checksum_str, 2)) {
294 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
295 return FALSE;
296 }
297
298 return TRUE;
299}
300
301static void gnss_nmea_process(const char *data, int data_len)
302{
b.liu99c645d2024-06-20 10:52:15 +0800303 // LOGD("gnss_nmea_process() : data_len - %d", data_len);
304#if 0
b.liu8f231a12024-05-31 17:55:06 +0800305 char nmea[GNSS_BUFF_SIZE] = {0};
306 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800307#else
308 const char *nmea = data;
309#endif
b.liu8f231a12024-05-31 17:55:06 +0800310
311 if(!nmea_check(nmea, data_len)) {
b.liu99c645d2024-06-20 10:52:15 +0800312 LOGD("NO-NMEA:%s", nmea);
313#if GNSS_DEBUG
314 log_save(nmea_log_fd, "/**/", 4);
315 log_save(nmea_log_fd, nmea, data_len);
316#endif
317 if(gnss_info.gnss_set_cb)
318 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800319 return;
320 }
321
322#ifdef GNSS_DEBUG
323 if(nmea_log_enable) {
324 LOGD("NMEA[%d]:%s", data_len, nmea);
325 }
b.liu99c645d2024-06-20 10:52:15 +0800326
327 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800328#endif
329
330 nmea_print(nmea, data_len);
331}
332
333#if 0
334static void gnss_cmd_rsp_process(const char *data, int data_len)
335{
336 char rsp[GNSS_BUFF_SIZE] = {0};
337 memcpy(rsp, data, data_len);
338 LOGD("RSP[%d]:%s", data_len, rsp);
339}
340#endif
341
342static bool nmea_char_check(char ch)
343{
344 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
b.liu99c645d2024-06-20 10:52:15 +0800345 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=')
b.liu8f231a12024-05-31 17:55:06 +0800346 return TRUE;
347
348 return FALSE;
349}
350
351static void gnss_data_process(const char *data, int data_len)
352{
353 if(gnss_info.state == GNSS_STATE_OPEN) {
354 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
355 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
356 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800357 if(gnss_info.gnss_dl_read_cb) {
358 gnss_info.gnss_dl_read_cb(data, data_len);
359 }
b.liu8f231a12024-05-31 17:55:06 +0800360 } else if(gnss_info.state == GNSS_STATE_READY) {
361 int index = 0;
362 while(index < data_len) {
363 if(nmea_found) {
364 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800365 // Copy nmea_buff to data_buff
366 // Start with '$', but not nmea data, so copy to data_buff.
367 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
368 data_buff_len += nmea_buff_len;
369 data_buff[data_buff_len++] = data[index];
370
371 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800372 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800373 continue;
374 }
375
376 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800377 nmea_buff[nmea_buff_len++] = data[index];
378 if(nmea_buff[nmea_buff_len - 1] == '\n') {
379 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800380#if GNSS_DEBUG
381 log_save(nmea_log_fd, "/**/", 4);
382 log_save(nmea_log_fd, data_buff, data_buff_len);
383#endif
384 if(gnss_info.gnss_set_cb) {
385 gnss_info.gnss_set_cb(data_buff, data_buff_len);
386 }
b.liud0ba7152024-06-19 14:47:21 +0800387 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800388 }
389
b.liud0ba7152024-06-19 14:47:21 +0800390 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800391 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800392 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800393 } else if(nmea_buff_len > 0) {
394 nmea_buff[nmea_buff_len] = '\0';
395 LOGD("NO-NMEA:%s", nmea_buff);
396#if GNSS_DEBUG
397 log_save(nmea_log_fd, "/**/", 4);
398 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
399#endif
b.liud0ba7152024-06-19 14:47:21 +0800400 }
401
402 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800403 nmea_found = FALSE;
404 }
405 }
406 } else {
407 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800408 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800409 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800410 nmea_buff[nmea_buff_len++] = data[index];
411 } else {
412 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800413 }
414 }
415 index++;
416 }
417 } else {
418 LOGW("Unknown state : %d", gnss_info.state);
419 }
420}
421
422void* gnss_read_pthread(void* arg)
423{
424 LOGD("gnss_read_pthread enter.");
425 char buffer[GNSS_BUFF_SIZE];
426 int len = 0;
427 int ret = 0;
428 fd_set fdr, fdw;
429 int fd_max = 0;
430
b.liu8f231a12024-05-31 17:55:06 +0800431 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800432 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800433 memset(nmea_buff, 0, sizeof(nmea_buff));
434 memset(data_buff, 0, sizeof(data_buff));
435 nmea_buff_len = 0;
436 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800437#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800438 if(nmea_log_enable) {
439 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
440 if(debug_fd < 0) {
441 LOGE("Open debug fd fail.");
442 }
443 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
444 if(nmea_log_fd < 0) {
445 LOGE("Open nmea fd fail.");
446 }
b.liu99c645d2024-06-20 10:52:15 +0800447 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800448 }
449#endif
450
b.liudbc3f4b2024-06-25 18:22:24 +0800451 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
452
b.liu8f231a12024-05-31 17:55:06 +0800453 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800454 FD_ZERO(&fdw);
455 FD_ZERO(&fdr);
456 FD_SET(gnss_info.fd, &fdr);
457 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800458 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
459 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800460 if(gnss_info.state < GNSS_STATE_OPEN) {
461 LOGD("State = %d, ret = %d", gnss_info.state, ret);
462 if(ret > 0) {
463 if (FD_ISSET(gnss_info.fd, &fdr)) {
464 LOGD("gnss_fd can read.");
465 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
466 LOGD("exit_fd can read.");
467 } else {
468 LOGW("Unknown select event.");
469 }
470 }
471 break;
472 }
473
b.liu8f231a12024-05-31 17:55:06 +0800474 if (ret < 0)
475 {
476 if (errno == EINTR)
477 {
478 continue;
479 }
480 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
481 break;
482 }
483 else if (ret == 0)
484 {
485 LOGE("select ret == 0");
486 break;
487 }
488
489 if (FD_ISSET(gnss_info.fd, &fdr))
490 {
491 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800492 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800493 if(len > 0) {
494 //log_hex("READ", buffer, len);
495
496#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800497 //LOGD("read data_len = %d", len);
498 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800499#endif
500
501 gnss_data_process(buffer, len);
502
503 } else if(len ==0 ){
504 LOGE("Read end : len = 0");
505 break;
506 } else {
507 if(EAGAIN == errno) {
508 usleep(50000);
509 continue;
510 } else {
511 LOGD("Read ret = -1 ,errno = %d", errno);
512 break;
513 }
514 }
515 }
516 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
517 {
b.liuece0db02024-06-25 18:39:09 +0800518 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800519 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800520 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800521 if(len > 0) {
522 if(strcmp(buffer, "exit") == 0) {
523 LOGD("Get thread exit message.");
524 break;
525 }
526 }
527 }
528 else
529 {
530 LOGW("Unknown select event.");
531 continue;
532 }
533 }
534
535#if GNSS_DEBUG
536 if(debug_fd > 0) {
537 close(debug_fd);
538 debug_fd = -1;
539 }
540 if(nmea_log_fd > 0) {
541 close(nmea_log_fd);
542 nmea_log_fd = -1;
543 }
544#endif
545
546 gnss_info.state = GNSS_STATE_CLOSE;
547 LOGD("gnss_read_pthread exit.");
548 return NULL;
549}
550
551#if 0
552int gnss_write(int fd, const void *data, int data_len)
553{
554 int count = 0;
555 int len = 0;
556 while(1)
557 {
558 len = write(fd, data + count, data_len - count);
559 if (len > 0)
560 {
561 count += len;
562 }
563 else
564 {
565 LOGE("write() fail,ret = %d,errno = %d", len, errno);
566 break;
567 }
568
569 if (count == data_len)
570 break;
571 }
572
573 return count;
574}
575#else
b.liu778645e2024-06-21 16:47:42 +0800576int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800577{
b.liu778645e2024-06-21 16:47:42 +0800578 ssize_t size;
579 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800580 ssize_t size_written;
581 if(GNSS_BUFF_SIZE < buf_len)
582 {
583 return -1;
584 }
585 for(size = 0; size < buf_len;)
586 {
587 size_to_wr = buf_len - size;
588 if( size_to_wr > GNSS_BUFF_SIZE)
589 size_to_wr = GNSS_BUFF_SIZE;
590
b.liu778645e2024-06-21 16:47:42 +0800591 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800592 if (size_written==-1)
593 {
594 return -1;
595 }
596 size += size_written;
597 if(size_written != size_to_wr)
598 {
599 return size;
600 }
601 }
602 // LOGD("SEND %d / %d", size, buf_len);
603 return size;
604}
605#endif
606
607int gnss_init(uint32 print_port)
608{
609 if(gnss_info.state != GNSS_STATE_CLOSE) {
610 LOGW("GNSS not close:%d", gnss_info.state);
b.liuced8dd02024-06-28 13:28:29 +0800611 if(gnss_info.state == GNSS_STATE_READY) {
612 LOGD("Reset print port : %d -> %d", gnss_info.print_port, print_port);
613 if(gnss_info.print_port != print_port) {
614 return gnss_ports_open(print_port);
615 } else {
616 return GNSS_ERR_OK;
617 }
618 } else {
619 return GNSS_ERR_OK;
620 }
b.liu8f231a12024-05-31 17:55:06 +0800621 }
622
623 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800624 if(gnss_info.dl_befor_open) {
625 //if(gnss_info.auto_dl_fw) {
626 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800627 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800628 if(ret) {
629 LOGE("gnss_fw_dl() fail : %d", ret);
630 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800631 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800632 }
b.liu8f231a12024-05-31 17:55:06 +0800633
b.liu99c645d2024-06-20 10:52:15 +0800634 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
635 if(gnss_info.fd <= 0) {
636 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
637 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800638 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800639 }
640 if(pipe(gnss_info.exit_fd)) {
641 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800642 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800643 }
644 // GNSS is opened.
645 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800646
b.liu99c645d2024-06-20 10:52:15 +0800647#if 0
648 // Start gnss read thread.
649 pthread_attr_t thread_attr;
650 pthread_attr_init(&thread_attr);
651 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
652 {
653 LOGE("pthread_attr_setdetachstate() fail.");
654 goto main_exit;
655 }
b.liu8f231a12024-05-31 17:55:06 +0800656
b.liu99c645d2024-06-20 10:52:15 +0800657 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800658#else
b.liu99c645d2024-06-20 10:52:15 +0800659 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800660#endif
b.liu99c645d2024-06-20 10:52:15 +0800661 {
662 LOGE("pthread_create() fail.");
663 goto exit_with_close;
664 }
b.liu8f231a12024-05-31 17:55:06 +0800665
b.liu99c645d2024-06-20 10:52:15 +0800666 ret = gnss_info.gnss_dev_open();
667 if(ret) {
668 LOGE("gnss_dev_open() fail : %d", ret);
669 goto exit_with_thread_exit;
670 }
671 //}
672 } else {
673 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
674 if(gnss_info.fd <= 0) {
675 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
676 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800677 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800678 }
679 if(pipe(gnss_info.exit_fd)) {
680 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800681 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800682 }
683 // GNSS is opened.
684 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800685
b.liu99c645d2024-06-20 10:52:15 +0800686#if 0
687 // Start gnss read thread.
688 pthread_attr_t thread_attr;
689 pthread_attr_init(&thread_attr);
690 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
691 {
692 LOGE("pthread_attr_setdetachstate() fail.");
693 goto main_exit;
694 }
695
696 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
697#else
698 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
699#endif
700 {
701 LOGE("pthread_create() fail.");
702 goto exit_with_close;
703 }
704
705 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800706 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800707 LOGE("gnss_dev_open() fail : %d", ret);
708 goto exit_with_thread_exit;
709 }
b.liu8f231a12024-05-31 17:55:06 +0800710 }
711
712 // GNSS is ready, NMEA can print from uart.
713 gnss_info.state = GNSS_STATE_READY;
b.liu8f231a12024-05-31 17:55:06 +0800714
715 LOGD("GNSS open success.");
716
b.liuced8dd02024-06-28 13:28:29 +0800717 return gnss_ports_open(print_port);
b.liu8f231a12024-05-31 17:55:06 +0800718
719exit_with_dev_close:
720 if(gnss_info.gnss_dev_close()) {
721 LOGE("gnss_dev_close() fail.");
722 }
723exit_with_thread_exit:
724 gnss_info.state = GNSS_STATE_CLOSING;
725 // Wait for read thread exit.
726 ret = pthread_join(gnss_info.read_pid, NULL);
727 if(ret){
728 LOGE("pthrad_join fail(%d)",ret);
729 }
730exit_with_close:
731 if(gnss_info.gnss_close(gnss_info.fd)) {
732 LOGE("gnss_close() fail.");
733 }
734 if(gnss_info.exit_fd[0] > 0) {
735 close(gnss_info.exit_fd[0]);
736 gnss_info.exit_fd[0] = -1;
737 }
738 if(gnss_info.exit_fd[1] > 0) {
739 close(gnss_info.exit_fd[1]);
740 gnss_info.exit_fd[1] = -1;
741 }
742 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800743 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800744}
745
746int gnss_deinit()
747{
748 if(gnss_info.state == GNSS_STATE_CLOSE) {
749 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +0800750 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800751 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
752 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +0800753 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800754 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
755 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +0800756 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800757 }
758
759 // Wait for read thread exit.
760 if(gnss_info.exit_fd[1] > 0) {
761 write(gnss_info.exit_fd[1], "exit", 4);
762 }
763
764 gnss_info.state = GNSS_STATE_CLOSING;
765 int ret = pthread_join(gnss_info.read_pid, NULL);
766 if(ret){
767 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +0800768 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800769 }
770
771 if(gnss_info.gnss_close(gnss_info.fd)) {
772 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800773 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800774 }
775
776 if(gnss_info.gnss_dev_close()) {
777 LOGE("gnss_dev_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800778 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800779 }
780
781 if(gnss_ports_close()) {
782 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800783 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800784 }
785
b.liud0ba7152024-06-19 14:47:21 +0800786 LOGD("gnss_ports_close() complete.");
787
b.liu8f231a12024-05-31 17:55:06 +0800788 gnss_info.fd = -1;
789 if(gnss_info.exit_fd[0] > 0) {
790 close(gnss_info.exit_fd[0]);
791 gnss_info.exit_fd[0] = -1;
792 }
793 if(gnss_info.exit_fd[1] > 0) {
794 close(gnss_info.exit_fd[1]);
795 gnss_info.exit_fd[1] = -1;
796 }
797 gnss_info.state = GNSS_STATE_CLOSE;
798 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +0800799 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800800}
801
802int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
803{
b.liud0ba7152024-06-19 14:47:21 +0800804 if(buf && buf_len > 0) {
805 if(cmd_rsp && cmd_rsp_len > 0) {
806 memset(cmd_rsp, 0, cmd_rsp_len);
807 }
b.liu8f231a12024-05-31 17:55:06 +0800808 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
809 } else {
b.liudbc3f4b2024-06-25 18:22:24 +0800810 return GNSS_ERR_UNKNOWN;
811 }
812}
813
814int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
815{
816 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
817 return GNSS_ERR_UNSUPPORT;
818 }
819
820 if(rsp && rsp_len > 0) {
821 memset(rsp, 0, rsp_len);
822 }
823
824 if(gnss_info.gnss_fw_dl) {
825 if(GNSS_ERR_OK != gnss_deinit()) {
826 LOGE("Close gnss fail.");
827 return GNSS_ERR_UNKNOWN;
828 } else {
829 LOGD("Start gnss fw dl.");
830 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
831 }
832 } else {
833 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800834 }
835}
836
837static void sig_process(int sig)
838{
839 LOGI("I got signal %d\n", sig);
840 if(gnss_deinit()) {
841 LOGE("gnss_deinit() fail, no exist...");
842 return;
843 }
844
845 switch(sig)
846 {
847 case SIGINT: // Ctrl + C
848 {
849 LOGI("Exit by SIGINT.\n");
850 exit(0);
851 }
852 case SIGQUIT: // Ctrl + \ (ÀàËÆ SIGINT £¬µ«Òª²úÉúcoreÎļþ)
853 {
854 LOGI("Exit by SIGQUIT.\n");
855 exit(0);
856 }
857 case SIGTERM:// ĬÈÏkill (ͬ SIGKILL £¬µ« SIGKILL ²»¿É²¶»ñ)
858 {
859 LOGI("Exit by SIGTERM.\n");
860 exit(0);
861 }
862 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP £¬µ« SIGSTOP ²»¿É²¶»ñ)
863 {
864 LOGI("Exit by SIGTSTP.\n");
865 exit(0);
866 }
867 case SIGSEGV: // Èç¿ÕÖ¸Õë
868 {
869 LOGI("Exit by SIGSEGV.\n");
870 exit(0);
871 }
872 default:
873 {
874 LOGI("Unknown sig:%d\n",sig);
875 break;
876 }
877 }
878}
879
880
b.liuced8dd02024-06-28 13:28:29 +0800881// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1 <port_type>
b.liu8f231a12024-05-31 17:55:06 +0800882int main(int argc, char *argv[])
883{
884 mbtk_log_init("radio", GNSS_TAG);
885
b.liubb590492024-06-13 16:42:08 +0800886#ifdef MBTK_DUMP_SUPPORT
887 mbtk_debug_open(NULL, TRUE);
888#endif
889
b.liu8f231a12024-05-31 17:55:06 +0800890 signal(SIGINT, sig_process);
891 signal(SIGQUIT, sig_process);
892 signal(SIGTERM, sig_process);
893
894 if(arg_check(argc, argv)) {
895 return -1;
896 }
897
898#ifdef GNSS_DEBUG
899 char buff[10];
900 memset(buff, 0, 10);
901 property_get(MBTK_PROP_GNSS_LOG, buff, "");
902 if(strlen(buff) > 0 && atoi(buff) > 0) {
903 nmea_log_enable = TRUE;
904 }
905#endif
906
907 memset(&gnss_info, 0, sizeof(gnss_info_t));
908 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
909 gnss_info.state = GNSS_STATE_CLOSE;
910 if(!strcmp(argv[1], GNSS_ID_6228)) {
911 gnss_info.gnss_id = GNSS_TYPE_6228;
912 gnss_info.auto_open = (bool)atoi(argv[3]);
913 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +0800914 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800915 gnss_info.gnss_dev_open = gnss_6228_dev_open;
916 gnss_info.gnss_dev_close = gnss_6228_dev_close;
917 gnss_info.gnss_open = gnss_6228_open;
918 gnss_info.gnss_close = gnss_6228_close;
919 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
920 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
921 gnss_info.gnss_set = gnss_6228_set;
922 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +0800923 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
924 gnss_info.gnss_id = GNSS_TYPE_8122;
925 gnss_info.auto_open = (bool)atoi(argv[3]);
926 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +0800927 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +0800928 gnss_info.gnss_dev_open = gnss_8122_dev_open;
929 gnss_info.gnss_dev_close = gnss_8122_dev_close;
930 gnss_info.gnss_open = gnss_8122_open;
931 gnss_info.gnss_close = gnss_8122_close;
932 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
933 gnss_info.gnss_dl_read_cb = NULL;
934 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +0800935 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +0800936 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
937 gnss_info.gnss_id = GNSS_TYPE_5311;
938 gnss_info.auto_open = (bool)atoi(argv[3]);
939 gnss_info.auto_dl_fw = TRUE;
940 gnss_info.dl_befor_open = TRUE;
941 gnss_info.gnss_dev_open = gnss_5311_dev_open;
942 gnss_info.gnss_dev_close = gnss_5311_dev_close;
943 gnss_info.gnss_open = gnss_5311_open;
944 gnss_info.gnss_close = gnss_5311_close;
945 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
946 gnss_info.gnss_dl_read_cb = NULL;
947 gnss_info.gnss_set = gnss_5311_set;
948 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu8f231a12024-05-31 17:55:06 +0800949 } else {
950 LOGE("No support : %s", argv[1]);
951 return -1;
952 }
953
954 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
955 // Auto open gnss.
956 if(gnss_info.auto_open) {
b.liuced8dd02024-06-28 13:28:29 +0800957 int init_mode = atoi(argv[3]);
958 if(((GNSS_PRINT_PORT_UART1 | GNSS_PRINT_PORT_USB_NMEA | GNSS_PRINT_PORT_USB_AT | GNSS_PRINT_PORT_TTY_AT) & init_mode) != init_mode) {
959 init_mode = 0;
b.liu8f231a12024-05-31 17:55:06 +0800960 }
b.liuced8dd02024-06-28 13:28:29 +0800961 if(gnss_init((uint32)init_mode)) {
962 LOGE("gnss_init() fail.");
963 // return -1;
964 }
965 } else {
966 gnss_info.print_port = 0;
b.liu8f231a12024-05-31 17:55:06 +0800967 }
968
969 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +0800970#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +0800971 if(gnss_ubus_init()) {
972 LOGD("main() run...");
973 uloop_run();
974 } else {
975 LOGE("gnss_ubus_init() fail.");
976 }
b.liu5f950c52024-06-15 20:13:12 +0800977#else
978 if(!gnss_ipc_service_start()) {
979 LOGD("main() run...");
980 while(1) {
981 sleep(24 * 60 * 60);
982 }
983 } else {
984 LOGE("gnss_ipc_service_start() fail.");
985 }
986#endif
b.liu8f231a12024-05-31 17:55:06 +0800987
988 LOGD("main() exit.");
989 return 0;
990}