www.pudn.com > FumaBuildParse.rar > FumaBuildParse.c
#include#include #include #include #include #include #include #include #include #include #include ///////////////////////////////////////////////////////////// //|Function:unsigned int cal_crc //| //|16位CRC:按位计算,速度最慢,占用空间最少,数据流是高位先行 //| //|输入:整数以及初始crc值 //| //|输出:按位计算的16位crc值,余式采用0x1021 ////////////////////////////////////////////////////////////// unsigned int cal_crc(unsigned int command, unsigned int crc){ unsigned int i; crc=crc^(command<<8); for(i=0; i<=7; i++) { if((crc&0x8000)!=0) crc=(crc<<1)^0x1021; else crc=(crc<<1); } //fprintf(stderr,"CRC%d\n",crc); return crc; } /////////////////////////////////////////////////////////////////////// //| Function: FUMAChangeback() //| 富马转义逆变换,将输入的数组按照富马协议恢复,也就是 //| //| 输入:源字符串,融合起始位置,融合长度,目标数据数组,数据起始位置 //| //| 返回:int ,正常返回1; 解包错误返回-1; //| //| Example: //| unsigned char str[]={0x23,0x7D,0x5D,0x7D,0x5E} //| int data[5]; //| BinaryFuse(str,0,5,data,0); //data={0x03,0x23,0x7D,0x7E, ...} ///////////////////////////////////////////////////////////////////////// int FUMAChangeback(unsigned char* Str,int SStart, int Len, int* Data,int DStart) { int i,j; int dec; // length to shorten dec=0; //if(DStart==0) Data[0]=Len; //else // Data[0]=Len; if(Len<1) return -1 ; //no 容错功能,默认对方的包是正确的. for(i=0,j=0;i<=Len;i++,j++){ if(Str[i]==0x7D) { if(Str[i+1]==0x5E) { Data[1+j]=0x7E; i++; dec++; } else if(Str[i+1]==0x5D) { Data[1+j]=0x7D; i++; dec++; } else return -1; } else Data[1+j]=Str[i]; } Data[0]=Data[0]-dec; return 1; } ///////////////////////////////////////////////////////////////////////// //| Function: int FUMAParse() BinaryFuse(Str,0,strlen,Data,0); //|从源字符串中获取命令包、对命令包进行CRC校验、解析出命令单元的数据保存到目的字符串 Data[0]为转换后数组有效的长度 //| //|输入: 源数据组,源数据长度, 目的数据数组 //| //|返回:int 解析成功则返回1 , //| 如果失败返回负数, -1表示:起始结束标记出错 -2表示:富马转义逆变化出错 -3表示: //| } ///////////////////////////////////////////////////////////////////////// int FUMAParse(unsigned char *Str,int strlen, int *Data){ int i; unsigned int RcvCrc, CalCrc=0; //搜索消息字符串的起始标志位0x7E if(Str[0]!=0x7E){ Str=NULL; Data=NULL; // fprintf(stderr,"Finding Message String StartFlag Error!\n"); return -1; } Str=Str+1; //搜索消息字符串的结束标志位0x7E if(Str[strlen-2]!=0x7E){ Str=NULL; Data=NULL; // fprintf(stderr,"Finding Message String EndFlag Error!\n"); return -1; } //对命令单元和检验单元字符串进行二进制合并 strlen=strlen-2; if( !FUMAChangeback(Str,0,strlen,Data,0) ) { return -2; } //for(i=0;i<23;i++) // fprintf(stderr,"Data Message %x\n",Data[i]); //CRC 校验 RcvCrc=Data[(Data[0])]*256+Data[(Data[0])-1]; //fprintf(stderr,"ReceiveCrc %x\n",RcvCrc); for(i=1;i<=Data[0]-2;i++) CalCrc=cal_crc(Data[i],CalCrc); CalCrc=CalCrc&0xffff; //fprintf(stderr,"CalCrc %x\n",CalCrc); if(RcvCrc!=CalCrc){ Str=NULL; fprintf(stderr,"Check Message String CRC Error!\n"); return 0x04; } Data[0]-=2; //命令体长度检验 /* if(Data[12]!=Data[0]-12){ Str=NULL; Data=NULL; fprintf(stderr,"Check Command Body Length Error!"); return 0xA0; } */ //消息命令体处理完毕 Str=NULL; return 1; } ///////////////////////////////////////////////////////////////// //| Function: FUMAChange() //|转义 //|将源整数数组进行如下处理,从数组的第二位起逐个比较数据,看是否有数据为7E 7D 如果有, //| 将相应的数据扩展为7E ---> 7D 5E ; 7D ----> 7D 5D; //| //|输入:源数据数组,起始位置,拆分的长度,目的字符串 //| //|返回:int 有效Str长度 //| Example: //| int data[2]={0x2,0x7E,0x34}; //| char str[]; //| FUMAChange(data,1,2,Str); //str={0x7D,0x5E,0x34} //| /////////////////////////////////////////////////////////// //完成,没有测试 int FUMAChange(int* Data,int DStart, int Len, unsigned char* Str){ int i; int add; //新增加的数据数目 add=0; if(DStart<=0) DStart=1; if(Len<=0) Len=1; if(Len>Data[0]) Len=Data[0]; for(i=0;i 0) { for(i=0;i 0) { for(i=0;i