www.pudn.com > comm11111.rar > comm.h


/***************************** 
comm.h:终端与支付密码器通讯协议 
编制人:李健 
编制日期:2001/8/28 
修改日期:2001/12/13 /2001/12/17 
上层调用:comm.c 
*****************************/ 
 
#include  
#include  
#include  
#include  
#include  
#include  
 
char MsgLog[50]="/usr/zfmm/comm/comm.log";  /*程序信息*/ 
FILE *fp; 
 
#define TTY		0	/*	0-串口,1-辅口		*/ 
 
#define True   		0  
#define False   	-1	 
 
#define PACKLEN		520	/*	帧最大长度		*/ 
 
#define STX		0x02	/*	帧头			*/ 
#define ETX		0x03	/*	帧尾			*/ 
 
/*	TAG		*/ 
#define READ_SN		0x31	/*	读机具号和芯片序列号	*/	 
#define GEN_KEYPAIR	0x32	/*	产生密钥对		*/ 
#define LOAD_AK		0x33	/*	下载AK支		*/ 
#define DEL_ACCU	0x34	/*	删除帐号		*/ 
#define ADD_SIG		0x35	/*	增发签名		*/ 
#define UNLOCK		0x36	/*	解锁			*/ 
#define DIST_MACH	0x37	/*	发行机具		*/ 
#define CONN_CALU	0x38	/*	联机计算		*/ 
 
#define INIT_IC		0x50	/*	初始化IC卡		*/ 
#define VER_ICMM	0x51	/*	验证IC卡密码		*/ 
#define CHG_ICMM	0x52	/*	修改IC卡密码		*/ 
#define COMP_CHIPNO	0x53	/*	比较算法芯片号		*/ 
#define ICZFMM		0x54	/*	生成支付密码对照表	*/ 
 
char Send_Buff[PACKLEN];	/*	Send Buffer		*/ 
char Rece_Buff[PACKLEN];	/*	Rece Buffer		*/ 
 
char AUXLEAD[25];		/*	终端辅口头		*/ 
char AUXEND[25];		/*	终端辅口尾		*/ 
 
static int    Port_no; 
static struct termio bak_termio,curr_termio; 
 
#if TTY==0 
/*	此处程序供串口使用		*/ 
 
/*	初始化串口	*/ 
int Port_Init(char *tty_name) 
{ 
 
	Port_no=open(tty_name,O_RDWR); 
	if (Port_no<0) return (False); 
	if (ioctl(Port_no,TCGETA,&bak_termio)<0)  return (False); 
 
	curr_termio=bak_termio; 
	curr_termio.c_iflag&=~IXON; 
	curr_termio.c_iflag&=~IXOFF; 
	curr_termio.c_iflag&=~INLCR; 
	curr_termio.c_iflag&=~ICRNL; 
 
	curr_termio.c_oflag&=~OPOST; 
	curr_termio.c_oflag&=~OLCUC; 
	curr_termio.c_oflag&=~ONLCR; 
	curr_termio.c_oflag&=~OCRNL; 
 
	curr_termio.c_cflag&=~CBAUD;    
	curr_termio.c_cflag|=B9600; 
	curr_termio.c_cflag&=~CSIZE; 
	curr_termio.c_cflag|=CS8; 
 
	curr_termio.c_lflag&=~ECHO; 
	curr_termio.c_lflag&=~ICANON; 
	curr_termio.c_lflag&=~ISIG; 
 
	curr_termio.c_cc[VMIN]=0; 
	curr_termio.c_cc[VTIME]=5; 
	curr_termio.c_cc[VQUIT]=0xff; 
 
 
	ioctl(Port_no,TCFLSH,2); 
	if (ioctl(Port_no,TCSETA,&curr_termio)<0) return (False); 
 
	return (True); 
} 
 
/*	恢复串口	*/ 
int Port_Res() 
{ 
	if(Port_no<0)	return (False); 
	if(ioctl(Port_no,TCSETAW,&bak_termio)<0)  return (False); 
	close(Port_no); 
	return (True); 
} 
 
/*	发送字符串	*/ 
int Out_Port(char *temp) 
{ 
	int i,temp_len=0; 
	char buf[2]; 
 
	temp_len=strlen(temp); 
 
	ioctl(Port_no,TCSBRK,1); 
 
	for(i=0;i>4)&0x0f;			/*	SEQ	*/ 
	if (Temp[1]>=10) 
		Temp[1]=Temp[1]-10+0x41; 
	else 
		Temp[1]=Temp[1]+0x30; 
	Temp[2]=(xh)&0x0f;	 
	if (Temp[2]>=10) 
		Temp[2]=Temp[2]-10+0x41; 
	else 
		Temp[2]=Temp[2]+0x30; 
	xh++; 
 
	Temp[3]=(TAG>>4)&0x0f;			/*	TAG	*/ 
	if (Temp[3]>=10) 
		Temp[3]=Temp[3]-10+0x41; 
	else 
		Temp[3]=Temp[3]+0x30; 
	Temp[4]=(TAG)&0x0f;	 
	if (Temp[4]>=10) 
		Temp[4]=Temp[4]-10+0x41; 
	else 
		Temp[4]=Temp[4]+0x30; 
 
	len=strlen(buffer)/2;			/*	LEN	*/ 
	Temp[5]=(len>>12)&0x0f;	 
	if (Temp[5]>=10) 
		Temp[5]=Temp[5]-10+0x41; 
	else 
		Temp[5]=Temp[5]+0x30; 
	Temp[6]=(len>>8)&0x0f;	 
	if (Temp[6]>=10) 
		Temp[6]=Temp[6]-10+0x41; 
	else 
		Temp[6]=Temp[6]+0x30; 
	Temp[7]=(len>>4)&0x0f;	 
	if (Temp[7]>=10) 
		Temp[7]=Temp[7]-10+0x41; 
	else 
		Temp[7]=Temp[7]+0x30; 
	Temp[8]=(len)&0x0f;	 
	if (Temp[8]>=10) 
		Temp[8]=Temp[8]-10+0x41; 
	else 
		Temp[8]=Temp[8]+0x30; 
	 
	strcat(Temp,buffer);			/*	DATA	*/ 
 
	 
	for (i=0;i<4+len;i++)			/*	LRC	*/	 
	{ 
		if ((Temp[i*2+1]>='A')&&(Temp[i*2+1]<='F')) 
			s1=(Temp[i*2+1]-'A'+10); 
		else if((Temp[i*2+1]>='0')&&(Temp[i*2+1]<='9')) 
			s1=(Temp[i*2+1]-'0'); 
		if ((Temp[i*2+2]>='A')&&(Temp[i*2+2]<='F')) 
			s2=(Temp[i*2+2]-'A'+10); 
		else if((Temp[i*2+2]>='0')&&(Temp[i*2+2]<='9')) 
			s2=(Temp[i*2+2]-'0'); 
 
		x=(s1<<4)|(s2); 
		q=(q+x)%65536;	/*	2001/12/13修改	*/ 
		s=(s+q)%65536; 
	} 
	Temp[8+len*2+1]=(s>>12)&0x0f;	 
	if (Temp[8+len*2+1]>=10) 
		Temp[8+len*2+1]=Temp[8+len*2+1]-10+0x41; 
	else 
		Temp[8+len*2+1]=Temp[8+len*2+1]+0x30; 
 
	Temp[8+len*2+2]=(s>>8)&0x0f;	 
	if (Temp[8+len*2+2]>=10) 
		Temp[8+len*2+2]=Temp[8+len*2+2]-10+0x41; 
	else 
		Temp[8+len*2+2]=Temp[8+len*2+2]+0x30; 
 
	Temp[8+len*2+3]=(s>>4)&0x0f;	 
	if (Temp[8+len*2+3]>=10) 
		Temp[8+len*2+3]=Temp[8+len*2+3]-10+0x41; 
	else 
		Temp[8+len*2+3]=Temp[8+len*2+3]+0x30; 
 
	Temp[8+len*2+4]=(s)&0x0f;	 
	if (Temp[8+len*2+4]>=10) 
		Temp[8+len*2+4]=Temp[8+len*2+4]-10+0x41; 
	else 
		Temp[8+len*2+4]=Temp[8+len*2+4]+0x30; 
 
	Temp[8+len*2+5]=ETX;			/*	ETC	*/ 
 
	strcpy(Send_Buff,Temp); 
	return (True); 
} 
 
/*		校验接收字符串			*/ 
int Check_Rece(char TAG,char *Temp) 
{ 
	int i,len=0,q=0,s=0,x=0,s1=0,s2=0; 
	int LRC; 
 
	if ((Temp[0]!=STX)||(Temp[strlen(Temp)-1]!=ETX)) 
		return (False); 
 
	/*	验证TAG		*/ 
	if ((Temp[3]>='A')&&(Temp[3]<='F')) 
		s1=(Temp[3]-'A'+10); 
	else if((Temp[3]>='0')&&(Temp[3]<='9')) 
		s1=(Temp[3]-'0'); 
	if ((Temp[4]>='A')&&(Temp[4]<='F')) 
		s2=(Temp[4]-'A'+10); 
	else if((Temp[4]>='0')&&(Temp[4]<='9')) 
		s2=(Temp[4]-'0'); 
 
	x=(s1<<4)|(s2); 
 
	if(TAG!=x)	return (False);	 
 
	 
	if ((Temp[5]>='A')&&(Temp[5]<='F'))	/*	LEN	*/ 
		len=(Temp[5]-'A'+10)*4096; 
	else if((Temp[5]>='0')&&(Temp[5]<='9')) 
		len=(Temp[5]-'0')*4096; 
 
	if ((Temp[6]>='A')&&(Temp[6]<='F')) 
		len=len+(Temp[6]-'A'+10)*256; 
	else if((Temp[6]>='0')&&(Temp[6]<='9')) 
		len=len+(Temp[6]-'0')*256; 
 
	if ((Temp[7]>='A')&&(Temp[7]<='F')) 
		len=len+(Temp[7]-'A'+10)*16; 
	else if((Temp[7]>='0')&&(Temp[7]<='9')) 
		len=len+(Temp[7]-'0')*16; 
 
	if ((Temp[8]>='A')&&(Temp[8]<='F')) 
		len=len+(Temp[8]-'A'+10); 
	else if((Temp[8]>='0')&&(Temp[8]<='9')) 
		len=len+(Temp[8]-'0'); 
 
 
	for (i=0;i<4+len;i++)			/*	LRC	*/	 
	{ 
		if ((Temp[i*2+1]>='A')&&(Temp[i*2+1]<='F')) 
			s1=(Temp[i*2+1]-'A'+10); 
		else if((Temp[i*2+1]>='0')&&(Temp[i*2+1]<='9')) 
			s1=(Temp[i*2+1]-'0'); 
		if ((Temp[i*2+2]>='A')&&(Temp[i*2+2]<='F')) 
			s2=(Temp[i*2+2]-'A'+10); 
		else if((Temp[i*2+2]>='0')&&(Temp[i*2+2]<='9')) 
			s2=(Temp[i*2+2]-'0'); 
 
		x=(s1<<4)|(s2); 
		q=(q+x)%65536;	/*	2001/12/13修改	*/ 
		s=(s+q)%65536; 
	} 
 
	/*	接收到的LRC	*/	 
	if ((Temp[strlen(Temp)-5]>='A')&&(Temp[strlen(Temp)-5]<='F')) 
		LRC=(Temp[strlen(Temp)-5]-'A'+10)*4096; 
	else if((Temp[strlen(Temp)-5]>='0')&&(Temp[strlen(Temp)-5]<='9')) 
		LRC=(Temp[strlen(Temp)-5]-'0')*4096; 
	if ((Temp[strlen(Temp)-4]>='A')&&(Temp[strlen(Temp)-4]<='F')) 
		LRC=LRC+(Temp[strlen(Temp)-4]-'A'+10)*256; 
	else if((Temp[strlen(Temp)-4]>='0')&&(Temp[strlen(Temp)-4]<='9')) 
		LRC=LRC+(Temp[strlen(Temp)-4]-'0')*256; 
	if ((Temp[strlen(Temp)-3]>='A')&&(Temp[strlen(Temp)-3]<='F')) 
		LRC=LRC+(Temp[strlen(Temp)-3]-'A'+10)*16; 
	else if((Temp[strlen(Temp)-3]>='0')&&(Temp[strlen(Temp)-3]<='9')) 
		LRC=LRC+(Temp[strlen(Temp)-3]-'0')*16; 
	if ((Temp[strlen(Temp)-2]>='A')&&(Temp[strlen(Temp)-2]<='F')) 
		LRC=LRC+(Temp[strlen(Temp)-2]-'A'+10); 
	else if((Temp[strlen(Temp)-2]>='0')&&(Temp[strlen(Temp)-2]<='9')) 
		LRC=LRC+(Temp[strlen(Temp)-2]-'0'); 
 
 
	if(LRC!=s)	return (False);	 
 
	return (True); 
} 
 
/*		接收程序		*/ 
int  Rece_codestr(char TAG,char *buffer) 
{ 
	char temp; 
	int result=0,resend=0,i=0,status=0; 
	int SUCCESS; 
	int count; 
 
	while(1) 
	{ 
		switch(status) 
		{ 
			case 0:		/*		STX		*/ 
				/*	接收回应包时间加长	*/ 
 
				for(count=0;count<20;count++) 
					{ 
						result=In_Port(&temp); 
						if (result==True) break; 
					} 
 
				#ifdef DEBUG 
 				ShowMsg("STX=%d\n",result); 
				#endif 
	 
				if (result==True) 
				{ 
					if (temp==STX)	 
						{ 
							buffer[i++]=temp; 
							status=1; 
						} 
				} 
				else 
					status=99; 
				break; 
			case 1:		/*		帧其余部分	*/ 
				result=In_Port(&temp); 
				#ifdef DEBUG 
				if (result==True) 
				{ 
					fp=fopen(MsgLog,"a+"); 
  					fputc(temp,fp); 
  					fclose(fp); 
				} 
				else 
				{ 
					fp=fopen(MsgLog,"a+"); 
  					fputc('T',fp); 
  					fclose(fp); 
				} 
				#endif 
				if (result==True) 
				{ 
					buffer[i++]=temp; 
					if (temp==ETX)	 
						{ 
						#ifdef DEBUG 
 						ShowMsg("ETX=%d\n",result); 
						#endif 
							status=2; 
						} 
				} 
				else 
					status=99; 
				break; 
			case 2:		/*		校验		*/ 
				result=Check_Rece(TAG,buffer); 
				#ifdef DEBUG 
 				ShowMsg("Check_Rece=%d\n",result); 
				#endif 
				if (result==True) 
				{ 
					SUCCESS=True; 
					status=100; 
				} 
				else 
					status=99; 
				break; 
			case 99:	/*		重发		*/ 
				if (++resend<3) 
				{ 
					Out_Port(Send_Buff); 
					#ifdef DEBUG 
 					ShowMsg("comm 重发第%d次 Send_Buff=%s\n",resend,Send_Buff); 
					#endif 
					status=0; 
				} 
				else 
				{ 
					SUCCESS=False; 
					status=100; 
				} 
				break; 
			case 100: 
				return (SUCCESS); 
		}/*	switch	*/ 
	}/*	while	*/ 
} 
 
int OPEN_PORT() 
{ 
	int result; 
	char tty_name[25]; 
	char COM; 
 
	#ifdef DEBUG 
 	ShowId("comm"); 
	#endif 
 
	#if TTY==0 
		// 2001/12/17 
  		GetEnv("/usr/zfmm/zfmm.cfg","[银河]COM",&COM);	 
		#ifdef DEBUG 
 		ShowMsg("comm open COM=%c\n",COM); 
		#endif 
		switch(COM) 
		{ 
			case '1': 
				strcpy(tty_name,"/dev/tty1a"); 
				break; 
			case '2': 
				strcpy(tty_name,"/dev/tty2a"); 
				break; 
			default: 
				strcpy(tty_name,"/dev/tty1a"); 
				break; 
		} 
			 
	#endif 
	#if TTY==1 
		strcpy(tty_name,ttyname(1)); 
	#endif 
 
	result=Port_Init(tty_name); 
	#ifdef DEBUG 
 	ShowMsg("comm OPEN_PORT=%d\n",result); 
	#endif 
	if (result==False) 
	{ 
	      	Port_Res();	 
		return (False); 
	} 
	return (True); 
} 
 
 
int PORT_RW(char TAG,char *buffer,char *rece_buffer) 
{ 
	char temp[PACKLEN]; 
	int result=0,i=0,s1=0,s2=0,x=0; 
 
	/*	打开端口	*/ 
	result=OPEN_PORT(); 
	if (result==False) 
		return (False); 
 
	/*	打包		*/ 
	Make_Item(TAG,buffer); 
 
	/*	发送字符串	*/ 
	Out_Port(Send_Buff); 
	#ifdef DEBUG 
 	ShowMsg("comm Out_Port Send_Buff=%s\n",Send_Buff); 
	#endif 
 
 
	memset(temp,'\0',PACKLEN);  
	memset(Rece_Buff,'\0',PACKLEN); 
 
	/*	接收字符串	*/ 
	result=Rece_codestr(TAG,temp); 
	#ifdef DEBUG 
 	ShowMsg("comm 接收结果=%d\n",result); 
	#endif 
	if (result==True) 
	{ 
		switch(TAG) 
		{ 
			case READ_SN: 
					i=18;	break; 
			case GEN_KEYPAIR: 
					i=192;	break; 
			case ADD_SIG: 
					i=16;	break; 
			case LOAD_AK: 
			case DEL_ACCU: 
			case UNLOCK: 
			case DIST_MACH: 
			case INIT_IC: 
			case VER_ICMM: 
			case CHG_ICMM: 
			case COMP_CHIPNO: 
					i=0;	break; 
			case CONN_CALU: 
					i=20;	break; 
			case ICZFMM: 
					i=500;	break; 
			default:	 
					break; 
		} 
 
		result=i; 
 
		for (i=0;i='A')&&(temp[9]<='F')) 
		s1=(temp[9]-'A'+10); 
	else if((temp[9]>='0')&&(temp[9]<='9')) 
		s1=(temp[9]-'0'); 
	if ((temp[10]>='A')&&(temp[10]<='F')) 
		s2=(temp[10]-'A'+10); 
	else if((temp[10]>='0')&&(temp[10]<='9')) 
		s2=(temp[10]-'0'); 
 
	x=s1*10+s2; 
 
	/*	关闭端口	*/ 
	Port_Res(); 
 
	#ifdef DEBUG 
 	ShowMsg("comm 返回码=%d\n",x); 
	#endif 
 
	return (x); 
}