AP05/uart_utils/read_utils.c

177 lines
4.5 KiB
C

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <errno.h>
#include "read_utils.h"
#define PRINT_TIME_TAG
#define DBG_TAG "read_utils"
#define DBG_LVL DBG_INFO
#include "debug_print.h"
/*************************************************************
* 功能: 设定的时间内读取数据
**************************************************************/
int read_data_until_time(int fd, char *buffer, int len, int timeout_first, int timeout_interval)
{
unsigned char c = '\0';
fd_set fds;
struct timeval tv;
int ret;
int i;
memset(buffer, 0, len);
for(i=0; i<len; i++){
FD_ZERO(&fds);
FD_SET(fd, &fds);
// 每次都要重新设置超时时间,因为 select 会修改 tv
tv.tv_sec = 0;
tv.tv_usec = (i == 0) ? timeout_first*1000 : timeout_interval*1000;
// 确保超时时间正确设置
if(tv.tv_usec >= 1000000) {
tv.tv_sec = tv.tv_usec / 1000000;
tv.tv_usec = tv.tv_usec % 1000000;
}
ret = select(fd + 1, &fds, NULL, NULL, &tv);
if(ret < 0){
LOG_I("%s:select error, errno=%d (%s), fd=%d\n",__func__, errno, strerror(errno), fd);
i = -1;
break;
}else if(ret > 0){
if(FD_ISSET(fd, &fds)){
ret = read(fd, &c, 1);
if(ret < 0){
LOG_I("read error\n");
i = -1;
break;
}else if(ret == 0){
//LOG_I("end of file\n");
break;
}else{
buffer[i] = c;
}
}
}else{
//LOG_I("read time out\n");
break;
}
}
return i;
}
/*************************************************************
* 功能: 读一串至截止字符的字符串,在设定的时间内读不到数据则函数返回
**************************************************************/
int read_data_until_char(int fd, char *buffer, int len, char until, int timeout_first, int timeout_interval)
{
unsigned char c = '\0';
fd_set fds;
struct timeval tv;
int ret;
int i;
memset(buffer, 0, len);
for(i=0; i<len; i++){
FD_ZERO(&fds);
FD_SET(fd, &fds);
// 每次都要重新设置超时时间,因为 select 会修改 tv
tv.tv_sec = 0;
tv.tv_usec = (i == 0) ? timeout_first*1000 : timeout_interval*1000;
// 确保超时时间正确设置
if(tv.tv_usec >= 1000000) {
tv.tv_sec = tv.tv_usec / 1000000;
tv.tv_usec = tv.tv_usec % 1000000;
}
ret = select(fd + 1, &fds, NULL, NULL, &tv);
if(ret < 0){
LOG_I("%s:select error, errno=%d (%s), fd=%d\n",__func__, errno, strerror(errno), fd);
i = -1;
break;
}else if(ret > 0){
if(FD_ISSET(fd, &fds)){
ret = read(fd, &c, 1);
if(ret < 0){
LOG_I("read error\n");
i = -1;
break;
}else if(ret == 0){
LOG_I("end of file\n");
}else{
buffer[i] = c;
#if 0
LOG_D("i= %d\n", i);
LOG_D("\t,[%#x], <%c>\n", c, c);
#endif
}
}
}else{
if(c == until){
i++;
break;
}
//LOG_I("read time out\n");
}
}
return i;
}
/*************************************************************
* 功能: 读一串至截止字符串的字符串,在设定的时间内读不到数据则函数返回
**************************************************************/
int read_data_until_str(int fd, char *buffer, int len, char *until, int until_len, int timeout_first, int timeout_interval)
{
unsigned char c = '\0';
fd_set fds;
struct timeval tv;
int ret;
int i;
memset(buffer, 0, len);
for(i=0; i<len; i++){
FD_ZERO(&fds);
FD_SET(fd, &fds);
// 每次都要重新设置超时时间,因为 select 会修改 tv
tv.tv_sec = 0;
tv.tv_usec = (i == 0) ? timeout_first*1000 : timeout_interval*1000;
// 确保超时时间正确设置
if(tv.tv_usec >= 1000000) {
tv.tv_sec = tv.tv_usec / 1000000;
tv.tv_usec = tv.tv_usec % 1000000;
}
ret = select(fd + 1, &fds, NULL, NULL, &tv);
if(ret < 0){
LOG_I("%s:select error, errno=%d (%s), fd=%d\n",__func__, errno, strerror(errno), fd);
i = -1;
break;
}else if(ret > 0){
if(FD_ISSET(fd, &fds)){
ret = read(fd, &c, 1);
if(ret < 0){
LOG_I("read error\n");
i = -1;
break;
}else if(ret == 0){
LOG_I("end of file\n");
}else{
buffer[i] = c;
#if 0
LOG_I("i= %d\n", i);
LOG_I("\t,[%#x], <%c>\n", c, c);
#endif
tv.tv_sec = 0;
tv.tv_usec = timeout_interval*1000;
if((i+1) >= until_len) {
if(strncmp(buffer+i+1-until_len, until, until_len) == 0){
i++;
break;
}
}
}
}
}else{
//LOG_I("read time out\n");
}
}
return i;
}