blob: 5b60d9353b2f47beed51f5a3b2eb5804a7811533 [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
b.liud0ba7152024-06-19 14:47:21 +080049static char nmea_buff[GNSS_BUFF_SIZE*2] = {0};
50static char data_buff[GNSS_BUFF_SIZE] = {0};
51static 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
88 if(strcmp(argv[3], "0") && strcmp(argv[3], "1")) {
89 goto check_fail;
90 }
91
92 return 0;
93check_fail:
94 help();
95 return -1;
96}
97
98static int gnss_ports_open(uint32 print_port)
99{
100 if(print_port & GNSS_PRINT_PORT_TTY_AT) {
101 if(gnss_pty_open(&gnss_pty_master_fd, &gnss_pty_slave_fd, GNSS_PORT_PTY)) {
b.liudbc3f4b2024-06-25 18:22:24 +0800102 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800103 }
104 LOGD("Open PTY port success.");
105 }
106
107 if(print_port & GNSS_PRINT_PORT_USB_AT) {
108 if((gnss_usb_at_port_fd = gnss_port_open(GNSS_PORT_USB_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
b.liudbc3f4b2024-06-25 18:22:24 +0800109 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800110 }
111 LOGD("Open USB AT port success.");
112 }
113
114 if(print_port & GNSS_PRINT_PORT_USB_NMEA) {
115 if((gnss_usb_nmea_port_fd = gnss_port_open(GNSS_PORT_USB_NMEA, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, FALSE)) <= 0) {
b.liudbc3f4b2024-06-25 18:22:24 +0800116 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800117 }
118 LOGD("Open USB NMEA port success.");
119 }
120
121 if(print_port & GNSS_PRINT_PORT_UART1) {
122 if((gnss_uart_at_port_fd = gnss_port_open(GNSS_PORT_UART_AT, O_RDWR | O_NONBLOCK | O_NOCTTY, 115200, TRUE)) <= 0) {
b.liudbc3f4b2024-06-25 18:22:24 +0800123 return GNSS_ERR_OPEN_DEV;
b.liu8f231a12024-05-31 17:55:06 +0800124 }
125 LOGD("Open UART AT port success.");
126 }
127
b.liudbc3f4b2024-06-25 18:22:24 +0800128 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800129}
130
131static int gnss_ports_close()
132{
133 if(gnss_usb_at_port_fd > 0) {
134 close(gnss_usb_at_port_fd);
135 gnss_usb_at_port_fd = -1;
136 }
137
138 if(gnss_usb_nmea_port_fd > 0) {
139 close(gnss_usb_nmea_port_fd);
140 gnss_usb_nmea_port_fd = -1;
141 }
142
143 if(gnss_uart_at_port_fd > 0) {
144 close(gnss_uart_at_port_fd);
145 gnss_uart_at_port_fd = -1;
146 }
147
148 if(gnss_pty_master_fd > 0) {
149 close(gnss_pty_master_fd);
150 gnss_pty_master_fd = -1;
151 }
152
153 if(gnss_pty_slave_fd > 0) {
154 close(gnss_pty_slave_fd);
155 gnss_pty_slave_fd = -1;
156 unlink(GNSS_PORT_PTY);
157 }
158
159 return 0;
160}
161
b.liu8f231a12024-05-31 17:55:06 +0800162#ifdef GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800163static void log_save(int fd, const char *data, int data_len)
164{
b.liu8f231a12024-05-31 17:55:06 +0800165 if(nmea_log_enable){
b.liu99c645d2024-06-20 10:52:15 +0800166 if(0 /* debug_fd_len > GNSS_FILE_LOG_MAX */) {
167 LOGD("Reopen file:%s(len = %d)", GNSS_FILE_LOG, debug_fd_len);
168 close(debug_fd);
169 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
170 if(debug_fd < 0) {
171 LOGE("Open debug fd fail.");
172 }
173 debug_fd_len = 0;
174
175 LOGD("Reopen file:%s", GNSS_NMEA_FILE_LOG);
b.liu8f231a12024-05-31 17:55:06 +0800176 close(nmea_log_fd);
177 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
178 if(nmea_log_fd < 0) {
179 LOGE("Open debug fd fail.");
180 }
b.liu8f231a12024-05-31 17:55:06 +0800181 }
182
b.liu99c645d2024-06-20 10:52:15 +0800183 if(fd == nmea_log_fd) {
184 if(nmea_log_fd > 0) {
185 write(nmea_log_fd, data, data_len);
186 debug_fd_len += data_len;
187 }
188 } else if(fd == debug_fd) {
189 if(debug_fd > 0) {
190 write(debug_fd, data, data_len);
191 debug_fd_len += data_len;
192 }
b.liu8f231a12024-05-31 17:55:06 +0800193 }
194 }
b.liu99c645d2024-06-20 10:52:15 +0800195}
b.liu8f231a12024-05-31 17:55:06 +0800196#endif
197
b.liu99c645d2024-06-20 10:52:15 +0800198static void nmea_print(const char *nmea, int nmea_len)
199{
b.liu8f231a12024-05-31 17:55:06 +0800200 if(gnss_usb_at_port_fd > 0) {
201 write(gnss_usb_at_port_fd, nmea, nmea_len);
202 }
203
204 if(gnss_usb_nmea_port_fd > 0) {
205 write(gnss_usb_nmea_port_fd, nmea, nmea_len);
206 }
207
208 if(gnss_uart_at_port_fd > 0) {
209 write(gnss_uart_at_port_fd, nmea, nmea_len);
210 }
211
212 if(gnss_pty_master_fd > 0) {
213 write(gnss_pty_master_fd, nmea, nmea_len);
214 }
215}
216
217static unsigned char nmea_checksum(const char *nmea)
218{
219 const char *p = nmea;
220 unsigned char chs = 0;
221
222 while (*p == '$') // skip '$'
223 p++;
224 while (*p != '*' && *p != 0)
225 chs ^= *p++;
226
227 return chs;
228}
229
230static bool nmea_check(const char *nmea, int nmea_len)
231{
232 char **ptr = gnss_filter_info;
233 while(*ptr) {
234 if(strstr(nmea, *ptr)) {
235 break;
236 }
237 ptr++;
238 }
239
240 if(*ptr == NULL) {
241 LOGD("Unknown NMEA[%d]:%s", nmea_len, nmea);
242 return FALSE;
243 }
244
245 char *checksum_str = strstr(nmea, "*");
246 checksum_str++; // Jump '*'
247 char checksum_buf[3] = {0};
248 snprintf(checksum_buf, 3, "%02x", nmea_checksum(nmea));
249 if(strncasecmp(checksum_buf, checksum_str, 2)) {
250 LOGD("Checksum error[%d](checksum - %s):%s", nmea_len, checksum_buf, nmea);
251 return FALSE;
252 }
253
254 return TRUE;
255}
256
257static void gnss_nmea_process(const char *data, int data_len)
258{
b.liu99c645d2024-06-20 10:52:15 +0800259 // LOGD("gnss_nmea_process() : data_len - %d", data_len);
260#if 0
b.liu8f231a12024-05-31 17:55:06 +0800261 char nmea[GNSS_BUFF_SIZE] = {0};
262 memcpy(nmea, data, data_len);
b.liu99c645d2024-06-20 10:52:15 +0800263#else
264 const char *nmea = data;
265#endif
b.liu8f231a12024-05-31 17:55:06 +0800266
267 if(!nmea_check(nmea, data_len)) {
b.liu99c645d2024-06-20 10:52:15 +0800268 LOGD("NO-NMEA:%s", nmea);
269#if GNSS_DEBUG
270 log_save(nmea_log_fd, "/**/", 4);
271 log_save(nmea_log_fd, nmea, data_len);
272#endif
273 if(gnss_info.gnss_set_cb)
274 gnss_info.gnss_set_cb(nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800275 return;
276 }
277
278#ifdef GNSS_DEBUG
279 if(nmea_log_enable) {
280 LOGD("NMEA[%d]:%s", data_len, nmea);
281 }
b.liu99c645d2024-06-20 10:52:15 +0800282
283 log_save(nmea_log_fd, nmea, data_len);
b.liu8f231a12024-05-31 17:55:06 +0800284#endif
285
286 nmea_print(nmea, data_len);
287}
288
289#if 0
290static void gnss_cmd_rsp_process(const char *data, int data_len)
291{
292 char rsp[GNSS_BUFF_SIZE] = {0};
293 memcpy(rsp, data, data_len);
294 LOGD("RSP[%d]:%s", data_len, rsp);
295}
296#endif
297
298static bool nmea_char_check(char ch)
299{
300 if(isalnum(ch) || ch == '$' || ch == '\r' || ch == '\n' || ch == '.'
b.liu99c645d2024-06-20 10:52:15 +0800301 || ch == ',' || ch == '*' || ch == '\0' || ch == '/' || ch == '_' || ch == '=')
b.liu8f231a12024-05-31 17:55:06 +0800302 return TRUE;
303
304 return FALSE;
305}
306
307static void gnss_data_process(const char *data, int data_len)
308{
309 if(gnss_info.state == GNSS_STATE_OPEN) {
310 LOGD("GNSS_OPEN[%d]:%s", data_len, data);
311 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
312 // LOGD("GNSS_DL[%d]:%s", data_len, data);
b.liu99c645d2024-06-20 10:52:15 +0800313 if(gnss_info.gnss_dl_read_cb) {
314 gnss_info.gnss_dl_read_cb(data, data_len);
315 }
b.liu8f231a12024-05-31 17:55:06 +0800316 } else if(gnss_info.state == GNSS_STATE_READY) {
317 int index = 0;
318 while(index < data_len) {
319 if(nmea_found) {
320 if(!nmea_char_check(data[index])) {
b.liud0ba7152024-06-19 14:47:21 +0800321 // Copy nmea_buff to data_buff
322 // Start with '$', but not nmea data, so copy to data_buff.
323 memcpy(data_buff + data_buff_len, nmea_buff, nmea_buff_len);
324 data_buff_len += nmea_buff_len;
325 data_buff[data_buff_len++] = data[index];
326
327 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800328 nmea_found = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800329 continue;
330 }
331
332 if(data[index] != '\0') {
b.liud0ba7152024-06-19 14:47:21 +0800333 nmea_buff[nmea_buff_len++] = data[index];
334 if(nmea_buff[nmea_buff_len - 1] == '\n') {
335 if(data_buff_len > 0) {
b.liu99c645d2024-06-20 10:52:15 +0800336#if GNSS_DEBUG
337 log_save(nmea_log_fd, "/**/", 4);
338 log_save(nmea_log_fd, data_buff, data_buff_len);
339#endif
340 if(gnss_info.gnss_set_cb) {
341 gnss_info.gnss_set_cb(data_buff, data_buff_len);
342 }
b.liud0ba7152024-06-19 14:47:21 +0800343 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800344 }
345
b.liud0ba7152024-06-19 14:47:21 +0800346 if(nmea_buff_len > 6 && nmea_buff[nmea_buff_len - 5] == '*') { // $XXX*YY\r\n
b.liu99c645d2024-06-20 10:52:15 +0800347 nmea_buff[nmea_buff_len] = '\0';
b.liud0ba7152024-06-19 14:47:21 +0800348 gnss_nmea_process(nmea_buff, nmea_buff_len);
b.liu99c645d2024-06-20 10:52:15 +0800349 } else if(nmea_buff_len > 0) {
350 nmea_buff[nmea_buff_len] = '\0';
351 LOGD("NO-NMEA:%s", nmea_buff);
352#if GNSS_DEBUG
353 log_save(nmea_log_fd, "/**/", 4);
354 log_save(nmea_log_fd, nmea_buff, nmea_buff_len);
355#endif
b.liud0ba7152024-06-19 14:47:21 +0800356 }
357
358 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800359 nmea_found = FALSE;
360 }
361 }
362 } else {
363 if(data[index] == '$') {
b.liud0ba7152024-06-19 14:47:21 +0800364 nmea_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800365 nmea_found = TRUE;
b.liud0ba7152024-06-19 14:47:21 +0800366 nmea_buff[nmea_buff_len++] = data[index];
367 } else {
368 data_buff[data_buff_len++] = data[index];
b.liu8f231a12024-05-31 17:55:06 +0800369 }
370 }
371 index++;
372 }
373 } else {
374 LOGW("Unknown state : %d", gnss_info.state);
375 }
376}
377
378void* gnss_read_pthread(void* arg)
379{
380 LOGD("gnss_read_pthread enter.");
381 char buffer[GNSS_BUFF_SIZE];
382 int len = 0;
383 int ret = 0;
384 fd_set fdr, fdw;
385 int fd_max = 0;
386
b.liu8f231a12024-05-31 17:55:06 +0800387 fd_max = (gnss_info.fd > fd_max) ? gnss_info.fd : fd_max;
b.liu8f231a12024-05-31 17:55:06 +0800388 fd_max = (gnss_info.exit_fd[0] > fd_max) ? gnss_info.exit_fd[0] : fd_max;
b.liud0ba7152024-06-19 14:47:21 +0800389 memset(nmea_buff, 0, sizeof(nmea_buff));
390 memset(data_buff, 0, sizeof(data_buff));
391 nmea_buff_len = 0;
392 data_buff_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800393#if GNSS_DEBUG
b.liu8f231a12024-05-31 17:55:06 +0800394 if(nmea_log_enable) {
395 debug_fd = open(GNSS_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
396 if(debug_fd < 0) {
397 LOGE("Open debug fd fail.");
398 }
399 nmea_log_fd = open(GNSS_NMEA_FILE_LOG, O_WRONLY | O_CREAT | O_TRUNC, 0666);
400 if(nmea_log_fd < 0) {
401 LOGE("Open nmea fd fail.");
402 }
b.liu99c645d2024-06-20 10:52:15 +0800403 debug_fd_len = 0;
b.liu8f231a12024-05-31 17:55:06 +0800404 }
405#endif
406
b.liudbc3f4b2024-06-25 18:22:24 +0800407 LOGD("uart_fd - %d, exit_fd - %d", gnss_info.fd, gnss_info.exit_fd[0]);
408
b.liu8f231a12024-05-31 17:55:06 +0800409 while(gnss_info.state >= GNSS_STATE_OPEN) {
wangyouqiang55d36bf2024-06-27 09:35:52 +0800410 FD_ZERO(&fdw);
411 FD_ZERO(&fdr);
412 FD_SET(gnss_info.fd, &fdr);
413 FD_SET(gnss_info.exit_fd[0], &fdr);
b.liu8f231a12024-05-31 17:55:06 +0800414 ret = select(fd_max + 1, &fdr, &fdw, 0, NULL);
415 //LOGD("select - %d", ret);
b.liuece0db02024-06-25 18:39:09 +0800416 if(gnss_info.state < GNSS_STATE_OPEN) {
417 LOGD("State = %d, ret = %d", gnss_info.state, ret);
418 if(ret > 0) {
419 if (FD_ISSET(gnss_info.fd, &fdr)) {
420 LOGD("gnss_fd can read.");
421 } else if (FD_ISSET(gnss_info.exit_fd[0], &fdr)) {
422 LOGD("exit_fd can read.");
423 } else {
424 LOGW("Unknown select event.");
425 }
426 }
427 break;
428 }
429
b.liu8f231a12024-05-31 17:55:06 +0800430 if (ret < 0)
431 {
432 if (errno == EINTR)
433 {
434 continue;
435 }
436 LOGE("select error, errno = %d (%s)", errno, strerror(errno));
437 break;
438 }
439 else if (ret == 0)
440 {
441 LOGE("select ret == 0");
442 break;
443 }
444
445 if (FD_ISSET(gnss_info.fd, &fdr))
446 {
447 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liu99c645d2024-06-20 10:52:15 +0800448 len = read(gnss_info.fd, buffer, GNSS_BUFF_SIZE - 1);
b.liu8f231a12024-05-31 17:55:06 +0800449 if(len > 0) {
450 //log_hex("READ", buffer, len);
451
452#if GNSS_DEBUG
b.liu99c645d2024-06-20 10:52:15 +0800453 //LOGD("read data_len = %d", len);
454 log_save(debug_fd, buffer, len);
b.liu8f231a12024-05-31 17:55:06 +0800455#endif
456
457 gnss_data_process(buffer, len);
458
459 } else if(len ==0 ){
460 LOGE("Read end : len = 0");
461 break;
462 } else {
463 if(EAGAIN == errno) {
464 usleep(50000);
465 continue;
466 } else {
467 LOGD("Read ret = -1 ,errno = %d", errno);
468 break;
469 }
470 }
471 }
472 else if (FD_ISSET(gnss_info.exit_fd[0], &fdr))
473 {
b.liuece0db02024-06-25 18:39:09 +0800474 LOGD("exit_fd select event.");
b.liu8f231a12024-05-31 17:55:06 +0800475 memset(buffer, 0, GNSS_BUFF_SIZE);
b.liudbc3f4b2024-06-25 18:22:24 +0800476 len = read(gnss_info.exit_fd[0], buffer, GNSS_BUFF_SIZE);
b.liu8f231a12024-05-31 17:55:06 +0800477 if(len > 0) {
478 if(strcmp(buffer, "exit") == 0) {
479 LOGD("Get thread exit message.");
480 break;
481 }
482 }
483 }
484 else
485 {
486 LOGW("Unknown select event.");
487 continue;
488 }
489 }
490
491#if GNSS_DEBUG
492 if(debug_fd > 0) {
493 close(debug_fd);
494 debug_fd = -1;
495 }
496 if(nmea_log_fd > 0) {
497 close(nmea_log_fd);
498 nmea_log_fd = -1;
499 }
500#endif
501
502 gnss_info.state = GNSS_STATE_CLOSE;
503 LOGD("gnss_read_pthread exit.");
504 return NULL;
505}
506
507#if 0
508int gnss_write(int fd, const void *data, int data_len)
509{
510 int count = 0;
511 int len = 0;
512 while(1)
513 {
514 len = write(fd, data + count, data_len - count);
515 if (len > 0)
516 {
517 count += len;
518 }
519 else
520 {
521 LOGE("write() fail,ret = %d,errno = %d", len, errno);
522 break;
523 }
524
525 if (count == data_len)
526 break;
527 }
528
529 return count;
530}
531#else
b.liu778645e2024-06-21 16:47:42 +0800532int gnss_write(int fd, const void* buf, int buf_len)
b.liu8f231a12024-05-31 17:55:06 +0800533{
b.liu778645e2024-06-21 16:47:42 +0800534 ssize_t size;
535 ssize_t size_to_wr;
b.liu8f231a12024-05-31 17:55:06 +0800536 ssize_t size_written;
537 if(GNSS_BUFF_SIZE < buf_len)
538 {
539 return -1;
540 }
541 for(size = 0; size < buf_len;)
542 {
543 size_to_wr = buf_len - size;
544 if( size_to_wr > GNSS_BUFF_SIZE)
545 size_to_wr = GNSS_BUFF_SIZE;
546
b.liu778645e2024-06-21 16:47:42 +0800547 size_written = write(fd, (const uint8*)buf + size, size_to_wr);
b.liu8f231a12024-05-31 17:55:06 +0800548 if (size_written==-1)
549 {
550 return -1;
551 }
552 size += size_written;
553 if(size_written != size_to_wr)
554 {
555 return size;
556 }
557 }
558 // LOGD("SEND %d / %d", size, buf_len);
559 return size;
560}
561#endif
562
563int gnss_init(uint32 print_port)
564{
565 if(gnss_info.state != GNSS_STATE_CLOSE) {
566 LOGW("GNSS not close:%d", gnss_info.state);
b.liudbc3f4b2024-06-25 18:22:24 +0800567 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800568 }
569
570 int ret = 0;
b.liu99c645d2024-06-20 10:52:15 +0800571 if(gnss_info.dl_befor_open) {
572 //if(gnss_info.auto_dl_fw) {
573 gnss_info.state = GNSS_STATE_DOWNLOAD;
b.liudbc3f4b2024-06-25 18:22:24 +0800574 ret = gnss_info.gnss_fw_dl(gnss_info.fd, NULL, gnss_info.dev_name);
b.liu99c645d2024-06-20 10:52:15 +0800575 if(ret) {
576 LOGE("gnss_fw_dl() fail : %d", ret);
577 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800578 return GNSS_ERR_DL_FW;
b.liu99c645d2024-06-20 10:52:15 +0800579 }
b.liu8f231a12024-05-31 17:55:06 +0800580
b.liu99c645d2024-06-20 10:52:15 +0800581 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
582 if(gnss_info.fd <= 0) {
583 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
584 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800585 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800586 }
587 if(pipe(gnss_info.exit_fd)) {
588 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800589 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800590 }
591 // GNSS is opened.
592 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800593
b.liu99c645d2024-06-20 10:52:15 +0800594#if 0
595 // Start gnss read thread.
596 pthread_attr_t thread_attr;
597 pthread_attr_init(&thread_attr);
598 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
599 {
600 LOGE("pthread_attr_setdetachstate() fail.");
601 goto main_exit;
602 }
b.liu8f231a12024-05-31 17:55:06 +0800603
b.liu99c645d2024-06-20 10:52:15 +0800604 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800605#else
b.liu99c645d2024-06-20 10:52:15 +0800606 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
b.liu8f231a12024-05-31 17:55:06 +0800607#endif
b.liu99c645d2024-06-20 10:52:15 +0800608 {
609 LOGE("pthread_create() fail.");
610 goto exit_with_close;
611 }
b.liu8f231a12024-05-31 17:55:06 +0800612
b.liu99c645d2024-06-20 10:52:15 +0800613 ret = gnss_info.gnss_dev_open();
614 if(ret) {
615 LOGE("gnss_dev_open() fail : %d", ret);
616 goto exit_with_thread_exit;
617 }
618 //}
619 } else {
620 gnss_info.fd = gnss_info.gnss_open(gnss_info.dev_name);
621 if(gnss_info.fd <= 0) {
622 LOGE("gnss_open(%s) fail : %d", gnss_info.dev_name, gnss_info.fd);
623 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800624 return GNSS_ERR_OPEN_DEV;
b.liu99c645d2024-06-20 10:52:15 +0800625 }
626 if(pipe(gnss_info.exit_fd)) {
627 LOGE("pipe() fail[%d].", errno);
b.liudbc3f4b2024-06-25 18:22:24 +0800628 return GNSS_ERR_UNKNOWN;
b.liu99c645d2024-06-20 10:52:15 +0800629 }
630 // GNSS is opened.
631 gnss_info.state = GNSS_STATE_OPEN;
b.liu8f231a12024-05-31 17:55:06 +0800632
b.liu99c645d2024-06-20 10:52:15 +0800633#if 0
634 // Start gnss read thread.
635 pthread_attr_t thread_attr;
636 pthread_attr_init(&thread_attr);
637 if(pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_DETACHED))
638 {
639 LOGE("pthread_attr_setdetachstate() fail.");
640 goto main_exit;
641 }
642
643 if(pthread_create(&gnss_info.read_pid, &thread_attr, gnss_read_pthread, NULL))
644#else
645 if(pthread_create(&gnss_info.read_pid, NULL, gnss_read_pthread, NULL))
646#endif
647 {
648 LOGE("pthread_create() fail.");
649 goto exit_with_close;
650 }
651
652 ret = gnss_info.gnss_dev_open();
b.liu8f231a12024-05-31 17:55:06 +0800653 if(ret) {
b.liu99c645d2024-06-20 10:52:15 +0800654 LOGE("gnss_dev_open() fail : %d", ret);
655 goto exit_with_thread_exit;
656 }
b.liu8f231a12024-05-31 17:55:06 +0800657 }
658
659 // GNSS is ready, NMEA can print from uart.
660 gnss_info.state = GNSS_STATE_READY;
661 gnss_info.print_port = print_port;
662
663 LOGD("GNSS open success.");
664
665 return gnss_ports_open(gnss_info.print_port);
666
667exit_with_dev_close:
668 if(gnss_info.gnss_dev_close()) {
669 LOGE("gnss_dev_close() fail.");
670 }
671exit_with_thread_exit:
672 gnss_info.state = GNSS_STATE_CLOSING;
673 // Wait for read thread exit.
674 ret = pthread_join(gnss_info.read_pid, NULL);
675 if(ret){
676 LOGE("pthrad_join fail(%d)",ret);
677 }
678exit_with_close:
679 if(gnss_info.gnss_close(gnss_info.fd)) {
680 LOGE("gnss_close() fail.");
681 }
682 if(gnss_info.exit_fd[0] > 0) {
683 close(gnss_info.exit_fd[0]);
684 gnss_info.exit_fd[0] = -1;
685 }
686 if(gnss_info.exit_fd[1] > 0) {
687 close(gnss_info.exit_fd[1]);
688 gnss_info.exit_fd[1] = -1;
689 }
690 gnss_info.state = GNSS_STATE_CLOSE;
b.liudbc3f4b2024-06-25 18:22:24 +0800691 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800692}
693
694int gnss_deinit()
695{
696 if(gnss_info.state == GNSS_STATE_CLOSE) {
697 LOGW("GNSS is closed.");
b.liudbc3f4b2024-06-25 18:22:24 +0800698 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800699 } else if(gnss_info.state == GNSS_STATE_CLOSING) {
700 LOGW("GNSS is closing...");
b.liudbc3f4b2024-06-25 18:22:24 +0800701 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800702 } else if(gnss_info.state == GNSS_STATE_DOWNLOAD) {
703 LOGW("GNSS is downloading...");
b.liudbc3f4b2024-06-25 18:22:24 +0800704 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800705 }
706
707 // Wait for read thread exit.
708 if(gnss_info.exit_fd[1] > 0) {
709 write(gnss_info.exit_fd[1], "exit", 4);
710 }
711
712 gnss_info.state = GNSS_STATE_CLOSING;
713 int ret = pthread_join(gnss_info.read_pid, NULL);
714 if(ret){
715 LOGE("pthrad_join fail(%d)",ret);
b.liudbc3f4b2024-06-25 18:22:24 +0800716 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800717 }
718
719 if(gnss_info.gnss_close(gnss_info.fd)) {
720 LOGE("gnss_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800721 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800722 }
723
724 if(gnss_info.gnss_dev_close()) {
725 LOGE("gnss_dev_close() fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800726 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800727 }
728
729 if(gnss_ports_close()) {
730 LOGE("gnss_ports_close fail.");
b.liudbc3f4b2024-06-25 18:22:24 +0800731 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800732 }
733
b.liud0ba7152024-06-19 14:47:21 +0800734 LOGD("gnss_ports_close() complete.");
735
b.liu8f231a12024-05-31 17:55:06 +0800736 gnss_info.fd = -1;
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;
746 LOGD("GNSS close success.");
b.liudbc3f4b2024-06-25 18:22:24 +0800747 return GNSS_ERR_OK;
b.liu8f231a12024-05-31 17:55:06 +0800748}
749
750int gnss_set(const void* buf, unsigned int buf_len, void *cmd_rsp, int cmd_rsp_len)
751{
b.liud0ba7152024-06-19 14:47:21 +0800752 if(buf && buf_len > 0) {
753 if(cmd_rsp && cmd_rsp_len > 0) {
754 memset(cmd_rsp, 0, cmd_rsp_len);
755 }
b.liu8f231a12024-05-31 17:55:06 +0800756 return gnss_info.gnss_set(gnss_info.fd, buf, cmd_rsp, cmd_rsp_len);
757 } else {
b.liudbc3f4b2024-06-25 18:22:24 +0800758 return GNSS_ERR_UNKNOWN;
759 }
760}
761
762int gnss_dl_fw(const char* fw_name, void *rsp, int rsp_len)
763{
764 if(gnss_info.gnss_id != GNSS_TYPE_8122) {
765 return GNSS_ERR_UNSUPPORT;
766 }
767
768 if(rsp && rsp_len > 0) {
769 memset(rsp, 0, rsp_len);
770 }
771
772 if(gnss_info.gnss_fw_dl) {
773 if(GNSS_ERR_OK != gnss_deinit()) {
774 LOGE("Close gnss fail.");
775 return GNSS_ERR_UNKNOWN;
776 } else {
777 LOGD("Start gnss fw dl.");
778 return gnss_info.gnss_fw_dl(gnss_info.fd, fw_name, gnss_info.dev_name);
779 }
780 } else {
781 return GNSS_ERR_UNKNOWN;
b.liu8f231a12024-05-31 17:55:06 +0800782 }
783}
784
785static void sig_process(int sig)
786{
787 LOGI("I got signal %d\n", sig);
788 if(gnss_deinit()) {
789 LOGE("gnss_deinit() fail, no exist...");
790 return;
791 }
792
793 switch(sig)
794 {
795 case SIGINT: // Ctrl + C
796 {
797 LOGI("Exit by SIGINT.\n");
798 exit(0);
799 }
800 case SIGQUIT: // Ctrl + \ (ÀàËÆ SIGINT £¬µ«Òª²úÉúcoreÎļþ)
801 {
802 LOGI("Exit by SIGQUIT.\n");
803 exit(0);
804 }
805 case SIGTERM:// ĬÈÏkill (ͬ SIGKILL £¬µ« SIGKILL ²»¿É²¶»ñ)
806 {
807 LOGI("Exit by SIGTERM.\n");
808 exit(0);
809 }
810 case SIGTSTP:// Ctrl + Z (ͬ SIGSTOP £¬µ« SIGSTOP ²»¿É²¶»ñ)
811 {
812 LOGI("Exit by SIGTSTP.\n");
813 exit(0);
814 }
815 case SIGSEGV: // Èç¿ÕÖ¸Õë
816 {
817 LOGI("Exit by SIGSEGV.\n");
818 exit(0);
819 }
820 default:
821 {
822 LOGI("Unknown sig:%d\n",sig);
823 break;
824 }
825 }
826}
827
828
829// mbtk_gnssd 6228 /dev/ttyS2 baud 0/1
830int main(int argc, char *argv[])
831{
832 mbtk_log_init("radio", GNSS_TAG);
833
b.liubb590492024-06-13 16:42:08 +0800834#ifdef MBTK_DUMP_SUPPORT
835 mbtk_debug_open(NULL, TRUE);
836#endif
837
b.liu8f231a12024-05-31 17:55:06 +0800838 signal(SIGINT, sig_process);
839 signal(SIGQUIT, sig_process);
840 signal(SIGTERM, sig_process);
841
842 if(arg_check(argc, argv)) {
843 return -1;
844 }
845
846#ifdef GNSS_DEBUG
847 char buff[10];
848 memset(buff, 0, 10);
849 property_get(MBTK_PROP_GNSS_LOG, buff, "");
850 if(strlen(buff) > 0 && atoi(buff) > 0) {
851 nmea_log_enable = TRUE;
852 }
853#endif
854
855 memset(&gnss_info, 0, sizeof(gnss_info_t));
856 memcpy(gnss_info.dev_name, argv[2], strlen(argv[2]));
857 gnss_info.state = GNSS_STATE_CLOSE;
858 if(!strcmp(argv[1], GNSS_ID_6228)) {
859 gnss_info.gnss_id = GNSS_TYPE_6228;
860 gnss_info.auto_open = (bool)atoi(argv[3]);
861 gnss_info.auto_dl_fw = TRUE;
b.liu99c645d2024-06-20 10:52:15 +0800862 gnss_info.dl_befor_open = FALSE;
b.liu8f231a12024-05-31 17:55:06 +0800863 gnss_info.gnss_dev_open = gnss_6228_dev_open;
864 gnss_info.gnss_dev_close = gnss_6228_dev_close;
865 gnss_info.gnss_open = gnss_6228_open;
866 gnss_info.gnss_close = gnss_6228_close;
867 gnss_info.gnss_fw_dl = gnss_6228_fw_dl;
868 gnss_info.gnss_dl_read_cb = gnss_6228_dl_read_cb;
869 gnss_info.gnss_set = gnss_6228_set;
870 gnss_info.gnss_set_cb = gnss_6228_set_cb;
b.liuf9fbfa12024-06-14 15:53:59 +0800871 } else if(!strcmp(argv[1], GNSS_ID_8122)) {
872 gnss_info.gnss_id = GNSS_TYPE_8122;
873 gnss_info.auto_open = (bool)atoi(argv[3]);
874 gnss_info.auto_dl_fw = FALSE;
b.liu99c645d2024-06-20 10:52:15 +0800875 gnss_info.dl_befor_open = FALSE;
b.liuf9fbfa12024-06-14 15:53:59 +0800876 gnss_info.gnss_dev_open = gnss_8122_dev_open;
877 gnss_info.gnss_dev_close = gnss_8122_dev_close;
878 gnss_info.gnss_open = gnss_8122_open;
879 gnss_info.gnss_close = gnss_8122_close;
880 gnss_info.gnss_fw_dl = gnss_8122_fw_dl;
881 gnss_info.gnss_dl_read_cb = NULL;
882 gnss_info.gnss_set = gnss_8122_set;
b.liu5f950c52024-06-15 20:13:12 +0800883 gnss_info.gnss_set_cb = gnss_8122_set_cb;
b.liu99c645d2024-06-20 10:52:15 +0800884 } else if(!strcmp(argv[1], GNSS_ID_5311)) {
885 gnss_info.gnss_id = GNSS_TYPE_5311;
886 gnss_info.auto_open = (bool)atoi(argv[3]);
887 gnss_info.auto_dl_fw = TRUE;
888 gnss_info.dl_befor_open = TRUE;
889 gnss_info.gnss_dev_open = gnss_5311_dev_open;
890 gnss_info.gnss_dev_close = gnss_5311_dev_close;
891 gnss_info.gnss_open = gnss_5311_open;
892 gnss_info.gnss_close = gnss_5311_close;
893 gnss_info.gnss_fw_dl = gnss_5311_fw_dl;
894 gnss_info.gnss_dl_read_cb = NULL;
895 gnss_info.gnss_set = gnss_5311_set;
896 gnss_info.gnss_set_cb = gnss_5311_set_cb;
b.liu8f231a12024-05-31 17:55:06 +0800897 } else {
898 LOGE("No support : %s", argv[1]);
899 return -1;
900 }
901
902 LOGD("GNSS : %s, Device: %s", argv[1], gnss_info.dev_name);
903 // Auto open gnss.
904 if(gnss_info.auto_open) {
905 if(gnss_init(0)) { // No print to any port.
906 LOGE("gnss_init() fail.");
907 return -1;
908 }
909 }
910
911 // Init ubus and waitting IPC commands.
b.liud0ba7152024-06-19 14:47:21 +0800912#ifdef MBTK_GNSS_UBUS_ENABLE
b.liu8f231a12024-05-31 17:55:06 +0800913 if(gnss_ubus_init()) {
914 LOGD("main() run...");
915 uloop_run();
916 } else {
917 LOGE("gnss_ubus_init() fail.");
918 }
b.liu5f950c52024-06-15 20:13:12 +0800919#else
920 if(!gnss_ipc_service_start()) {
921 LOGD("main() run...");
922 while(1) {
923 sleep(24 * 60 * 60);
924 }
925 } else {
926 LOGE("gnss_ipc_service_start() fail.");
927 }
928#endif
b.liu8f231a12024-05-31 17:55:06 +0800929
930 LOGD("main() exit.");
931 return 0;
932}