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;i0)
    {
        for(i=0;i0)
    {
    for(i=0;i