📄 comm.c
字号:
#include "Comm.h"
/***********************************************************************
*
* 函数名:RxdHost()
* 说 明:接收主机的应答,然后对应答信息进行分析
* 入口值:无
* 返回值:=0xff, 通信超时,断开所有通道
* 2:从从机转发数据或者表示收到初始化命令
* 1:执行了正确的命令
* 0:没有收到有效的命令
* 日 期:2006-09-29
*
***********************************************************************/
unsigned char RxdHost(void)
{
unsigned char bTemp;
bTemp=AnalyseRxHost(); // 1:收到有效数据;0没有 //
if(bTemp==1) // 收到有效数据 //
{
bTemp=PerformCmd(); // 0:三次重发超时;1、通讯超时;2、初始化应答 //
if(bTemp==0) // 三次重发超时即退出 //
{
return 0xff;
}
else
{
return bTemp; /*应答正确返回上一级*/
}
}
return 0;
}
/***********************************************************************
*
* 函数名:byte AnalyseRxHost(void)
* 说 明:分析从主机串口收到的数据,分析数据是否为有效数据,然后将有
* 效的命令数据交下层处理。
* 入口值:无
* 返回值:1 收到主机的有效数据包
* 0 没有有效数据包
* 日 期:2006-09-29
*
***********************************************************************/
unsigned char AnalyseRxHost(void)
{
unsigned char i;
unsigned char aTemp[30];
unsigned char bTemp;
unsigned char bOffSet=0;
unsigned char bLength=0;
if(iHostRxRd>=iHostRxWr) // 若没有收到有效的数据就返回0 //
return 0;
mem_set(aTemp,0,30);
for (i=0; i<30; i++)
{
bTemp=aHostRxBuf[iHostRxRd];
if(bTemp=='N') //0x4e、在接收缓冲区中搜寻开头字符N //
break;
iHostRxRd++;
if(iHostRxRd>=iHostRxWr)
return 0;
}
if(i==30)
{
return 0;
}
// 取出所有已经接收到的数据串,进行分析,以便送应用层或进行转发 //
bOffSet=(unsigned char)(iHostRxWr-iHostRxRd);
// 数据最小长度不符,退出 //
if(bOffSet<3)
return 0;
// 收到的数据存储到aTemp中 //
mem_cpy(aTemp,&aHostRxBuf[iHostRxRd],bOffSet);
while(1)
{
if((aTemp[1]==P_CONNECTICS)||(aTemp[1]==P_DTMFNUM)||(aTemp[1]==P_TXDFSK)) // S->T的变长命令仅此三条,ccw //
bTemp=aTemp[2]+2; // 数据长度+校验位+数据长度位 //
else
bTemp=SearchCmd(aTemp[1]); // 分析命令长度 //
if(bTemp==0) // 命令非法 //
{
bLength=2;
break;
}
bLength=bTemp+2; // 该命令的总长度,加命令和命令校验两位 //
if(bOffSet>=bLength)
{
bTemp=CalcCheckSum(aTemp+1,bLength-2); // 命令中除去0x4e、最后的校验和 //
//if(bTemp==aTemp[bLength-1]) // 命令正确,进行处理 //
{
iHostRxRd+=bLength; // 对齐指针收发 //
bCmdAns.bLineCmd=aTemp[1];
bCmdAns.bLength=bLength-3; // 数据体的长度 除掉0x4e,命令,命令校验和 //
mem_cpy(bCmdAns.aBuf,&aTemp[2],bCmdAns.bLength);
return 1;
}
/*else
{
bLength=1;
break;
}*/
}
bLength=0;
break;
}
iHostRxRd+=bLength; // 对齐指针收发 //
return 0;
}
/***********************************************************************
*
* 函数名:PerformCmd(void)
* 说 明:对接收到的命令进行处理,执行命令或对于应答的命令进行处理
* 入口值:无
* 返回值:无
* 日 期:2006-09-29
*
***********************************************************************/
unsigned char PerformCmd(void)
{
unsigned char i=0;
LINE_DATA *p;
p=&aLineData;
switch(bCmdAns.bLineCmd)
{
case P_OK: //0x52 肯定应答
// 若收到的确认命令是期望的,就结束本次通信 //
if ((p->bExpAns==bCmdAns.bLineCmd)&&(p->bLastCmd==bCmdAns.aBuf[0]))
{
//p->fTxEn=1; // 打开发送使能 收到期望的命令,允许发送//
//p->fTimeOut=0;
p->bLastCmd=P_OVER;
}
// 否则继续接收该期望的命令应答 //
break;
case P_NAK: //0x53 否定应答
break;
case P_INITANS:
//0x51初始化应答
if (p->bExpAns==bCmdAns.bLineCmd)
{
//cbTimeOut=bCmdAns.aBuf[0]; // 通信超时 //
//if(cbTimeOut==0)
// cbTimeOut=10;
cbKeepTime=bCmdAns.aBuf[1]; // 链路保持时间 //
//cbDTMFTime=bCmdAns.aBuf[2]; // DTMF拨号时长 //
// if ((cbDTMFTime<3)||(cbDTMFTime>25))
// cbDTMFTime=10;
cbDialDelay=bCmdAns.aBuf[3]; // 摘机延时发平台接入码时间 //
return 2;
}
break;
case P_CONNECTICS: //0x60 // 接入平台 S->T,变长 //
p->bDailWord=0x10; // 设置代拨状态字为开始状态
p->bLineCmd=bCmdAns.bLineCmd;
RespondHost(P_OK,bCmdAns.bLineCmd);
break;
case P_DTMFNUM: // 0x61 DTMF号码 S->T,变长 //
p->bDailWord=0x11; // 设置代拨状态字为开始状态 //
p->bLineCmd=bCmdAns.bLineCmd;
RespondHost(P_OK,bCmdAns.bLineCmd);
break;
case P_TXDFSK: // FSK发送 S->T,变长 //
p->bLineCmd=bCmdAns.bLineCmd;
RespondHost(P_OK,bCmdAns.bLineCmd);
Delay1MS(5);
/*FSK发送*/
ModemTxFSK();
RxFskInit(); // 发送完成后准备再次接收数据 //
ModemRxFSK(); //中断函数内接收
break;
case P_ONHOOK: //0x64 挂机 //
p->bLineCmd=bCmdAns.bLineCmd;
RespondHost(P_OK,bCmdAns.bLineCmd);
break;
default:
return 3;
}
return 1;
}
/***********************************************************************
*
* 函数名:SearchCmd
* 说 明:查找命令是否有效及其长度
* 入口值:要查找的命令
* 返回值:该命令数据的长度,=0表示该命令无效
* 日 期:
*
***********************************************************************/
unsigned char SearchCmd(unsigned char bCmd)
{
unsigned char i=0;
unsigned char bTemp;
unsigned char aCmdTab[][2]={
0x50,17,
0x51,17,
0x52,2,
0x53,2,
0x54,2,
0x55,1,
0x56,1,
0x57,1,
0x58,1,
0x64,1,
0xff,0
};
while(1)
{
bTemp=aCmdTab[i][0];
if(bTemp==bCmd)
return aCmdTab[i][1];
else if(bTemp>0xa0)
return 0;
i++;
}
}
/***********************************************************************
*
* 函数名:RespondHost
* 说 明:应答主机发送的命令
* 入口值:主机发送命令、应答
* 返回值:无
* 日 期:2006.10.11
*
***********************************************************************/
void RespondHost(unsigned char bCmd,unsigned char bAnsCmd)
{
unsigned char aBuf[4];
aBuf[0]='N';
aBuf[1]=bCmd;
aBuf[2]=bAnsCmd;
aBuf[3]=CalcCheckSum(aBuf+1,2);
mem_cpy(aHostTxBuf,aBuf,4);
TX_addss=0;
cTX_num=4;
UCSR0B |= 0x28;// 发送数据 // // 首先发送对接收命令的应答 //
iHostRxWr=0;
iHostRxRd=0;
}
/***********************************************************************
*
* 函数名:SendHostCmd
* 说 明:向售卡机发送命令函数
* 入口值: 发送命令
* 返回值:无
* 日 期:2006.10.11
*
***********************************************************************/
void SendHostCmd(unsigned char bCmd)
{
unsigned char aBuf[4];
LINE_DATA *p;
p=&aLineData;
aBuf[0]='N';
aBuf[1]=bCmd;
aBuf[2]=CalcCheckSum(aBuf+1,2);
mem_cpy(aHostTxBuf,aBuf,3);
TX_addss=0;
cTX_num=3;
UCSR0B |= 0x28;
p->bExpAns=P_OK;
p->bLastCmd=bCmd;
iHostRxWr=0;
iHostRxRd=0;
/*需增加超时重传处理*/
}
/***********************************************************************
*
* 函数名:FskSendCmd
* 说 明:向售卡机发送平台下发FSK数据
* 入口值: 发送命令
* 返回值:无
* 日 期:2006.10.11
*
***********************************************************************/
void FskSendCmd(unsigned char bCmd)
{
unsigned char bLength;
aHostTxBuf[0]='N';
aHostTxBuf[1]=bCmd;
bLength = aHostTxBuf[4]+3;
aHostTxBuf[2]=bLength;
aHostTxBuf[3+bLength]=CalcCheckSum(aHostTxBuf+1,bLength+1);
TX_addss=0;
cTX_num=bLength+4;
UCSR0B |= 0x28;
iHostRxWr=0;
iHostRxRd=0;
/*需增加超时重传处理*/
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -