/******************************************************************************
Copyright (C), 2001-2011, Huawei Tech. Co., Ltd.
******************************************************************************
File Name :
Version :
Author :
Created : 2012/03/12
Last Modified :
Description :
Function List :
History :
1.Date : 2012/03/12
Author :
Modification: Created file
******************************************************************************/
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include "sqlist.h"
/*详细描述:
使用、、中提供的库函数。
实现接口,每个接口实现1个基本操作:
void getvalidframe():在该函数中实现提取有效帧
输入文件:testcase文件夹下in.txt
输入文件:testcase文件夹下out.txt
检查文件:testcase文件夹下check.txt
帧格式:
说明:
1、接收开始后,连续收到3个或以上0x7E为有效帧头
2、收到有效帧头后,帧内容中可能包含多个连续0x7E,此时作为数据处理
3、帧长度指示帧内容字节个数,有效值为1~8,如:帧长度=2,则帧内容为两字节
4、校验和长度1字节,为帧长度与帧内容的累加和(不记溢出),如:帧长度=3,
帧内容={0x01,0x02,0xFF},则校验和 = 0x03 + 0x01 + 0x02 +0xFF = 0x05
5、需考虑接收过程中,出现的各种码流数据异常情况(如校验和错)
6、在处理过程中,如出现接收异常(如校验和错等),立即从下一字节重新开始搜索
一帧帧头
有效帧样例:
输入样例:
0x7e,0x7e,0x7e,0x02,0x00,0x01,0x03,0x7e,0x7e,0x7e,0x03,0x00,0x01,0x02,0x06…
输出样例:
0x00,0x01
0x00,0x01,0x02
2
题目框架中有1个参考用例,其它用例请执行编写。
在testcase目录下有3个文件:
in.txt:输入文件
out.txt:输出文件
check.txt:检查文件,用于检查out的正确性
*/
void string_process(char* msg, FILE* fp);
void getvalidframe()
{
/* 代码在这里实现 */
FILE* fpin = NULL;
FILE* fpout = NULL;
char* file_in = "../testcase/in.txt";
char* file_out = "../testcase/out.txt";
fpin = fopen(file_in, "r");
if(NULL == fpin)
{
printf("open file_in error\n");
return ;
}
fpout = fopen(file_out, "a+");
if(NULL == fpout)
{
printf("open file_out error\n");
fclose(fpin);
fpin = NULL;
return;
}
char* recv_buf = NULL;
recv_buf = (char*)malloc(BUF_LEN);
if(NULL == recv_buf)
{
printf("malloc receive buffer error\n");
fclose(fpin);
fpin = NULL;
fclose(fpout);
fpout = NULL;
}
memset(recv_buf, 0, BUF_LEN);
while(1)
{
fgets(recv_buf, BUF_LEN, fpin);
if(0 == strlen(recv_buf))
{
break;
}
string_process(recv_buf,fpout);
memset(recv_buf, 0, BUF_LEN);
}
free(recv_buf);
recv_buf = NULL;
fclose(fpin);
fpin = NULL;
fclose(fpout);
fpout = NULL;
return ;
}
//unsigned long cut_str_2_num(char* p_now, char* p_next, char* cut_flag)
char* cut_str_2_num(char* p, char* num, char* cut_flag)
{
char *p_next = NULL, *temp = NULL, *flag = NULL, *p_buf = NULL;
/* 如果当前帧错误的情况下可以从下面的字节处理数据则可以采用如下简化代码 */
//if(NULL != p)
//{
// p_next = strstr(p, cut_flag);
// if(NULL != p_next)
// {
// p_next++;
// }
// temp = strtok(p, cut_flag);
// *num = (char)strtol(temp, &flag, 16);
//}
/* 如果该帧校验错误,需要从该帧的长度字段的下一个字节开始搜索,则需要在此处开辟缓存,用于存放待处理的字符串,防止入参字符串被修改 */
if(NULL != p)
{
/* 为了避免入参字符串进入函数后本身被strtok()修改,内存中开辟缓存用于存储字符串 */
p_buf = (char*)malloc(DATA_MAX_LEN);
if(NULL == p_buf)
{
printf("malloc error\n");
return NULL;
}
memset(p_buf, 0, DATA_MAX_LEN);
strncpy(p_buf, p, DATA_MAX_LEN);
/* 对缓存中的字符串进行字段的查找和提取操作 */
p_next = strstr(p, cut_flag);
if(NULL != p_next)
{
p_next++;
}
temp = strtok(p_buf, cut_flag);
*num = (char)strtol(temp, &flag, 16);
/*释放分配的缓存*/
free(p_buf);
}
return p_next;
}
void string_process(char* msg, FILE* fp)
{
char *p = NULL, *dst = NULL, *buf = NULL, *p_data = NULL;
unsigned long i = 0, data_len = 0, head_len = 0, count = 0;
char start_data = 0, msg_data = 0, msg_be_check = 0, msg_check = 0;
buf = (char*)malloc(DATA_STRING_MAX_LEN);
if(NULL == buf)
{
printf("malloc error\n");
return;
}
memset(buf, 0, (DATA_STRING_MAX_LEN));
p = msg;
while((NULL != p) && ('\0' != *p))
{
p = cut_str_2_num(p, &start_data, CUT_STRING_FLAG);
/* 如果该帧校验错误,需要从该帧的长度字段的下一个字节开始搜索,则需要在此处打标签*/
//dst = p;
if(MSG_START_DATA == start_data)
{
head_len++;
continue;
}
if(HEAD_LEN < head_len)
{
data_len = start_data;
memset(buf, 0, DATA_STRING_MAX_LEN);
strncpy(buf, p, LEN(data_len + 1));
p_data = buf;
if( (data_len > 0) && (data_len < DATA_MAX_LEN) )
{
msg_be_check = data_len;
for(i = 0; i < data_len + 1; i++)
{
if(NULL != p_data)
{
if(i != data_len)
{
p = cut_str_2_num(p, &msg_data, CUT_STRING_FLAG);
msg_be_check += msg_data;
}
else
{
p = cut_str_2_num(p, &msg_check, CUT_STRING_FLAG);
if(msg_be_check == msg_check)
{
*(buf + LEN(data_len) - 1) = '\0';
fprintf(fp, "%s\n", buf);
count++;
head_len = 0;
}
}
}
else
{
break;
}
}
}
}
/* 如果该帧校验错误,需要从该帧的长度字段的下一个字节开始搜索,则需要在此处恢复标签*/
//p = dst;
head_len = 0;
}
fprintf(fp, "%d\n", count);
free(buf);
buf = NULL;
}