177 lines
4.5 KiB
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;
|
|
}
|