blob: e0fa746ccc24f016a6fc398d7fd830ab56f691c3 [file] [log] [blame]
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <fcntl.h>
#include <termios.h>
#include <string.h>
#include <stdarg.h>
#include "mbtk_type.h"
#include "mbtk_log.h"
#define DATABITS CS8
#define STOPBITS 0
#define PARITYON 0
#define PARITY 0
#define MBTK_SLAVE_DEV_NAME_MAX_LEN 24
int uart_baud_get(int baud)
{
int rate = 0;
switch(baud)
{
case 300:
rate = B300;
break;
case 600:
rate = B600;
break;
case 1200:
rate = B1200;
break;
case 2400:
rate = B2400;
break;
case 4800:
rate = B4800;
break;
case 9600:
rate = B9600;
break;
case 19200:
rate = B19200;
break;
case 38400:
rate = B38400;
break;
case 57600:
rate = B57600;
break;
case 115200:
rate = B115200;
break;
case 230400:
rate = B230400;
break;
case 460800:
rate = B460800;
break;
case 921600:
rate = B921600;
break;
case 1500000:
rate = B1500000;
break;
case 2000000:
rate = B2000000;
break;
case 3000000:
rate = B3000000;
break;
case 4000000:
rate = B4000000;
break;
default:
rate = B115200;
break;
}
return rate;
}
int gnss_port_open(const char *dev, int flag, int baud, bool tty)
{
int fd = -1;
if((fd = open(dev, flag)) < 0)
{
LOGE("Open %s fail errno = [%d].", dev, errno);
return -1;
}
LOGD("Open %s success.", dev);
if (tty)
{
int rate = uart_baud_get(baud);
/* set newtio */
struct termios newtio;
memset(&newtio, 0, sizeof(newtio));
//(void)fcntl(fd, F_SETFL, 0);
/* no flow control for uart by default */
newtio.c_cflag = rate | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
//newtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
newtio.c_oflag = 0;
newtio.c_lflag = 0; /* disable ECHO, ICANON, etc... */
newtio.c_cc[VERASE] = 0x8; /* del */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtio.c_cc[VEOL] = 0xD; /* '\0' */
tcflush(fd, TCIOFLUSH);
tcsetattr(fd, TCSANOW, &newtio);
}
return fd;
}
int gnss_port_close(int fd)
{
if(fd > 0)
{
close(fd);
}
return 0;
}
int gnss_set_baudrate(int fd, int baudrate)
{
struct termios options, oldtio;
if(fcntl(fd, F_SETFL, 0) < 0) {
LOGE("fcntl failed!");
return -1;
}
if(tcgetattr(fd, &oldtio) != 0) {
LOGE("setup serial error!");
return -1;
}
/* Get the current options for the port... */
tcgetattr(fd, &options);
/* Set the baud rates to baudrate... */
cfsetispeed(&options,baudrate);
cfsetospeed(&options,baudrate);
tcsetattr(fd, TCSANOW, &options);
if (0 != tcgetattr(fd, &options))
{
LOGE("get options error!");
return -1;
}
/*
* 8bit Data,no partity,1 stop bit...
*/
options.c_cflag &= ~PARENB;//无奇偶校验
options.c_cflag &= ~CSTOPB;//停止位,1位
options.c_cflag &= ~CSIZE; //数据位的位掩码
options.c_cflag |= CS8; //数据位,8位
cfmakeraw(&options);
/*
* Set the new options for the port...
*/
if (tcsetattr(fd, TCSANOW, &options) != 0)
{
LOGE("setup serial error!");
return -1 ;
}
return 0 ;
}
uint16 get_crc16(const char *ptr, uint16 count)
{
uint16 crc, i;
crc = 0;
while(count--)
{
crc = crc ^ (int) *ptr++ << 8;
for(i = 0; i < 8; i++)
{
if(crc & 0x8000)
crc = crc << 1 ^ 0x1021;
else
crc = crc << 1;
}
}
return (crc & 0xFFFF);
}
int gnss_pty_open(int *master_fd, int *slave_fd, const char *dev)
{
int flags = -1;
int ret = -1;
if(*master_fd > 0) {
LOGD("PTY has inited.");
return 0;
}
char spty_name[MBTK_SLAVE_DEV_NAME_MAX_LEN] = {0};
int result = openpty(master_fd, slave_fd, spty_name, NULL, NULL);
if (-1 == result) {
LOGE("Failed to get a pty.");
return -1;
}
LOGD("Get a pty pair, FD -- master[%d] slave[%d]", *master_fd, *slave_fd);
LOGD("Slave name is:%s", spty_name);
if(access(dev, F_OK) == -1)
{
LOGD("symlink %s -> %s", spty_name, dev);
result = symlink(spty_name, dev);
if (-1 == result) {
LOGE("symlink error.");
goto ERROR;
}
}
flags = fcntl(*master_fd, F_GETFL);
if (flags == -1)
{
LOGE("fcntl get error.");
goto ERROR;
}
flags |= O_NONBLOCK;
flags |= O_NOCTTY;
ret = fcntl(*master_fd, F_SETFL, flags);
if(ret == -1)
{
LOGE("fcntl set error.");
goto ERROR;
}
if (1) {
/* set newtio */
struct termios newtio;
memset(&newtio, 0, sizeof(newtio));
/* no flow control for uart by default */
newtio.c_cflag = B115200 | CRTSCTS | DATABITS | STOPBITS | PARITYON | PARITY | CLOCAL | CREAD;
newtio.c_iflag = IGNPAR;
//newtio.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
newtio.c_oflag = 0;
newtio.c_lflag = 0; /* disable ECHO, ICANON, etc... */
newtio.c_cc[VERASE] = 0x8; /* del */
newtio.c_cc[VEOF] = 4; /* Ctrl-d */
newtio.c_cc[VMIN] = 1; /* blocking read until 1 character arrives */
newtio.c_cc[VEOL] = 0xD; /* '\0' */
tcflush(*master_fd, TCIFLUSH);
tcsetattr(*master_fd, TCSANOW, &newtio);
}
return 0;
ERROR:
if (0 < *master_fd) {
close(*master_fd);
*master_fd = -1;
}
if (0 < *slave_fd) {
close(*slave_fd);
*slave_fd = -1;
}
return -1;
}
int gnss_nmea_sscanf(const char *str, char *ret,...)
{
const char *ptr = str;
char *argv[16];
int argc;
va_list ap;
int i = 0;
va_start(ap, ret);
argc = 0;
argv[argc] = ret; // First arg.
do {
i = 0;
while(*ptr && *ptr != ',' && *ptr != '*') {
argv[argc][i++] = *ptr++;
}
ptr++; // Jump ',' or '*'
argc++;
} while((argv[argc] = va_arg(ap, char*)) != 0);
va_end(ap);
return argc;
}
void gnssStartTimer(struct uloop_timeout *timeout, int timeVal)
{
//UNUSED(timeout);
LOGD("%s: timeVal=%lu.", __FUNCTION__, timeVal);
uloop_timeout_set(timeout, timeVal);
return;
}
void gnssStopTimer(struct uloop_timeout *timeout)
{
//UNUSED(timeout);
uloop_timeout_cancel(timeout);
return;
}