blob: 6f5ad6af751c04b63e59a264b5c415660874e7eb [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 <fcntl.h>
6#include <termios.h>
7#include <string.h>
8#include <stdarg.h>
b.liu778645e2024-06-21 16:47:42 +08009#include <pty.h>
10#include <libubox/uloop.h>
b.liu8f231a12024-05-31 17:55:06 +080011
12#include "mbtk_type.h"
13#include "mbtk_log.h"
14
15#define DATABITS CS8
16#define STOPBITS 0
17#define PARITYON 0
18#define PARITY 0
19#define MBTK_SLAVE_DEV_NAME_MAX_LEN 24
20
21int uart_baud_get(int baud)
22{
23 int rate = 0;
24 switch(baud)
25 {
26 case 300:
27 rate = B300;
28 break;
29 case 600:
30 rate = B600;
31 break;
32 case 1200:
33 rate = B1200;
34 break;
35 case 2400:
36 rate = B2400;
37 break;
38 case 4800:
39 rate = B4800;
40 break;
41 case 9600:
42 rate = B9600;
43 break;
44 case 19200:
45 rate = B19200;
46 break;
47 case 38400:
48 rate = B38400;
49 break;
50 case 57600:
51 rate = B57600;
52 break;
53 case 115200:
54 rate = B115200;
55 break;
56 case 230400:
57 rate = B230400;
58 break;
59 case 460800:
60 rate = B460800;
61 break;
62 case 921600:
63 rate = B921600;
64 break;
65 case 1500000:
66 rate = B1500000;
67 break;
68 case 2000000:
69 rate = B2000000;
70 break;
71 case 3000000:
72 rate = B3000000;
73 break;
74 case 4000000:
75 rate = B4000000;
76 break;
77 default:
78 rate = B115200;
79 break;
80 }
81
82 return rate;
83}
84
85int gnss_port_open(const char *dev, int flag, int baud, bool tty)
86{
87
88 int fd = -1;
89 if((fd = open(dev, flag)) < 0)
90 {
91 LOGE("Open %s fail errno = [%d].", dev, errno);
92 return -1;
93 }
94
95 LOGD("Open %s success.", dev);
96 if (tty)
97 {
98 int rate = uart_baud_get(baud);
99 /* set newtio */
100 struct termios newtio;
101 memset(&newtio, 0, sizeof(newtio));
102 //(void)fcntl(fd, F_SETFL, 0);
103 /* no flow control for uart by default */
104 newtio.c_cflag = rate | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
105 newtio.c_iflag = IGNPAR;
106 //newtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
107 newtio.c_oflag = 0;
108 newtio.c_lflag = 0; /* disable ECHO, ICANON, etc... */
109
110 newtio.c_cc[VERASE] = 0x8; /* del */
111 newtio.c_cc[VEOF] = 4; /* Ctrl-d */
112 newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
113 newtio.c_cc[VEOL] = 0xD; /* '\0' */
114
115 tcflush(fd, TCIOFLUSH);
116 tcsetattr(fd, TCSANOW, &newtio);
117 }
118
119 return fd;
120}
121
122int gnss_port_close(int fd)
123{
124 if(fd > 0)
125 {
126 close(fd);
127 }
128 return 0;
129}
130
131int gnss_set_baudrate(int fd, int baudrate)
132{
133 struct termios options, oldtio;
134
135 if(fcntl(fd, F_SETFL, 0) < 0) {
136 LOGE("fcntl failed!");
137 return -1;
138 }
139
140 if(tcgetattr(fd, &oldtio) != 0) {
141 LOGE("setup serial error!");
142 return -1;
143 }
144
145 /* Get the current options for the port... */
146 tcgetattr(fd, &options);
147
148 /* Set the baud rates to baudrate... */
149 cfsetispeed(&options,baudrate);
150 cfsetospeed(&options,baudrate);
151 tcsetattr(fd, TCSANOW, &options);
152
153 if (0 != tcgetattr(fd, &options))
154 {
155 LOGE("get options error!");
156 return -1;
157 }
158
159 /*
160 * 8bit Data,no partity,1 stop bit...
161 */
162 options.c_cflag &= ~PARENB;//无奇偶校验
163 options.c_cflag &= ~CSTOPB;//停止位,1位
164 options.c_cflag &= ~CSIZE; //数据位的位掩码
165 options.c_cflag |= CS8; //数据位,8位
166
167 cfmakeraw(&options);
168
169 /*
170 * Set the new options for the port...
171 */
172 if (tcsetattr(fd, TCSANOW, &options) != 0)
173 {
174 LOGE("setup serial error!");
175 return -1 ;
176 }
177
178 return 0 ;
179}
180
181uint16 get_crc16(const char *ptr, uint16 count)
182{
183 uint16 crc, i;
184
185 crc = 0;
186 while(count--)
187 {
188 crc = crc ^ (int) *ptr++ << 8;
189
190 for(i = 0; i < 8; i++)
191 {
192 if(crc & 0x8000)
193 crc = crc << 1 ^ 0x1021;
194 else
195 crc = crc << 1;
196 }
197 }
198
199 return (crc & 0xFFFF);
200}
201
202int gnss_pty_open(int *master_fd, int *slave_fd, const char *dev)
203{
204 int flags = -1;
205 int ret = -1;
206 if(*master_fd > 0) {
207 LOGD("PTY has inited.");
208 return 0;
209 }
210 char spty_name[MBTK_SLAVE_DEV_NAME_MAX_LEN] = {0};
211 int result = openpty(master_fd, slave_fd, spty_name, NULL, NULL);
212 if (-1 == result) {
213 LOGE("Failed to get a pty.");
214 return -1;
215 }
216
217 LOGD("Get a pty pair, FD -- master[%d] slave[%d]", *master_fd, *slave_fd);
218 LOGD("Slave name is:%s", spty_name);
219
220 if(access(dev, F_OK) == -1)
221 {
222 LOGD("symlink %s -> %s", spty_name, dev);
223 result = symlink(spty_name, dev);
224 if (-1 == result) {
225 LOGE("symlink error.");
226 goto ERROR;
227 }
228 }
229
230 flags = fcntl(*master_fd, F_GETFL);
231 if (flags == -1)
232 {
233 LOGE("fcntl get error.");
234 goto ERROR;
235 }
236 flags |= O_NONBLOCK;
237 flags |= O_NOCTTY;
238 ret = fcntl(*master_fd, F_SETFL, flags);
239 if(ret == -1)
240 {
241 LOGE("fcntl set error.");
242 goto ERROR;
243 }
244
245 if (1) {
246 /* set newtio */
247 struct termios newtio;
248 memset(&newtio, 0, sizeof(newtio));
249 /* no flow control for uart by default */
250 newtio.c_cflag = B115200 | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
251 newtio.c_iflag = IGNPAR;
252 //newtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
253 newtio.c_oflag = 0;
254 newtio.c_lflag = 0; /* disable ECHO, ICANON, etc... */
255
256 newtio.c_cc[VERASE] = 0x8; /* del */
257 newtio.c_cc[VEOF] = 4; /* Ctrl-d */
258 newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
259 newtio.c_cc[VEOL] = 0xD; /* '\0' */
260
261 tcflush(*master_fd, TCIFLUSH);
262 tcsetattr(*master_fd, TCSANOW, &newtio);
263 }
264 return 0;
265
266ERROR:
267 if (0 < *master_fd) {
268 close(*master_fd);
269 *master_fd = -1;
270 }
271
272 if (0 < *slave_fd) {
273 close(*slave_fd);
274 *slave_fd = -1;
275 }
276
277 return -1;
278}
279
280int gnss_nmea_sscanf(const char *str, char *ret,...)
281{
282 const char *ptr = str;
283 char *argv[16];
284 int argc;
285 va_list ap;
286 int i = 0;
287
288 va_start(ap, ret);
289 argc = 0;
290 argv[argc] = ret; // First arg.
291
292 do {
293 i = 0;
294 while(*ptr && *ptr != ',' && *ptr != '*') {
295 argv[argc][i++] = *ptr++;
296 }
297 ptr++; // Jump ',' or '*'
298 argc++;
299 } while((argv[argc] = va_arg(ap, char*)) != 0);
300
301 va_end(ap);
302
303 return argc;
304}
305
306void gnssStartTimer(struct uloop_timeout *timeout, int timeVal)
307{
308 //UNUSED(timeout);
309 LOGD("%s: timeVal=%lu.", __FUNCTION__, timeVal);
310 uloop_timeout_set(timeout, timeVal);
311 return;
312}
313
314void gnssStopTimer(struct uloop_timeout *timeout)
315{
316 //UNUSED(timeout);
317 uloop_timeout_cancel(timeout);
318 return;
319}
320