📄 secdlink.c
字号:
i = Port - 1;
p=(ComLink[i]->RxdBuf+ComLink[i]->RxdHead);
if(p[2+ComLink[i]->LinkAddrSize]!=CheckSum(Port, p))
return(FALSE);
if(p[3+ComLink[i]->LinkAddrSize]!=ENDCODE)
return(FALSE);
if(ComLink[i]->LinkAddrSize==1)
addr=p[2];
else
addr=(p[2]+(p[3]<<8));
if(addr!=ComLink[i]->SourceNo)
return(FALSE);
return(TRUE);
}
//判断68帧头。
BOOL S101_2002ExeDLFun68(INT8U Port)
{
INT8U i;
INT8U *p;
i = Port - 1;
p=(ComLink[i]->RxdBuf+ComLink[i]->RxdHead);
if((p[0]!=p[3])||(p[1]!=p[2]))
return(FALSE);
if(ComLink[i]->LinkAddrSize==1)
{
if((p[5]!=ComLink[i]->SourceNo)&&(p[5]!=0xff))
return(FALSE);
}
else
{
if(((p[5]+(p[6]<<8))!=ComLink[i]->SourceNo)&&((p[5]+(p[6]<<8))!=0xffff))
return(FALSE);
}
return(TRUE);
}
void S101_2002ExeDLFunCode10(INT8U Port)
{
INT8U Stop=0;
INT8U Control, i;
i = Port-1;
Control=ComLink[i]->RxdBuf[1];
ComLink[i]->IdleTimeCount=0;
ComLink[i]->TimeOutTick_Pri=0;//链路有数据就可以不重发??
if(Control&P101_PRM)//子站作为从动站接收主站的命令
{
if ((!(Control&P101_FCV)) || ((Control&P101_FCB) !=((ComLink[i]->RlaConCode) & 0x20)))
{
if (Control&P101_FCV)//FCV有效,FCB翻转。
{
ComLink[i]->RlaConCode=ComLink[i]->RxdBuf[1];
ComLink[i]->FCBNoTurnNum=MAXRETRYNUM;
}
switch(Control&P101_FUNCODE)
{
case DLREQSTATUS://召唤链路状态
S101_2002RecReqDLStatus(Port);
while(((ComLink[i]->RxdTail-ComLink[i]->RxdHead)>=ComLink[i]->FixFrmLength)&&(Stop==0))//收到召唤链路状态命令时,清掉后续相同命令。
{//可以避免答非所问的过程,尽快建立链路。
if(memcmp(ComLink[i]->RxdBuf,ComLink[i]->RxdBuf+ComLink[i]->RxdHead,ComLink[i]->FixFrmLength)==0)
ComLink[i]->RxdHead+=ComLink[i]->FixFrmLength;
else
Stop=1;
}
break;
case DLRESETRDL://复位链路
S101_2002RecResetDL(Port);
break;
case DLREQDATA1://10
//应用层调用
ComApp[i]->DLCommand=DL_CALLDATA1;
if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
ComApp[i]->DLCommand|=DL_FCBOK;
ComApp[i]->LengthIn=0;
Sec101_2002AppProc(Port, (ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize),ComApp[i]->LengthIn,ComApp[i]->DLCommand,
(ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize),(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
break;
case DLREQDATA2://11
//应用层调用
if(ComApp[i]->InitFlag==0xFF)
return;
ComApp[i]->DLCommand=DL_CALLDATA2;
if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
ComApp[i]->DLCommand|=DL_FCBOK;
ComApp[i]->LengthIn=0;
Sec101_2002AppProc(Port, ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
break;
default:
ComLink[i]->ComStatus.OtherError++;
break;
}
return;
}
else //FCB未翻转
{
//ComStatus.OtherError++;
//if (FCBNoTurnNum)
{
ComLink[i]->FCBNoTurnNum--;
//if (FCBNoTurnNum)
SendSec101_2002DataToMISI(Port);
}
}
}
else//Prm=0 平衡模式子站作为启动站接收到主站的命令。
{
ComLink[i]->TimeOutTick_Pri=0;
switch(Control&P101_FUNCODE)
{
case DLCON: //确认
RecConf10(Port);
break;
case DLSTATUSOK://应答链路
RecDLSta(Port);
break;
default:
CallDLStatus(Port);
ComLink[i]->ComStatus.OtherError++;
break;
}
}
}
void S101_2002ExeDLFunCode68(INT8U Port)
{
INT8U i;
INT8U Control;
i = Port - 1;
Control=ComLink[i]->RxdBuf[4];
ComLink[i]->IdleTimeCount=0;
ComLink[i]->TimeOutTick_Pri=0;//链路有数据就可以不重发??
if(Control&P101_PRM)//子站作为从动站接收主站链路报文。
{
if ((!(Control&P101_FCV)) || ((Control&P101_FCB) !=((ComLink[i]->RlaConCode) & 0x20)))
{
if (Control&P101_FCV)//FCV有效而且FCB变位
{
ComLink[i]->RlaConCode=ComLink[i]->RxdBuf[4]; //保存最新的功能码,这里只用到FCB
ComLink[i]->FCBNoTurnNum=MAXRETRYNUM;//设置重发次数,指下次收到主站报文FCB未翻转时重发缓冲区内的报文。
}
switch(Control&P101_FUNCODE)
{
case DLRESETUSE://1,启动站复位从动站用户过程
//应用层调用
ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
ComApp[i]->DLCommand=DL_RESETUSE;
if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
ComApp[i]->DLCommand|=DL_FCBOK;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
break;
case DLTESTDL://2,测试链路
ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
ComApp[i]->DLCommand=DL_TESTDLINK;
if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
ComApp[i]->DLCommand|=DL_FCBOK;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
break;
case DLSENDCON://3,发送/确认 命令
ComApp[i]->DLCommand=DL_SENDCON;//
ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
ComApp[i]->DLCommand|=DL_FCBOK;
Sec101_2002AppProc(Port, ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
break;
case DLSENDNOCON://4,发送/无回答 命令
ComApp[i]->DLCommand=DL_SENDNOCON;//
ComApp[i]->LengthIn=ComLink[i]->RxdBuf[1]-1-ComLink[i]->LinkAddrSize;
if((!ComLink[i]->BalanMode)&&(Control&P101_FCV))
ComApp[i]->DLCommand|=DL_FCBOK;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
break;
}
}
else //FCB 未翻转 //change by wyj
{
//ComStatus.OtherError++;
//if (FCBNoTurnNum)
{
ComLink[i]->FCBNoTurnNum--;
// if (FCBNoTurnNum) //重发缓冲区的报文(上次的)
SendSec101_2002DataToMISI(Port);
}
return;
}
}
else //Prm=0;子站作为启动站接收主站链路报文
{
}
}
INT8U CheckSum(INT8U Port, INT8U *RxdBuf)
{
INT8U sum, i, j;
sum = 0;
i = Port - 1;
if(*(RxdBuf)==STARTCODE10)
{
for(j=0;j<ComLink[i]->LinkAddrSize+1;j++)
sum+=*(RxdBuf+1+j);
}
else
{
INT8U *p;
BYTE i;
p=RxdBuf+4;
i=*(RxdBuf+1);
while(i--)
sum += *p++ & 0xFF;
}
return(sum);
}
INT32U TimeDelay(INT8U Port, INT16U j)
{
INT8U i;
i = Port - 1;
ComLink[i]->TimeOutTickCopy=j*10/ComLink[i]->Baudrate+ComLink[i]->TimeOutValue/100+1;
return(ComLink[i]->TimeOutTickCopy);
}
void RecDLSta(INT8U Port)
{
INT8U i;
i=Port-1;
switch(ComLink[i]->DLPriStatus)
{
case PRIWAITSTATUS:
case PRIWAITRSCON://链路过程未完成,为解决报文错位情况。即发送复位链路收到链路状态的情况,这时继续复位链路。
EditFra10(Port, DLRESETRDL);
S101_2002SendDataToMISI(Port);
ComLink[i]->TlaConCode&=0xDF; //change by wyj
ComLink[i]->DLPriStatus=PRIWAITRSCON;
ComLink[i]->TimeOutTick_Pri=TimeDelay(Port, 2* ComLink[i]->FixFrmLength);
ComLink[i]->RetryCount=MAXRETRYNUM;
break;
default://出现状态错位情况,怎么处理
ComLink[i]->DLPriStatus=PRIENABLE;
}
}
void RecConf10(INT8U Port)
{
INT8U i;
i=Port-1;
if (ComLink[i]->DLPriStatus==PRIWAITRSCON)//非平衡模式不可能到这里
{
if (ComLink[i]->BalanMode)//平衡模式
{
ComLink[i]->DLPriStatus=PRIENABLE;
ComLink[i]->RemoteDLOK=0xff;//远方链路(主站)已经被复位
if(ComLink[i]->LocalDLOK==0xff)//如果这之前,本地链路已经被复位(主站复位过子站)则进行应用层调用。
{
if(ComLink[i]->StartDL==0xFF)
{
ComLink[i]->StartDL=0;//链路过程结束
ComApp[i]->DLCommand=DL_LINKENABLE;
ComApp[i]->LengthIn=0;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);//发送初始化结束帧
}
else//防止运行过程中召唤链路却未设置StartDL标志,这个判断好象没有必要。
{
ComLink[i]->StartDL=0xFF;
ComLink[i]->LocalDLOK=0;
}
}
}
}
else if (ComLink[i]->DLPriStatus==PRISENDCON)//平衡模式
{
ComLink[i]->DLPriStatus=PRIENABLE;
//应用层调用
ComApp[i]->DLCommand=DL_APPCON;
ComApp[i]->LengthIn=0;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);
}
else
ComLink[i]->DLPriStatus=PRIENABLE;
}
void S101_2002RecResetDL(INT8U Port)
{
INT8U i;
i=Port-1;
ComLink[i]->RlaConCode&=0xDF; //清FCB //change by wyj
ComLink[i]->FCBNoTurnNum=MAXRETRYNUM;
//调应用层服务,检测是否发送初始化结束
ComApp[i]->DLCommand=DL_RESETDL;
ComApp[i]->LengthIn=0;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
if((ComApp[i]->AppCommand&APP_HAVEDATA1)==APP_HAVEDATA1)
ComLink[i]->FlagData1=TRUE;
else
ComLink[i]->FlagData1=FALSE;
EditSec101_2002Fra10(Port, DLCON); //编辑应答帧。
S101_2002SendDataToMISI(Port);
if(ComLink[i]->BalanMode)
{
ComLink[i]->LocalDLOK=0xff;//子站链路已经被主站复位
if(ComLink[i]->RemoteDLOK==0xff)//这之前主站链路已经被复位
{
if(ComLink[i]->StartDL==0xff)//子站重启动初始化后的链路过程
{
ComLink[i]->StartDL=0;
//应用层调用
ComApp[i]->DLCommand=DL_LINKENABLE;
ComApp[i]->LengthIn=0;
Sec101_2002AppProc(Port,ComLink[i]->RxdBuf+5+ComLink[i]->LinkAddrSize,ComApp[i]->LengthIn,ComApp[i]->DLCommand,
ComLink[i]->TxdBuf+5+ComLink[i]->LinkAddrSize,(INT16U *)&ComApp[i]->LengthOut,(INT16U *)&ComApp[i]->AppCommand);
S101_2002DLSendProc(Port);//发送初始化结束帧
}
else//子站正常运行时的链路过程(说明主站运行过程中复位了)
CallDLStatus(Port);
}
else
CallDLStatus(Port);
}
}
void S101_2002RecReqDLStatus(INT8U Port)
{
INT8U i;
i=Port-1;
EditSec101_2002Fra10(Port, DLSTATUSOK);
S101_2002SendDataToMISI(Port);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -