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); }