📄 secapp.c
字号:
if(S101_2002CheckNVA(Port))
{
ComApp[i]->Data1.Flag|=HaveNVA;
}
}
if(ComApp[i]->Sec101Pad.Control&USEHISTORYDD)
{
if(ComApp[i]->FirstHisDDSaveCount==0xFF)
{
ComApp[i]->FirstHisDDSaveCount=0;
GetTime((void *)&absTime,ABSTIME);
ComApp[i]->HisDDSaveCount=(absTime.Minute % ComApp[i]->HisDDCycle) * 60;
}
else
ComApp[i]->HisDDSaveCount++;
if((ComApp[i]->HisDDSaveCount)>=(ComApp[i]->HisDDCycle*60))
{
ComApp[i]->HisDDSaveCount=0;
SaveKWHToBuf(Port);
}
}
}
//SecAppProc:链路接口函数
//输入参数:bufin:输入的缓冲区数据地址,从类型标识开始,
//输入参数:lengthin为应用层数据长度,
//输入参数:dlcommand为链路层到应用层间的功能码
//输出参数:bufout:输出的缓冲区数据地址,从类型标识开始,
//输出参数:lengthout为应用层数据长度,
//输出参数:appcommand为应用层到链路层的命令
void Sec101_2002AppProc(INT8U Port, INT8U *bufin,INT16U lengthin,INT16U dlcommand,
INT8U* bufout,INT16U* lengthout,INT16U*appcommand)
{
BOOL HaveJob=FALSE;
INT8U i,j;
struct DBInfo info;
i=Port-1;
ComApp[i]->RxMsg=bufin;
ComApp[i]->TxMsg=bufout;
ComApp[i]->RxTypeID=ComApp[i]->RxMsg[0];
ComApp[i]->RxVsq=ComApp[i]->RxMsg[1];
ComApp[i]->RxCot=ComApp[i]->RxMsg[2];
ComApp[i]->pRxData=ComApp[i]->RxMsg+ComApp[i]->AsduHeadLength;
ComApp[i]->RxPubAddr=0;
for(j=0;j<ComApp[i]->PubAddrSize;j++)
ComApp[i]->RxPubAddr+=(ComApp[i]->RxMsg[ComApp[i]->PubAddrLocation+j]<<(8*j));
ComApp[i]->RxInfoAddr=0;
for(j=0;j<2;j++)//InfoAddrSize如果为3,也只取前2个字节。
ComApp[i]->RxInfoAddr+=(ComApp[i]->RxMsg[ComApp[i]->InfoAddrLocation+j]<<(8*j));
ComApp[i]->pTxTypeID=ComApp[i]->TxMsg;
ComApp[i]->pTxVSQ=(ComApp[i]->TxMsg+1);
ComApp[i]->pTxInfoAddr=(ComApp[i]->TxMsg+ComApp[i]->InfoAddrLocation);
ComApp[i]->pTxData=(ComApp[i]->TxMsg+ComApp[i]->AsduHeadLength);
if(ComApp[i]->CotSize==2)//传送原因为2字节时,高位固定为0。
ComApp[i]->TxMsg[ComApp[i]->CotLocation+1]=0;
if(ComApp[i]->InfoAddrSize==3)//信息体地址为3个字节时,最高字节为0
ComApp[i]->TxMsg[ComApp[i]->InfoAddrLocation+2]=0;
if(ComApp[i]->DLCommand&DL_FCBOK)//非平衡模式
{
ComApp[i]->DLCommand&=(~DL_FCBOK);
//FCB处理,非平衡模式,COS、SOE、FA、指针累加。
if (ComApp[i]->LastDevIndex != 0xFFFF)
{
info.SuperID = ComDb[i]->DBCfgs->DevID;
info.DevID = ComApp[i]->LastDevIndex;
info.Type = ComApp[i]->LastDevType;
info.Num = ComApp[i]->LastDevNum;
if (DBClear(&info))
ComApp[i]->LastDevIndex = 0xFFFF;
if (DBCheck(&info))
{
if (ComApp[i]->LastDevType == SOEDATA)
ComApp[i]->Data1.Flag |= HaveSOE;
if (ComApp[i]->LastDevType == COSDATA)
ComApp[i]->Data1.Flag |= HaveCOS;
}
}
}
if(ComApp[i]->LengthIn==0)//命令处理
{
switch(ComApp[i]->DLCommand)
{
case DL_LINKDISABLE://链路无效
ComApp[i]->MasterStatus=NOUSE;
if ((ComApp[i]->LastFrame==BI)&&(ComApp[i]->BIFrame&BIENTFRAME))//上次发送数据为变位YX
{
ComApp[i]->Data1.Flag|=(HaveCOS);
ComApp[i]->Data1.COT=SPONT;
}
if ((ComApp[i]->LastFrame==BI)&&(ComApp[i]->BIFrame&BIETFRAME))//上次发送数据为soe
{
ComApp[i]->Data1.Flag|=(HaveSOE);
ComApp[i]->Data1.COT=SPONT;
}
ComApp[i]->LastFrame=Polling;
break;
case DL_RESETDL://链路收到对方复位链路命令,判断是否有初始化结束
HaveJob=TRUE;
if(ComApp[i]->InitFlag==0xFF)
{
ComApp[i]->AppCommand=APP_APPCON;
ComApp[i]->AppCommand|=APP_HAVEDATA1;
if(!ComApp[i]->BalanMode)
ComApp[i]->Data1.Flag|=HaveInitEnd;
}
else//从站未复位
{
if ((ComApp[i]->LastFrame==BI)&&(ComApp[i]->BIFrame&BIENTFRAME))//上次发送数据为变位YX
ComApp[i]->Data1.Flag|=(HaveCOS);
if ((ComApp[i]->LastFrame==BI)&&(ComApp[i]->BIFrame&BIETFRAME))//上次发送数据为soe
ComApp[i]->Data1.Flag|=(HaveSOE);
ComApp[i]->LastFrame=Polling;
ComApp[i]->AppCommand=APP_APPCON;
}
ComApp[i]->Data1.Flag&=(~HaveNVA);//避免变化遥测影响通讯进程
ComApp[i]->Data1.Flag&=0xf;//清掉除COS、SOE、INITEND、FA之外的一级数据,避免出现通讯问题。
ComApp[i]->Data2Flag=0;//清掉二级数据标志
ComApp[i]->LengthOut=0;
break;
case DL_LINKENABLE://链路有效,平衡模式
//MasterStatus=INUSE;
//if(InitFlag==0xFF)//平衡模式下,应该在每次链路过程后都发初始化结束,否则主站处理有问题
{//这么理解:平衡模式下每次链路的建立都是双方的,也意味着子站也进行了复位所以要发初始化结束
//否则,应该在报文中有区别,而平衡模式的报文没有这方面的显示。
HaveJob=TRUE;
ComApp[i]->InitFlag=0;
ComApp[i]->Data1.Flag&=(~HaveInitEnd);
EnCodeInitEnd(Port);
}
break;
case DL_SCAN1S://平衡模式,
//处理?
HaveJob=TRUE;
if(ComApp[i]->Data1.Flag)
S101ProcData1(Port);
else if(ComApp[i]->Data2Flag)
S101ProcData2(Port);
else
HaveJob=FALSE;
break;
case DL_CALLUDATA://取紧急数据,平衡模式
case DL_CALLDBMSG://取消息,平衡模式
case DL_CALLDATA1://取一级数据
HaveJob=TRUE;
S101ProcData1(Port);
break;
case DL_CALLDATA2://取二级数据
HaveJob=TRUE;
S101ProcData2(Port);
break;
case DL_APPCON://平衡模式收到对03的确认,COS,SOE,FA,指针累加。
HaveJob=TRUE;
if (ComApp[i]->LastDevIndex != 0xFFFF)
{
info.SuperID = ComDb[i]->DBCfgs->DevID;
info.DevID = ComApp[i]->LastDevIndex;
info.Type = ComApp[i]->LastDevType;
info.Num = ComApp[i]->LastDevNum;
if (DBClear(&info))
ComApp[i]->LastDevIndex = 0xFFFF;
if (DBCheck(&info))
{
if (ComApp[i]->LastDevType == SOEDATA)
ComApp[i]->Data1.Flag |= HaveSOE;
if (ComApp[i]->LastDevType == COSDATA)
ComApp[i]->Data1.Flag |= HaveCOS;
}
}
if(ComApp[i]->Data1.Flag)
S101ProcData1(Port);
else if(ComApp[i]->Data2Flag)
S101ProcData2(Port);
else
HaveJob=FALSE;
break;
default:
HaveJob=FALSE;
break;
}
}
else//数据处理
{
if((ComApp[i]->RxCot&COT_REASON)>47)//传送原因有错误,发链路确认,记录错误数据
{
ComApp[i]->HaveWrongData=TRUE;
ComApp[i]->WrongDataLength=ComApp[i]->LengthIn;
ComApp[i]->RxMsg[ComApp[i]->CotLocation]=UNKNOWNCOT;
ComApp[i]->RxMsg[ComApp[i]->CotLocation]|=0x40;
memcpy((void*)ComApp[i]->WrongData,(void*)ComApp[i]->RxMsg,ComApp[i]->LengthIn);
ComApp[i]->LengthOut=0;
ComApp[i]->AppCommand=APP_APPCON;
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(!S101GetActDevIndexByAddr(Port, ComApp[i]->RxPubAddr))//公共体地址错误,可能为0xFF
{
if((ComApp[i]->RxTypeID!=C_IC_NA)&&(ComApp[i]->RxTypeID!=C_CI_NA)&&(ComApp[i]->RxTypeID!=C_CS_NA))//总召唤或电度召唤可以为0xFF
{
ComApp[i]->HaveWrongData=TRUE;
ComApp[i]->WrongDataLength=ComApp[i]->LengthIn;
ComApp[i]->RxMsg[ComApp[i]->CotLocation]=UNKNOWNPUBADDR;
ComApp[i]->RxMsg[ComApp[i]->CotLocation]|=0x40;
memcpy((void*)ComApp[i]->WrongData,(void*)ComApp[i]->RxMsg,ComApp[i]->LengthIn);
ComApp[i]->LengthOut=0;
ComApp[i]->AppCommand=APP_APPCON;
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
}
HaveJob=TRUE;
switch(ComApp[i]->RxTypeID)
{
case C_SC_NA://单点遥控命令
case C_DC_NA://双点遥控命令
case C_RC_NA://升降命令
S101ProcControl(Port);
break;
case C_IC_NA://总召唤或分组召唤
S101ProcAllDataCall(Port);
break;
case C_CI_NA://电度总召唤或分组召唤
S101ProcDDCall(Port);
break;
case C_CD_NA://延时获得命令
S101ProcTimeDelay(Port);
break;
case C_CS_NA://对钟命令
ComApp[i]->MasterStatus=INUSE;
if (ComApp[i]->Sec101Pad.PBase.CmdControl&SETSECTIME)
{
if(ComApp[i]->DLCommand==DL_SENDNOCON)//广播对钟
{
S101ProcClock(Port, FALSE);
HaveJob=FALSE;
}
else
S101ProcClock(Port, TRUE);
}
else
HaveJob=FALSE;
break;
case C_RP_NA://复位进程命令
S101ProcReset(Port);
break;
case C_TS_NA://测试命令
S101ProcTest(Port);
break;
case F_SC_NA:
ProcFileCall(Port);
break;
case F_AF_NA:
SConfirm(Port);
break;
case C_PF_NA://保护定值设定
S101SetProtect(Port);
break;
case P_PF_NA://保护定值召唤
S101CallProtect(Port);
break;
default://类型标识有错误或不支持
HaveJob=TRUE;
ComApp[i]->HaveWrongData=TRUE;
ComApp[i]->WrongDataLength=ComApp[i]->LengthIn;
ComApp[i]->RxMsg[ComApp[i]->CotLocation]=UNKNOWNTYPEID;
ComApp[i]->RxMsg[ComApp[i]->CotLocation]|=0x40;
memcpy((void*)ComApp[i]->WrongData,(void*)ComApp[i]->RxMsg,ComApp[i]->LengthIn);
ComApp[i]->LengthOut=0;
ComApp[i]->AppCommand=APP_APPCON;
ComApp[i]->AppCommand|=APP_HAVEDATA1;
break;
}
}//end of else//数据处理
if((!HaveJob))
{
ComApp[i]->LengthOut=0;
ComApp[i]->AppCommand=APP_NOJOB;
}
}
//一级数据处理:优先级安排基本按照标准要求
void S101ProcData1(INT8U Port)
{
INT8U i;
i=Port-1;
if(ComApp[i]->HaveWrongData)
{
ComApp[i]->HaveWrongData=FALSE;
memcpy((void*)ComApp[i]->TxMsg,(void*)ComApp[i]->WrongData,ComApp[i]->WrongDataLength);
ComApp[i]->LengthOut=ComApp[i]->WrongDataLength;
ComApp[i]->AppCommand=APP_SENDDATA;
if(ComApp[i]->Data1.Flag!=0)//如果有后续一级数据,继续将ACD设置为1
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&HaveInitEnd)
{
ComApp[i]->Data1.Flag&=(~HaveInitEnd);
ComApp[i]->InitFlag=0;
EnCodeInitEnd(Port);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&HaveYK)
{
ComApp[i]->Data1.Flag&=(~HaveYK);
if(ComApp[i]->YKStatus==YKTERM)//遥控结束
{
ComApp[i]->YKStatus=NOTUSE;
EditYKTerm(Port);
}
else
ProcTaskMsg(Port);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&HaveCOS)
{
EnCodeBIENT(Port);
//ComApp[i]->Data1.Flag &= (~HaveCOS);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&HaveSOE)
{
S101EnCodeSOE(Port);
//ComApp[i]->Data1.Flag &= (~HaveSOE);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&ProtectCon)//保护定值镜像确认
{
ComApp[i]->Data1.Flag&=(~ProtectCon);
SendProtectCon(Port);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&CallClock)
{
ComApp[i]->Data1.Flag&=(~CallClock);
S101EnCodeClock(Port);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&CallTimeDelay)
{
ComApp[i]->Data1.Flag&=(~CallTimeDelay);
EnCodeTimeDelay(Port);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&CallTest)//测试过程
{
ComApp[i]->Data1.Flag&=(~CallTest);
EnCodeTest(Port);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&CallReset)//复位进程
{
ComApp[i]->Data1.Flag&=(~CallReset);
EnCodeReset(Port);
if(ComApp[i]->Data1.Flag!=0)//
ComApp[i]->AppCommand|=APP_HAVEDATA1;
return;
}
if(ComApp[i]->Data1.Flag&CallAllData)//站召唤
{
if(ComApp[i]->EditAllDataCon==0xff)
{
ComApp[i]->EditAllDataCon=0;
S101EnCodeAllDataConf(Port);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -