📄 redundant.c
字号:
/*
*********************************************************************************************************
* EPA冗余
*
*
* File : epa_redundant.c
* By : yshj
* date : 2006年02月22日
* Version : V0.01
*********************************************************************************************************
*/
#include "fs_module.h"
#include "epa_module.h"
#include "timer.h"
#include "tcpip.h"
#include <string.h>
#define SAFTY_REDUNDANT 1
///////上次收到设备冗余状态报文的时间
Time LastReceiveDAATime;
///////活动设备IP
uint32 R_IP;
///////是否已经进行了第一次同步,0:否,1:是
uint8 FirstMaintainOK = 0;
//////上一次冗余同步时间
uint32 Last_Maintain_time = 0;
/*$PAGE*/
/*
*********************************************************************************************************
* PTP_Subtract
*
* Description: 时间减法函数
*
* Arguments : t1 时间1
* t2 时间2
*
* Returns : t1和t2的偏差
*********************************************************************************************************
*/
Time PTP_Subtract(Time t1, Time t2)
{
Time t3;
if(t1.secs > t2.secs) {
if (t1.nasecs >= t2.nasecs) {
t3.secs = t1.secs - t2.secs;
t3.nasecs = t1.nasecs - t2.nasecs;
}
else {
t3.secs = t1.secs - t2.secs - 1;
t3.nasecs = 1000000000 - t2.nasecs + t1.nasecs;
}
}
else {
t3.secs = 0;
if (t1.nasecs > t2.nasecs) {
t3.nasecs = t1.nasecs - t2.nasecs;
}
else {
t3.nasecs = 0;
}
}
return(t3);
}
/*$PAGE*/
/*
*********************************************************************************************************
* FS_R_RemoteDeviceActiveAnnu
*
* Description: 冗余状态声明响应
*
* Returns : void
*********************************************************************************************************
*/
void FS_R_RemoteDeviceActiveAnnun(PSock psock)
{
Time ctime, timedif;
uint32 remoteip;
VisualString r_pdtag;
GetPDTag(r_pdtag);
Getime(&ctime);////读当前系统时间
///////////如果与本地pdtag象匹配
if(memcmp(r_pdtag, psock->payload, 32) == 0) {
n2h32(psock->payload + 32, &remoteip);
if(GetRedundancyState() == 0) {//////////设备是active状态
if(remoteip < gNetIf.localip) {////////本地ip大于远程ip
//////////本地设备转换备份状态
SetRedundancyState(1);
///////记录冗余设备ip
R_IP = remoteip;
////////记录本次收到此报文的时间
LastReceiveDAATime = ctime;
}
}
else {////////设备是备份状态
timedif = PTP_Subtract(ctime, LastReceiveDAATime);/////////记录此次收到报文与上次收到报文的时间偏差
if(((timedif.secs * 1000) + (timedif.nasecs / 1000000)) < 1200) {
LastReceiveDAATime = ctime;
R_IP = remoteip;
}
else {///////////偏差大于6个宏周期
//////设备转换为活动状态
SetRedundancyState(0);
FS_R_LocalDeviceChange();//////////发送设备切换事件
R_IP = gNetIf.localip;
}
}
}
FreeSock(psock);
}
/*$PAGE*/
/*
*********************************************************************************************************
* FS_R_RemoteMaintain
*
* Description: 设备冗余同步响应
*
*
* Returns : void
*********************************************************************************************************
*/
void FS_R_RemoteMaintain(PSock psock)
{
uint8 serviceid;
uint16 did;
uint16 desAppID;
#if SAFTY_REDUNDANT
FSLinkObject fslo;
FSManagementInfoHeaderObject fsmiho;
#else
EPALINKOBJECTHEADER loh;
LINKOBJECT lo,*tmplo;
#endif
n2h16(psock->payload , &desAppID);
serviceid = psock->srvid;////////读取请求类型
#if SAFTY_REDUNDANT
n2h16(psock->payload + 6, &did);
if(did==11)////////////对安全管理信息对象头操作
{
memcpy((uint8 *)&fsmiho,psock->payload + 8,sizeof(FSManagementInfoHeaderObject)); //读安全管理信息对象
FSMIB_Set(FSMIBHEADER_BASE_OBJECTID, (uint8*)&fsmiho);
FS_R_LocalMaintainPositive(desAppID,psock->srcip,psock->msgid);///////发送正响应
FreeSock(psock);
}
else////////////////对安全链接对象操作
{
FSMIB_Get(FSMIBHEADER_BASE_OBJECTID, (uint8*)&fsmiho);
//////////////是否在安全链接对象id范围
if((did>=fsmiho.FirstNumber_FSLinkObject)&&(did<=fsmiho.FirstNumber_FSLinkObject+fsmiho.Number_FSLinkObject))
{
//EMIB_Read(did,0,(Uint8 *)&tmpfslo,sizeof(FSLinkObject));
memcpy((uint8 *)&fslo,psock->payload + 8,sizeof(FSLinkObject));
//fslo.SendTimeOffset=tmpfslo.SendTimeOffset;
FSMIB_Set(did, (uint8*)&fslo);
FS_R_LocalMaintainPositive(desAppID,psock->srcip,psock->msgid);///////发送正响应
}
else
{
FS_R_LocalMaintainNegative(desAppID,psock->srcip,psock->msgid);///////////发负响应
}
}
#else
if(did==8)//////////对链接对象头操作
{
memcpy((Uint8 *)&,psock->payload[8],sizeof(EPALINKOBJECTHEADER)); //读安全管理信息对象
SetLinkObjHeader(&loh);
FS_R_LocalMaintainPositive(desAppID,psock->srcip,psock->msgid);///////发送正响应
}
else///////////对链接对象操作
{
memcpy((Uint8 *)&loh,(Uint8 *)GetFSLinkObjByIndex(8,0),sizeof(EPALINKOBJECTHEADER));////////读链接对象头
//////////////是否在安全链接对象id范围
if((did>=loh.FirstConfiguredLinkObjectID)&&(did<=loh.FirstConfiguredLinkObjectIDt+loh.NumberofLinkObject))
{
//EMIB_Read(did,0,(Uint8 *)&tmpfslo,sizeof(LINKOBJECT));
memcpy((Uint8 *)&lo,psock->payload[8],sizeof(LINKOBJECT));
//lo.SendTimeOffset=.SendTimeOffset;
SetLinkObjByObjID(did, &lo);//////////写入管理信息库
FS_R_LocalMaintainPositive(desAppID,psock->srcip,psock->msgid);///////发送正响应
}
else
{
FS_R_LocalMaintainNegative(desAppID,psock->srcip,psock->msgid);///////////发负响应
}
}
#endif
FreeSock(psock);
}
/*$PAGE*/
/*
*********************************************************************************************************
* FS_R_RemoteMaintainRequest
*
* Description: 设备冗余同步请求响应
*
*
* Returns : void
*********************************************************************************************************
*/
void FS_R_RemoteMaintainRequest(PSock psock) {
uint16 dstappid;
uint32 ip;
VisualString r_pdtag;
GetPDTag(r_pdtag);
if(GetRedundancyState() == 0) {
n2h32(psock->payload, &ip);
n2h16(psock->payload , &dstappid);
if((memcmp(psock->payload + 4, r_pdtag, 32)==0) && (gNetIf.localip == ip)) {
FS_R_LocalMaintainRequestPositive(dstappid, psock->srcip, psock->msgid);
}
else {
FS_R_LocalMaintainRequestNegative(dstappid, psock->srcip, psock->msgid);
}
}
FreeSock(psock);
}
/*$PAGE*/
/*
*********************************************************************************************************
* FS_R_RemoteDeviceChange
*
* Description: 设备冗余切换事件响应
*
*
* Returns : void
*********************************************************************************************************
*/
void FS_R_RemoteDeviceChange(PSock psock) {
#if SAFTY_REDUNDANT
uint16 Number_FSLinkObject;
uint16 FirstNumber_FSLinkObject;
uint16 Number_ConfiguredFSLinkObject;
FSLinkObject fslo;
#else
uint16 NumOfLinkObj;
uint16 FirNumOfLinkObj;
uint16 NumOfConfigLinkObj;
EPALINKOBJECTHEADER loh;
LINKOBJECT lo;
#endif
uint32 ActiveDeviceIP;///////current active device ip
uint32 FailedDeviceIP;//////failed devive ip
int i;
////////copy active device ip
n2h32(psock->payload + 32,&ActiveDeviceIP);
//////////copy failed device ip
n2h32(psock->payload + 36,&FailedDeviceIP);
#if SAFTY_REDUNDANT
////////read FSManagementInfoHeaderObject
Number_FSLinkObject = GetFSLinkObjNum();
FirstNumber_FSLinkObject = GetFSFirstLinkObj();
Number_ConfiguredFSLinkObject = GetFSCfgLinkObjNum();
#else
////////read FSManagementInfoHeaderObject
NumOfLinkObj = GetLinkObjNum();
FirNumOfLinkObj = GetFirstLinkObj();
NumOfConfigLinkObj = GetCfgLinkObj();
#endif
#if SAFTY_REDUNDANT
for(i=0;i<Number_ConfiguredFSLinkObject;i++) {
FSMIB_Get(FSLO_BASE_OBJECTID + i, (uint8*)&fslo);
if(ActiveDeviceIP == fslo.RemoteIPAddress) {
break;
}
else {
if(FailedDeviceIP == fslo.RemoteIPAddress) {
fslo.RemoteIPAddress = ActiveDeviceIP;
FSMIB_Set(FSLO_BASE_OBJECTID + i, (uint8*)&fslo);
}
else
break;
}
}
#else
for(i=0;i<NumOfConfigLinkObj;i++)/////query all configuredfslinkobject
{
/////////////read link object
lo=GetLinkObjByIndex(i);
if(ActiveDeviceIP==lo->RemoteIPAddress)//////if there is link relation between two devices
{
break;
}
else
{
if(FailedDeviceIP==lo->RemoteIPAddress)
{
lo->RemoteIPAddress=ActiveDeviceIP;
SetLinkObjbyindex(i, &lo);
}
else
break;
}
}
#endif
FreeSock(psock);
}
/*$PAGE*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -