211 lines
5.3 KiB
C
211 lines
5.3 KiB
C
#include "ttydevice.h"
|
|
static int tty_set_device(PROFILE_T *profile, FDS_T *fds)
|
|
{
|
|
int baud_rate, data_bits;
|
|
struct termios tty;
|
|
baud_rate = profile->baud_rate;
|
|
data_bits = profile->data_bits;
|
|
if (tcgetattr(fds->tty_fd, &tty) != 0)
|
|
{
|
|
err_msg("Error getting tty attributes");
|
|
return COMM_ERROR;
|
|
}
|
|
memmove(&fds->old_termios, &tty, sizeof(struct termios));
|
|
cfmakeraw(&tty);
|
|
tty.c_cflag |= CLOCAL; // 忽略调制解调器控制线,允许本地连接
|
|
tty.c_cflag |= CREAD; // 使能接收
|
|
|
|
// clear flow control ,stop bits parity
|
|
tty.c_cflag &= ~CRTSCTS;
|
|
tty.c_cflag &= ~CSTOPB;
|
|
tty.c_cflag &= ~PARENB;
|
|
tty.c_oflag &= ~OPOST;
|
|
tty.c_cc[VMIN] = 0;
|
|
tty.c_cc[VTIME] = 1;
|
|
|
|
// set data bits 5,6,7,8
|
|
tty.c_cflag &= ~CSIZE; // 清除数据位设置
|
|
switch (data_bits)
|
|
{
|
|
case 5:
|
|
tty.c_cflag |= CS5;
|
|
break;
|
|
case 6:
|
|
tty.c_cflag |= CS6;
|
|
break;
|
|
case 7:
|
|
tty.c_cflag |= CS7;
|
|
break;
|
|
case 8:
|
|
tty.c_cflag |= CS8;
|
|
break;
|
|
default:
|
|
tty.c_cflag |= CS8;
|
|
break;
|
|
}
|
|
|
|
// set baud rate
|
|
switch (baud_rate)
|
|
{
|
|
case 4800:
|
|
cfsetspeed(&tty, B4800);
|
|
break;
|
|
case 9600:
|
|
cfsetspeed(&tty, B9600);
|
|
break;
|
|
case 19200:
|
|
cfsetspeed(&tty, B19200);
|
|
break;
|
|
case 38400:
|
|
cfsetspeed(&tty, B38400);
|
|
break;
|
|
case 57600:
|
|
cfsetspeed(&tty, B57600);
|
|
break;
|
|
case 115200:
|
|
cfsetspeed(&tty, B115200);
|
|
break;
|
|
|
|
default:
|
|
cfsetspeed(&tty, B115200);
|
|
break;
|
|
}
|
|
if (tcsetattr(fds->tty_fd, TCSANOW, &tty) != 0)
|
|
{
|
|
err_msg("Error setting tty attributes");
|
|
return COMM_ERROR;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
int tty_open_device(PROFILE_T *profile,FDS_T *fds)
|
|
{
|
|
fds->tty_fd = open(profile->tty_dev, O_RDWR | O_NOCTTY);
|
|
if (fds->tty_fd < 0)
|
|
{
|
|
err_msg("Error opening tty device: %s", profile->tty_dev);
|
|
return COMM_ERROR;
|
|
}
|
|
|
|
if (tty_set_device(profile,fds) != 0)
|
|
{
|
|
err_msg("Error setting tty device");
|
|
return COMM_ERROR;
|
|
}
|
|
tcflush(fds->tty_fd, TCIOFLUSH);
|
|
if (fds->tty_fd >= 0)
|
|
close(fds->tty_fd);
|
|
else
|
|
return COMM_ERROR;
|
|
fds->tty_fd = open(profile->tty_dev, O_RDWR | O_NOCTTY | O_NONBLOCK);
|
|
fds->fdi = fdopen(fds->tty_fd, "r");
|
|
fds->fdo = fdopen(fds->tty_fd, "w");
|
|
if (fds->fdi == NULL || fds->fdo == NULL)
|
|
{
|
|
err_msg("Error opening file descriptor");
|
|
return COMM_ERROR;
|
|
}
|
|
|
|
if (setvbuf(fds->fdo , NULL, _IOFBF, 0))
|
|
{
|
|
err_msg("Error setting buffer for fdi");
|
|
return COMM_ERROR;
|
|
}
|
|
|
|
if (setvbuf(fds->fdi , NULL, _IOLBF, 0))
|
|
{
|
|
err_msg("Error setting buffer for fdi");
|
|
return COMM_ERROR;
|
|
}
|
|
return SUCCESS;
|
|
}
|
|
|
|
int tty_read(FILE *fdi, char *output, int len, int soft_timeout)
|
|
{
|
|
return tty_read_keyword(fdi, output, len, NULL, soft_timeout);
|
|
}
|
|
|
|
int tty_read_keyword(FILE *fdi, char *output, int len, char *key_word, int soft_timeout)
|
|
{
|
|
char tmp[LINE_BUF] = {0};
|
|
int msg_len = 0;
|
|
int read_flag = 0;
|
|
time_t start_time = time(NULL);
|
|
int exitcode = TIMEOUT_WAITING_NEWLINE;
|
|
while (difftime(time(NULL), start_time) < soft_timeout)
|
|
{
|
|
if (fgets(tmp, LINE_BUF, fdi))
|
|
{
|
|
read_flag = 1;
|
|
dbg_msg("%s", tmp);
|
|
if (output != NULL)
|
|
msg_len += snprintf(output + msg_len, len - msg_len, "%s", tmp);
|
|
|
|
if (strncmp(tmp, "OK", 2) == 0 ||
|
|
strncmp(tmp, "ERROR", 5) == 0 ||
|
|
strncmp(tmp, "+CMS ERROR:", 11) == 0 ||
|
|
strncmp(tmp, "+CME ERROR:", 11) == 0 ||
|
|
strncmp(tmp, "NO CARRIER", 10) == 0 ||
|
|
(key_word != NULL && strncmp(tmp, key_word, strlen(key_word)) == 0))
|
|
{
|
|
if (key_word != NULL && strncmp(tmp, key_word, strlen(key_word)) == 0)
|
|
{
|
|
dbg_msg("keyword found");
|
|
exitcode = SUCCESS;
|
|
}
|
|
else if (key_word == NULL)
|
|
{
|
|
exitcode = SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
exitcode = KEYWORD_NOT_MATCH;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
#ifdef EARLY_RETURN
|
|
else
|
|
{
|
|
if (read_flag > 500){
|
|
dbg_msg("early return");
|
|
exitcode = TIMEOUT_WAITING_NEWLINE;
|
|
break;
|
|
}
|
|
if (read_flag){
|
|
read_flag++;
|
|
}
|
|
}
|
|
#endif
|
|
usleep(1000);
|
|
}
|
|
if (read_flag == 0)
|
|
{
|
|
exitcode = COMM_ERROR;
|
|
}
|
|
return exitcode;
|
|
}
|
|
|
|
int tty_write(FILE *fdo, char *input)
|
|
{
|
|
int cmd_len, ret;
|
|
char *cmd_line;
|
|
cmd_len = strlen(input) + 3;
|
|
cmd_line = (char *)malloc(cmd_len);
|
|
if (cmd_line == NULL)
|
|
{
|
|
err_msg("Error allocating memory");
|
|
return COMM_ERROR;
|
|
}
|
|
snprintf(cmd_line, cmd_len, "%s\r\n", input);
|
|
ret = fputs(cmd_line, fdo);
|
|
free(cmd_line);
|
|
fflush(fdo);
|
|
usleep(100);
|
|
if (ret < 0)
|
|
{
|
|
err_msg("Error writing to tty %d" , ret);
|
|
return COMM_ERROR;
|
|
}
|
|
return SUCCESS;
|
|
}
|