You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

4961 lines
120 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

//***************************************************************
//* buban104.cpp *
//* aaawen 2005.09.14 *
//***************************************************************
//_DEBUG_MSG_,_OS_WINDOWS_DEBUG_
#ifndef _WIN32
#include <sys/types.h>
#include <unistd.h>
#include "commport.h"
// #include "baohulib/serialport.h"
#else
#include "commport.h"
#include "udpcomm.h"
#include "display.h"
#endif
#include <math.h>
#include <time.h>
#include <stdlib.h>
#include "buban101.h"
#include "buban104.h"
#include "scadaprotect.h"
#include "MySQLAdo.h"
extern SIO_PARAM_DEF SioParam[];
extern FUNCTION_CALL *FunCallPtr;
extern void *pvconf_handle;
extern void *pvportconf_handle;
extern void *pvdataconf_handle;
extern char pvDataFileName[256];
extern char IniFilePath[256];
const char *gpStrBuban104Cmd[BUBAN104_TIMER_CMD_NUM] =
{
"总召唤电度数据",
"召唤初始化数据",
"帧序应答"
};
/*!
组织结构:链路(间隔)+装置
*/
const char *gpStrBuban104ConfigInfo[] =
{
" ; ***** 部颁104规约参数定义 *****",
" ",
" ; 所有命令召唤周期均以秒为单位,可以为xx.xxx秒。",
" ; 注意:104规约只支持网络通讯,作为主站时是客户方式,作为子站时是服务器方式。",
" ; 网络端口 = 2404。",
" 站地址 = 1 ; 缺省= 0 。",
" 总召唤电度数据 = 120",
" 召唤初始化数据 = 300",
" 帧序应答 = 20",
" ; 在对方超时时间之内发送帧序应答帧。",
" 超时时间 = 3.0",
//" 转发返校超时时间 = 10.0",
" 转发是否要求应答 = 0",
" 超时发送测试帧 = 0",
" ; =0超时不发送测试报文而是帧序应答报文(缺省值)=1发送测试报文",
" 遥控方式=0",
" ; =0双点遥控(缺省)=1单点遥控。",
" ",
" 遥测信息体起始地址=0x701",
" 遥信信息体起始地址=0x001",
" 遥脉信息体起始地址=0xC01",
" 遥控信息体起始地址=0xB01",
" ;以上信息体地址可以配置,缺省值为97版部颁104所规定值",
" ",
" 帧序应答尺寸=2",
" ",
" 版本号 = 1",
" ;=0 是buban104(缺省值); =1 是IEC_870_5_104规约",
" 发布时间=2000",
" ;=1997; =2000(缺省值)",
" 转发遥测类型标识 = 21",
" ",
"*******部颁104规约结束*******",
"", // 结束标志(中间不能含有该空字符串)
};
//********************************************************************
//* 读取配置函数 *
//*参数int commid : 端口号 *
//********************************************************************
void Buban104ReadConfig(int commid)
{
int i;
char szSection[128], szbuf[128];
char szPortConfig[256];
pBUBAN104PORTPARAM pPortParam;
#ifdef OS_LINUX
strcpy(szPortConfig, "portconfig.ini");
#else
//GetCurrentDirectory(sizeof(szDir), szDir);
sprintf(szPortConfig, "%s/portconfig.ini", IniFilePath);
#endif
SioParam[commid].ExtInfo = HEAP_MALLOC(sizeof(BUBAN104PORTPARAM));
if(!SioParam[commid].ExtInfo)
{
sprintf(szbuf, "WARN(%04d): commid_%02d ExtInfo=malloc(%d) failed.\n",
_getpid(), commid, sizeof(BUBAN104PORTPARAM));
DebugPrint(szbuf);
return;
}
memset(SioParam[commid].ExtInfo, 0, sizeof(BUBAN104PORTPARAM));
pPortParam = (pBUBAN104PORTPARAM)SioParam[commid].ExtInfo;
/* 只有在SioParam[commid].m_psBaoHu非空时才会运行到这里 */
pPortParam->m_psBaoHu = SioParam[commid].m_psBaoHu;
sprintf(szSection, "Port%d", commid+1);
if(GetPrivateProString(szSection, "站地址", "0", szbuf, 120, szPortConfig) > 0)
{
pPortParam->wLinkAddr = atoi(szbuf);
}
// 轮询指令配置
for(i=0; i<BUBAN104_TIMER_CMD_NUM; i++)
{
GetPrivateProString(szSection, (char *)gpStrBuban104Cmd[i], "0", szbuf, 120, szPortConfig);
pPortParam->CmdTime[i].CmdTimerConst = (long)(atof(szbuf)*1000/TIMER_CNT);
if(pPortParam->CmdTime[i].CmdTimerConst > 5)
{
pPortParam->CmdTime[i].CmdTimerCnt = pPortParam->CmdTime[i].CmdTimerConst - 5;
}
}
if(GetPrivateProString(szSection, "超时时间", "20.0", szbuf, 120, szPortConfig) > 0)
{
pPortParam->lTimeOutConst = (long)(atof(szbuf)*1000/TIMER_CNT);
}
pPortParam->ProvAckOrNot = GetPrivateProInt(szSection, "转发是否要求应答", 0, szPortConfig);
if(pPortParam->ProvAckOrNot > 0)
{
pPortParam->ProvAckOrNot = 1;
}
else
{
pPortParam->ProvAckOrNot = 0;
}
// wen 2005.10.28 修改超时时是否发送测试报文
pPortParam->lTimeOutSendTest = GetPrivateProInt(szSection, "超时发送测试帧", 0, szPortConfig);
if(GetPrivateProString(szSection, "遥控方式", "0", szbuf, 120, szPortConfig) > 0)
{
pPortParam->YkMode = atoi(szbuf);
}
pPortParam->iAiBaseAddr = GetPrivateProInt(szSection, "遥测信息体起始地址", INFO_AI_BASEADDR, szPortConfig);
pPortParam->iDiBaseAddr = GetPrivateProInt(szSection, "遥信信息体起始地址", INFO_DI_BASEADDR, szPortConfig);
pPortParam->iPiBaseAddr = GetPrivateProInt(szSection, "遥脉信息体起始地址", INFO_PI_BASEADDR, szPortConfig);
pPortParam->iYkBaseAddr = GetPrivateProInt(szSection, "遥控信息体起始地址", INFO_YKYT_BASEADDR, szPortConfig);
pPortParam->m_iFrameSize = GetPrivateProInt(szSection, "帧序应答尺寸", MAX_FRAMEMATCHING_SIZE, szPortConfig);
pPortParam->RtuVersion = GetPrivateProInt(szSection, "版本号", 0, szPortConfig);
pPortParam->m_iPublishYear = GetPrivateProInt(szSection, "发布时间", 2000, szPortConfig);
pPortParam->m_bProvAiType = GetPrivateProInt(szSection, "转发遥测类型标识", 13, szPortConfig);
InitBuban104CommandBuffer(commid);
}
//
//
//********************************************************************
//* 读取端口数据函数 *
//*参数int commid : 端口号 *
//* u_char buf : 数据源缓冲区指针 *
//* int len : 数据源长度 *
//********************************************************************
void Buban104RecvData(int commid, u_char *buf, int len)// 规约读数据处理
{
int i;
pBUBAN104PORTPARAM pPortParam;
#ifdef _DEBUG_MSG_
char szbuf[256];
#endif
if(!IsExtInfoPtr(commid))
return;
pPortParam = (pBUBAN104PORTPARAM)SioParam[commid].ExtInfo;
printf("recvbuf: ");
for (i = 0; i < len; i++)
printf("%02X ", buf[i]);
printf("\n");
for(i=0; i<len; i++)
{
switch(pPortParam->m_psBaoHu->m_iRevStatus)
{
case 0:// 0x10 / 0x68
pPortParam->m_iRecvLen = 0;
if(buf[i] == 0x68)
{
pPortParam->m_psBaoHu->m_iRevStatus++;
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
}
else
{
pPortParam->m_psBaoHu->m_iRevStatus = 100;
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
}
break;
case 1:// length
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
pPortParam->m_psBaoHu->m_iNeedRevLength = buf[i];
if(pPortParam->m_psBaoHu->m_iNeedRevLength <= 0)
{
pPortParam->m_psBaoHu->m_iRevStatus = 100;
}
else
{
pPortParam->m_psBaoHu->m_iRevStatus++;
}
break;
case 2:// 正确接收数据
pPortParam->m_psBaoHu->m_iNeedRevLength--;
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
if(pPortParam->m_psBaoHu->m_iNeedRevLength > 0)
break;
Buban104ProcessData(commid, pPortParam, TRUE);
pPortParam->m_psBaoHu->m_iRevStatus = 0;
pPortParam->m_psBaoHu->RevCmdFlag = 1;
#ifdef _WIN32
if((GetCurPort() == commid) && IsRealDataDisp())
{
WatchDataPutDispBuf(commid, SDS_SIO_RECV_DATA,
(BYTE *)pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen);
}
#endif
//pPortParam->LinkOkCnt = 0;
break;
case 100:// 错误接收数据
default:
if(buf[i] == 0x68)
{
#ifdef _WIN32
// wen 2004.11.22 增加显示
if((GetCurPort() == commid) && IsRealDataDisp())
{
WatchDataPutDispBuf(commid, SDS_SIO_RECV_DATA,
(BYTE *)pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen);
}
#endif
Buban104ProcessData(commid, pPortParam, FALSE);
SioParam[commid].ErrMsgNum += pPortParam->m_iRecvLen;
pPortParam->m_psBaoHu->m_iRevStatus = 1;
pPortParam->m_iRecvLen = 1;
pPortParam->m_au8RecvBuf[0] = buf[i];
}
else
{
pPortParam->m_au8RecvBuf[pPortParam->m_iRecvLen++] = buf[i];
if(pPortParam->m_iRecvLen > 200)
{
#ifdef _WIN32
// wen 2004.11.22 增加显示
if((GetCurPort() == commid) && IsRealDataDisp())
{
WatchDataPutDispBuf(commid, SDS_SIO_RECV_DATA,
(BYTE *)pPortParam->m_au8RecvBuf, pPortParam->m_iRecvLen);
}
#endif
Buban104ProcessData(commid, pPortParam, FALSE);
SioParam[commid].ErrMsgNum += pPortParam->m_iRecvLen;
pPortParam->m_iRecvLen = 0;
}
}
break;
}
}
#ifdef _DEBUG_MSG_
sprintf(szbuf, "wen: commid = %d, send=%d, recv=%d, error=%d, lost=%d\n", commid,
SioParam[commid].SendCharNum, SioParam[commid].RecvCharNum,
SioParam[commid].ErrMsgNum, SioParam[commid].LostSyncCnt);
DebugPrint(szbuf);
#endif
}
//********************************************************************
//* 定时器处理函数 *
//*参数int commid : 端口号 *
//********************************************************************
void Buban104Timer(int commid)
{
BUBAN104PORTPARAM *pPortParam;
if(IsExtInfoPtr(commid) == FALSE)
{
return;
}
pPortParam = (pBUBAN104PORTPARAM)SioParam[commid].ExtInfo;
if(pPortParam->LinkOk)
{
// 超时计数
pPortParam->lTimeOutCnt++;
}
// 如果为转发端口,则不进行轮询指令的生成。
if(PROTOCOL_SLAVE != pPortParam->m_psBaoHu->PortType)
{
Buban104FindNextCmd(commid);
}
else
{
Buban104FindNextProvCmd(commid);
}
Buban104SendCmdFormPollCmdBuf(commid);
}
//********************************************************************
//* 遥控遥调数据处理函数 *
//*参数int commid : 端口号 *
//* u_char buf : 数据源缓冲区指针 *
//* int len : 数据源长度 *
//********************************************************************
void Buban104YkYtProcess(int commid, u_char *buf, int len) // 遥控遥调处理
{
int portno, ykytpnt;
int iDirect;
// buf[0] --- 端口号(=commid)
// buf[1]
// buf[2]
// buf[3]
// buf[4] --- 控点号
// buf[5]
// buf[6]
// buf[7]
// buf[8] --- 操作类型(遥控:1=选择,2=执行,3=取消,7=直控;
// 遥调:4=选择,5=执行,6=取消,8=急停)
// buf[9] --- 控制状态(1=分到合2=合到分)
// (最高位为1时为返校命令, 1=控合, 2=控分, 3=失败)
// 在转发遥控数据点中,只保留了要转发的控点号,实际的端口号应该是该转发点的端口
// 该转发点并没有指定虚拟的转发控点,则控点和转发点的点号一致。
if(IsExtInfoPtr(commid) == FALSE)
{
return;
}
iDirect = buf[9] & 0x80;
portno = buf[0]+buf[1]*256+buf[2]*65536+buf[3]*16777216;
ykytpnt = buf[4]+buf[5]*256+buf[6]*65536+buf[7]*16777216;
// 返校信息(反馈信号)
if(iDirect)
{
Buban104ProvMakeYkYtCommand(commid, buf, len);
}
else
{
MakeBuBan104YkYtCommand(commid, buf, len);
}
}
//********************************************************************
//* 系统下发对时函数 *
//*参数int commid : 端口号 *
//********************************************************************
void Buban104SendSystemTime(int commid) // 系统对时
{
BUBAN104PORTPARAM *pPortParam;
if(IsExtInfoPtr(commid) == FALSE)
{
return;
}
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(2 != pPortParam->m_psBaoHu->CheckTime)
{
return;
}
if(pPortParam->Initdata)
{
if(PROTOCOL_SLAVE != pPortParam->m_psBaoHu->PortType)
{
MakeBuban104Command(commid, RTU_TIME);
}
}
}
//********************************************************************
//* 系统退出时规约处理函数 *
//*参数int commid : 端口号 *
//********************************************************************
void Buban104Exit(int commid)
{
// 释放所有分配的内存
}
// 该函数用来驱动由转发端口下发到实际装置的保护命令
void Buban104BaoHuCmdProcess(int commid, RTUMSG *rtumsg, BOOL bUpData)
{
}
int Buban104GetBaohuDataBase(int commid, int iProvAddr, GROUPDEF **ppBaoHuDB)
{
return 0;
}
/////////////////////////通用函数接口结束///////////////////////////////
/////////////////////////buban104公共函数接口///////////////////////////
//指令缓冲区初始化
void InitBuban104CommandBuffer(int commid)
{
pBUBAN104PORTPARAM pPortParam;
pPortParam = (pBUBAN104PORTPARAM)SioParam[commid].ExtInfo;
pPortParam->LinkOk = false;
// wen 2005.09.15 将该标识修改为true后
// 在主站下发总召命令和总召电度后会将其标识置为false
// 而子站端不会受此标识的影响标识为false不下发数据。
//pPortParam->Initdata = false;
pPortParam->Initdata = true;
pPortParam->bAckRight = true;
pPortParam->bStopComm = false;
pPortParam->bCloseSocket = false;
pPortParam->CurCmdIdx = 0;
pPortParam->wRecvSequence = 0;
pPortParam->wSendSequence = 0;
pPortParam->wAckSequence = 0;
pPortParam->lTimeOutCnt = 0;
ClearAllCmdFromPollCmdBuf(commid);
}
//关闭socket通讯
void Buban104CloseSocket(u_32 commid)
{
#ifdef OS_LINUX
CloseNetPort(commid);
#endif
}
/////////////////////////buban104公共函数接口结束///////////////////////
void Buban104ProvMakeYkYtCommand(int commid, u_char *buf, int len)
{
// buf[0] --- 端口号(=commid)
// buf[1]
// buf[2]
// buf[3]
// buf[4] --- 控点号
// buf[5]
// buf[6]
// buf[7]
// buf[8] --- 操作类型(遥控:1=选择,2=执行,3=取消,7=直控;
// 遥调:4=选择,5=执行,6=取消,8=急停)
// buf[9] --- 控制状态(1=分到合2=合到分)
// (最高位为1时为返校命令, 1=控合, 2=控分, 3=失败)
// 在转发遥控数据点中,只保留了要转发的控点号,实际的端口号应该是该转发点的端口
// 该转发点并没有指定虚拟的转发控点,则控点和转发点的点号一致。
int ykpoint, iLen;
char commandbuf[MAX_POLLCMD_BUF_LEN];
BOOL bHaveOrder = FALSE;
BUBAN104PORTPARAM *pPortParam;
if(IsExtInfoPtr(commid) == FALSE)
{
return;
}
if((buf[9] & 0x80) == 0)
{
return;
}
pPortParam = (pBUBAN104PORTPARAM)SioParam[commid].ExtInfo;
memset( (char*)commandbuf, 0x00, MAX_POLLCMD_BUF_LEN );
ykpoint = buf[4]+buf[5]*256+buf[6]*65536+buf[7]*16777216;
ykpoint += pPortParam->iYkBaseAddr - 1;
commandbuf[0] = 0x68;
commandbuf[1] = 14;
switch(pPortParam->YkMode)
{
case CONTROL_SINGAL: // 单点控制
commandbuf[6] = 45;
break;
case CONTROL_DOUBLE: // 双点控制
case CONTROL_DIRECT: // 直接控制
commandbuf[6] = 46;//(rtumsg->MsgData[3] == 1) ? 46 : 47;
break;
}
commandbuf[7] = 1;
//commandbuf[8] 传送原因
iLen = 9;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = LOBYTE(LOWORD(ykpoint));
commandbuf[iLen++] = HIBYTE(LOWORD(ykpoint));
}
else
{
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = LOBYTE(LOWORD(ykpoint));
commandbuf[iLen++] = HIBYTE(LOWORD(ykpoint));
commandbuf[iLen++] = LOBYTE(HIWORD(ykpoint));
}
switch(buf[8])
{
case 1:
case 4: // 选择
bHaveOrder = TRUE;
commandbuf[8] = 7;
commandbuf[iLen] = 0xfc;
break;
case 2:
case 5: // 执行
bHaveOrder = TRUE;
commandbuf[8] = 7;
commandbuf[iLen] = 0x7c;
break;
case 3:
case 6:
bHaveOrder = TRUE;
commandbuf[8] = 9;
commandbuf[iLen] = 0xfc;
break;
}
if( bHaveOrder )
{
if((buf[9] & 0x03) == 0x03)
{
commandbuf[8] |= 0x40;
}
else
{
// 控分还是控合
if((buf[9] & 0x03) == 0x01)// 控合
{
if(CONTROL_SINGAL == pPortParam->YkMode)
{
commandbuf[iLen++] |= 1;
}
else
{
commandbuf[iLen++] |= 2;
}
}
else// 控分
{
if(CONTROL_SINGAL != pPortParam->YkMode)
{
commandbuf[iLen++] |= 1;
}
}
}
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, (char *)commandbuf, iLen);
}
if(ShmGetDispYkYtFlag())
{
printf("TIP_(%04d): commid =%d ykytpnt=%d, op=%d checked.\n",
_getpid(), commid, ykpoint, (buf[9] & 0x7F));
}
}
//===========================以下为指令生成函数=======================
/*!
\brief 寻找并生成下一条命令
\param u_32 portno : RTU端口号
\param i_32 iBuIdx : 间隔装置索引
*/
void MakeBuban104Command(u_32 commid, u_char cmdidx)
{
int i, iLen;
DAY_TIME sCurTime;
char commandbuf[MAX_POLLCMD_BUF_LEN];
BUBAN104PORTPARAM *pPortParam;
memset( commandbuf, 0, sizeof( commandbuf ) );
pPortParam = (pBUBAN104PORTPARAM)SioParam[commid].ExtInfo;
iLen = 0;
switch ( cmdidx )
{
// format-i
case RTU_TIME: // 时间同步
GetLocalTimeEx(&sCurTime);
commandbuf[0] = 0x68;
iLen = 6;
commandbuf[iLen++] = 103;
commandbuf[iLen++] = 1;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
sCurTime.mSec = sCurTime.Sec * 1000 + sCurTime.mSec;
commandbuf[iLen++] = sCurTime.mSec % 256;
commandbuf[iLen++] = sCurTime.mSec / 256;
commandbuf[iLen++] = (u_char)sCurTime.Min;
commandbuf[iLen++] = (u_char)sCurTime.Hour;
commandbuf[iLen++] = (u_char)sCurTime.Day;
commandbuf[iLen++] = (u_char)sCurTime.Month;
commandbuf[iLen++] = (u_char)(sCurTime.Year%100);
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, commandbuf, iLen);
break;
case ASK_DI_DATA: // 召唤2级数据YX
for ( i = 0; i < (pPortParam->m_psBaoHu->DiNum+MAX_GROUP_DINUM-1)/MAX_GROUP_DINUM; i++)
{
commandbuf[0] = 0x68;
//commandbuf[1] = 14;
iLen = 6;
commandbuf[iLen++] = 100;
commandbuf[iLen++] = 0;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 5;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 5;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 21 + i;
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, commandbuf, iLen);
}
break;
case ASK_AI_DATA: // 召唤2级数据YC
for ( i = 0; i < (pPortParam->m_psBaoHu->AiNum+MAX_GROUP_AINUM-1)/MAX_GROUP_AINUM; i++)
{
commandbuf[0] = 0x68;
//commandbuf[1] = 14;
iLen = 6;
commandbuf[iLen++] = 100;
commandbuf[iLen++] = 0;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 5;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 5;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 29 + i;
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, commandbuf, iLen);
}
break;
case ASK_PI_DATA: // 召唤2级数据YM
for ( i = 0; i < (pPortParam->m_psBaoHu->PiNum+MAX_GROUP_PINUM-1)/MAX_GROUP_PINUM; i++)
{
commandbuf[0] = 0x68;
//commandbuf[1] = 14;
iLen = 6;
commandbuf[iLen++] = 101;
commandbuf[iLen++] = 0;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 2 + i;
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, commandbuf, iLen);
}
break;
case ASK_PI: //召唤电度量
commandbuf[0] = 0x68;
//commandbuf[1] = 14;
iLen = 6;
commandbuf[iLen++] = 101;
commandbuf[iLen++] = 1;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
// wen 2006.04.03 发布时间97版和2000版组分配不同
if(pPortParam->m_iPublishYear == 1997)
{
commandbuf[iLen++] = 0x41;
}
else
{
commandbuf[iLen++] = 0x45;
}
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, commandbuf, iLen);
pPortParam->Initdata = false;
break;
case ASK_ALL_DATA:// 召唤初始化数据
commandbuf[0] = 0x68;
//commandbuf[1] = 14;
iLen = 6;
commandbuf[iLen++] = 100;
commandbuf[iLen++] = 1;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 6;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 20;
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, commandbuf, iLen);
pPortParam->Initdata = false;
break;
// format-s
case FORMAT_S: // S-格式
// wen 2005.09.21 如果缓冲区内有数据则不生成S帧
if(CheckPollCmdBufEmpty(commid) <= 0)
{
break;
}
commandbuf[iLen++] = 0x68;
commandbuf[iLen++] = 4;
commandbuf[iLen++] = 0x01;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, commandbuf, iLen);
break;
// format-u
case FORMAT_U_START_ACT: // U-格式启动
commandbuf[iLen++] = 0x68;
commandbuf[iLen++] = 4;
commandbuf[iLen++] = 0x07;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, commandbuf, iLen);
break;
case FORMAT_U_START_CON: // U-格式启动应答
commandbuf[iLen++] = 0x68;
commandbuf[iLen++] = 4;
commandbuf[iLen++] = 0x0b;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, commandbuf, iLen);
break;
case FORMAT_U_STOP_ACT: // U-格式停止
commandbuf[iLen++] = 0x68;
commandbuf[iLen++] = 4;
commandbuf[iLen++] = 0x13;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, commandbuf, iLen);
break;
case FORMAT_U_STOP_CON: // U-格式停止应答
commandbuf[iLen++] = 0x68;
commandbuf[iLen++] = 4;
commandbuf[iLen++] = 0x23;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, commandbuf, iLen);
break;
case FORMAT_U_TEST_ACT: // U-格式测试
commandbuf[iLen++] = 0x68;
commandbuf[iLen++] = 4;
commandbuf[iLen++] = 0x43;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, commandbuf, iLen);
break;
case FORMAT_U_TEST_CON: // U-格式测试应答
commandbuf[iLen++] = 0x68;
commandbuf[iLen++] = 4;
commandbuf[iLen++] = (char)0x83;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
commandbuf[iLen++] = 0x00;
PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, commandbuf, iLen);
break;
default:
break;
}
}
//生成遥控遥调指令
void MakeBuBan104YkYtCommand( u_32 commid, u_char *buf, int len )
{
// buf[0] --- 端口号(=commid)
// buf[1]
// buf[2]
// buf[3]
// buf[4] --- 控点号
// buf[5]
// buf[6]
// buf[7]
// buf[8] --- 操作类型(遥控:1=选择,2=执行,3=取消,7=直控;
// 遥调:4=选择,5=执行,6=取消,8=急停)
// buf[9] --- 控制状态(1=分到合2=合到分)
// (最高位为1时为返校命令, 1=成功, 0=失败)
// 在转发遥控数据点中,只保留了要转发的控点号,实际的端口号应该是该转发点的端口
// 该转发点并没有指定虚拟的转发控点,则控点和转发点的点号一致。
int ykpoint, iLen;
char commandbuf[MAX_POLLCMD_BUF_LEN];
static int iYkStatus = 0;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (pBUBAN104PORTPARAM)SioParam[commid].ExtInfo;
memset( (char*)commandbuf, 0x00, MAX_POLLCMD_BUF_LEN );
ykpoint = buf[4]+buf[5]*256+buf[6]*65536+buf[7]*16777216;
ykpoint += pPortParam->iYkBaseAddr - 1;
iLen = 9;
switch(buf[8])
{
case 1:
case 4: // 选择
commandbuf[0] = 0x68;
commandbuf[1] = 14;
switch(pPortParam->YkMode)
{
case CONTROL_SINGAL: // 单点控制
commandbuf[6] = 45;
break;
case CONTROL_DOUBLE: // 双点控制
case CONTROL_DIRECT: // 直接控制
commandbuf[6] = 46;//(rtumsg->MsgData[3] == 1) ? 46 : 47;
break;
}
commandbuf[7] = 1;
commandbuf[8] = 6;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = (char)(ykpoint & 0x00ff);
commandbuf[iLen++] = (char)((ykpoint & 0xff00)>>8);
}
else
{
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
// wen 2002.11.18 字节顺序修改
commandbuf[iLen++] = (char)(ykpoint & 0x00ff);
commandbuf[iLen++] = (char)((ykpoint & 0xff00)>>8);
commandbuf[iLen++] = 0;
}
if(buf[9] == 1)
{
if(CONTROL_SINGAL == pPortParam->YkMode)
{
iYkStatus = 1;
}
else
{
iYkStatus = 2;
}
}
else
{
if(CONTROL_SINGAL == pPortParam->YkMode)
{
iYkStatus = 0;
}
else
{
iYkStatus = 1;
}
}
commandbuf[iLen++] = (BYTE)(0xfc + iYkStatus);
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, (char *)commandbuf, iLen);
break;
case 2:
case 5: // 执行
commandbuf[0] = 0x68;
commandbuf[1] = 14;
switch(pPortParam->YkMode)
{
case CONTROL_SINGAL: // 单点控制
commandbuf[6] = 45;
break;
case CONTROL_DOUBLE: // 双点控制
case CONTROL_DIRECT: // 直接控制
commandbuf[6] = 46;//(rtumsg->MsgData[3] == 1) ? 46 : 47;
break;
}
commandbuf[7] = 1;
commandbuf[8] = 6;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
// wen 2002.11.18 字节顺序修改
commandbuf[iLen++] = (char)(ykpoint & 0x00ff);
commandbuf[iLen++] = (char)((ykpoint & 0xff00)>>8);
}
else
{
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
// wen 2002.11.18 字节顺序修改
commandbuf[iLen++] = (char)(ykpoint & 0x00ff);
commandbuf[iLen++] = (char)((ykpoint & 0xff00)>>8);
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 0x7c + iYkStatus;
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, (char *)commandbuf, iLen);
break;
case 3:
case 6:
commandbuf[0] = 0x68;
commandbuf[1] = 14;
switch(pPortParam->YkMode)
{
case CONTROL_SINGAL: // 单点控制
commandbuf[6] = 45;
break;
case CONTROL_DOUBLE: // 双点控制
case CONTROL_DIRECT: // 直接控制
commandbuf[6] = 46;//(rtumsg->MsgData[3] == 1) ? 46 : 47;
break;
}
commandbuf[7] = 1;
commandbuf[8] = 8;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
// wen 2002.11.18 字节顺序修改
commandbuf[iLen++] = (char)(ykpoint & 0x00ff);
commandbuf[iLen++] = (char)((ykpoint & 0xff00)>>8);
}
else
{
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
// wen 2002.11.18 字节顺序修改
commandbuf[iLen++] = (char)(ykpoint & 0x00ff);
commandbuf[iLen++] = (char)((ykpoint & 0xff00)>>8);
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 0xfc + iYkStatus;
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, (char *)commandbuf, iLen);
break;
}
if(ShmGetDispYkYtFlag())
{
#ifdef _WIN32
printf("TIP_(%04d): commid =%d ykytpnt=%d, op=%d checked.\n",
_getpid(), commid, ykpoint, (buf[9] & 0x7F));
#else
printf("TIP_(%04d): commid =%d ykytpnt=%d, op=%d checked.\n",
getpid(), commid, ykpoint, (buf[9] & 0x7F));
#endif
}
}
//===================以下为POLLING规约常规函数接口======================
/*!
\brief 寻找并生成下一条命令
\param u_32 portno : RTU端口号
\param i_32 iBuIdx : 间隔装置索引
*/
void Buban104FindNextCmd(int commid)
{
int i, iCurCmdIdx;
BUBAN104PORTPARAM *pPortParam;
int framename[BUBAN104_TIMER_CMD_NUM] =
{
ASK_PI,
ASK_ALL_DATA,
FORMAT_S
};
if((commid < 0) || (commid >= GetMaxPort()))
{
return;
}
if(!ShmGetPortFlag(commid, FLAG_OPEN))
{
return;
}
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(!pPortParam->LinkOk)
{
if(CheckPollCmdBufEmpty(commid) <= 0)
{
return;
}
MakeBuban104Command(commid, FORMAT_U_START_ACT);
return;
}
for(i=0; i<BUBAN104_TIMER_CMD_NUM; i++)
{
if(pPortParam->CmdTime[i].CmdTimerConst )
pPortParam->CmdTime[i].CmdTimerCnt++;
}
if(CheckPollCmdBufEmpty(commid) <= 0)
{
return;
}
iCurCmdIdx = pPortParam->CurCmdIdx;
for ( i = 0; i < BUBAN104_TIMER_CMD_NUM; i++ )
{
if(!pPortParam->bAckRight)
{
break;
}
// wen 2005.09.16 在初始化不成功时,不生成轮询指令
if(!pPortParam->Initdata)
{
break;
}
iCurCmdIdx = (iCurCmdIdx+1) % BUBAN104_TIMER_CMD_NUM;
if ( (pPortParam->CmdTime[iCurCmdIdx].CmdTimerCnt
>= pPortParam->CmdTime[iCurCmdIdx].CmdTimerConst)
&& ( pPortParam->CmdTime[iCurCmdIdx].CmdTimerConst > 0 ))
{
pPortParam->CurCmdIdx = iCurCmdIdx;
MakeBuban104Command(commid, framename[iCurCmdIdx]);
pPortParam->CmdTime[iCurCmdIdx].CmdTimerCnt = 0;
return;
}
}
// wen (超时情况下)
if(CheckPollCmdBufEmpty(commid) > 0)
{
if(pPortParam->lTimeOutCnt >= pPortParam->lTimeOutConst)
{
if(!pPortParam->bCloseSocket)
{
//++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2005.10.28 修改超时时是否发送测试报文
//MakeBuban104Command(commid, FORMAT_S);
//======================================================
if(pPortParam->lTimeOutSendTest)
{
MakeBuban104Command(commid, FORMAT_U_TEST_ACT);
}
else
{
MakeBuban104Command(commid, FORMAT_S);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++
pPortParam->lTimeOutCnt = 0;
pPortParam->bCloseSocket = TRUE;
}
else
{
InitBuban104CommandBuffer(commid);
// 关闭网络端口
Buban104CloseSocket(commid);
}
}
}
}
void Buban104FindNextProvCmd(int commid)
{
BUBAN104PORTPARAM *pPortParam;
if((commid < 0) || (commid >= GetMaxPort()))
{
return;
}
if(!ShmGetPortFlag(commid, FLAG_OPEN))
{
return;
}
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(!pPortParam->LinkOk)
{
return;
}
if(CheckPollCmdBufEmpty(commid) <= 0)
{
return;
}
// wen (超时情况下)
if(pPortParam->lTimeOutCnt >= pPortParam->lTimeOutConst)
{
if(!pPortParam->bCloseSocket)
{
if(pPortParam->bAckRight)
{
if(pPortParam->Initdata)
{
//++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.23 修改超时时是否发送测试报文
//MakeBuban104Command(commid, FORMAT_U_TEST_ACT);
//======================================================
if(pPortParam->lTimeOutSendTest)
{
;//MakeBuban104Command(commid, FORMAT_U_TEST_ACT);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++
pPortParam->lTimeOutCnt = 0;
pPortParam->bCloseSocket = TRUE;
}
}
else
{
InitBuban104CommandBuffer(commid);
// 关闭网络端口
Buban104CloseSocket(commid);
}
}
else
{
InitBuban104CommandBuffer(commid);
// 关闭网络端口
Buban104CloseSocket(commid);
}
}
if(CheckPollCmdBufEmpty(commid) <= 0)
{
return;
}
if(pPortParam->bAckRight)
{
if(pPortParam->Initdata)
{
// 一类数据( 遥信变位 )
//ProvBuban104SendClass1(commid);
if(CheckPollCmdBufEmpty(commid) <= 0)
{
pPortParam->m_lNoDataCnt = 0;
return;
}
// 转发soe数据
//ProvBuban104SendSoe(commid);
if(CheckPollCmdBufEmpty(commid) <= 0)
{
pPortParam->m_lNoDataCnt = 0;
return;
}
// 二类数据( 遥测变化)
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.23 支持浮点数遥测的传送
//ProvBuban104SendClass2(commid);
//====================================================================
/*if(pPortParam->m_bProvAiType == 13)
{
ProvBuban104SendClass2withFloat(commid);
}
else
{
ProvBuban104SendClass2(commid);
}*/
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
if(CheckPollCmdBufEmpty(commid) <= 0)
{
pPortParam->m_lNoDataCnt = 0;
return;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.23 修改超时时是否发送测试报文
//pPortParam->m_lNoDataCnt++;
//if(pPortParam->m_lNoDataCnt >= pPortParam->lTimeOutConst)
//{
// pPortParam->m_lNoDataCnt = 0;
// MakeBuban104Command(commid, FORMAT_U_TEST_ACT);
//}
//======================================================
if(pPortParam->lTimeOutSendTest)
{
pPortParam->m_lNoDataCnt++;
if(pPortParam->m_lNoDataCnt >= pPortParam->lTimeOutConst)
{
pPortParam->m_lNoDataCnt = 0;
//MakeBuban104Command(commid, FORMAT_U_TEST_ACT);
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
}
}
void Buban104SendCmdFormPollCmdBuf(int commid)
{
BYTE fcb = 0x20;
BYTE buf[MAX_MSG_BUF_SIZE];
i_32 len;
BUBAN104PORTPARAM *pPortParam;
if((commid < 0) || (commid >= GetMaxPort()))
{
return;
}
if(!ShmGetPortFlag(commid, FLAG_OPEN))
{
return;
}
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(pPortParam->m_psBaoHu->ForceWaitFlag
&& pPortParam->m_psBaoHu->ForceWaitCnt)
{
pPortParam->m_psBaoHu->ForceWaitCnt--;
if(pPortParam->m_psBaoHu->ForceWaitCnt == 0)
{
// 清除当前命令
ClearCmdFormPollCmdBuf(commid);
//ClearCmdAllFlag(commid);
}
}
if(pPortParam->m_psBaoHu->SendCmdFlag
&& (pPortParam->m_psBaoHu->RevCmdFlag == 0))
{
pPortParam->m_psBaoHu->RetryTimeCnt++;
if(pPortParam->m_psBaoHu->RetryTimeCnt < pPortParam->m_psBaoHu->RetryTime)
{
return;
}
pPortParam->m_psBaoHu->RetryTimeCnt = 0;
pPortParam->m_psBaoHu->RetryCnt++;
if(pPortParam->m_psBaoHu->RetryCnt > pPortParam->m_psBaoHu->Retry)
{
// 清除当前命令
ClearCmdFormPollCmdBuf(commid);
//ClearCmdAllFlag(commid);
}
else
{
pPortParam->m_psBaoHu->SendCmdFlag = 0;
pPortParam->m_psBaoHu->RevCmdFlag = 0;
pPortParam->m_psBaoHu->ReSendCmdFlag = 1;
}
}
if(pPortParam->m_psBaoHu->SendCmdFlag
&& pPortParam->m_psBaoHu->RevCmdFlag)
{
// 清除当前命令
ClearCmdFormPollCmdBuf(commid);
//ClearCmdAllFlag(commid);
if(pPortParam->bSendFormatI)
{
//pPortParam->wSendSequence++;
//pPortParam->wSendSequence %= MAX_SEQUENCE;
pPortParam->bSendFormatI = FALSE;
}
}
if(pPortParam->m_psBaoHu->WaitTime)
{
pPortParam->m_psBaoHu->WaitTimeCnt++;
if(pPortParam->m_psBaoHu->WaitTimeCnt
< pPortParam->m_psBaoHu->WaitTime)
{
return;
}
}
pPortParam->m_psBaoHu->WaitTimeCnt = 0;
if(pPortParam->m_psBaoHu->ReSendCmdFlag)
{
len = ReGetCmdFormPollCmdBuf(commid, buf, sizeof(buf));
}
else
{
len = GetCmdFormPollCmdBuf(commid, buf, sizeof(buf));
// 清除标识已经在前面 ClearCmdAllFlag(commid)动作中完成
//pPortParam->m_psBaoHu->RetryCnt = 0;
}
if(len < 3)
{
return;
}
#ifdef _WIN32
if(isUdpSocketExist() == TRUE)
#endif
{
if(buf[4] & 0x01 )
{
// format_s
if((buf[4] & 0x02) == 0 )
{
buf[6] = LOBYTE(pPortParam->wRecvSequence << 1);
buf[7] = HIBYTE(pPortParam->wRecvSequence << 1);
}
// else format_u
}
// format_i
else
{
buf[4] = LOBYTE(pPortParam->wSendSequence << 1);
buf[5] = HIBYTE(pPortParam->wSendSequence << 1);
buf[6] = LOBYTE(pPortParam->wRecvSequence << 1);
buf[7] = HIBYTE(pPortParam->wRecvSequence << 1);
pPortParam->bSendFormatI = TRUE;
//4.bug_1.2.3_20060807_3/bug_2.0.1_20060807_4 104规约不能转发第二个端口的遥测数据
//发送数据后应当立即将发送序号1而不应当在清除命令时1
pPortParam->wSendSequence++;
pPortParam->wSendSequence %= MAX_SEQUENCE;
}
SendDataToPort(commid, (char *)&buf[2], len-2);
pPortParam->m_psBaoHu->SendCmdFlag = 1;
pPortParam->m_psBaoHu->ReSendCmdFlag = 0;
pPortParam->m_psBaoHu->RevCmdFlag = 0;
pPortParam->m_psBaoHu->RetryTimeCnt = 0;
}
#ifndef _WIN32
if(pPortParam->m_psBaoHu->LastGetCmdBuf == FAST_CMD_TYPE)
#else
if((pPortParam->m_psBaoHu->LastGetCmdBuf == FAST_CMD_TYPE)
|| !isUdpSocketExist())
#endif
{
pPortParam->m_psBaoHu->ForceWaitCnt = BYTE1(buf[0])+BYTE0(buf[1])+TIMER_CNT-1;
pPortParam->m_psBaoHu->ForceWaitCnt /= TIMER_CNT;
if(pPortParam->m_psBaoHu->ForceWaitCnt)
{
pPortParam->m_psBaoHu->ForceWaitFlag = 1;
}
else
{
ClearCmdFormPollCmdBuf(commid); // 清除当前命令
//ClearCmdAllFlag(commid); // 清除当前命令
if(pPortParam->bSendFormatI)
{
//pPortParam->wSendSequence++;
//pPortParam->wSendSequence %= MAX_SEQUENCE;
pPortParam->bSendFormatI = FALSE;
}
}
}
}
//===========================指令生成函数结束=========================
//===========================以下为数据处理函数=======================
void Buban104ProcessData(u_32 commid, BUBAN104PORTPARAM *psPortParam, BOOL bProcess)
{
RTUMSG msg;
BUBAN104PORTPARAM *pPortParam;
pPortParam = psPortParam;
if(TRUE == bProcess)
{
msg.PortIdx = (BYTE)commid;
msg.MsgLen = psPortParam->m_iRecvLen;
memcpy(msg.MsgData, psPortParam->m_au8RecvBuf, msg.MsgLen);
msg.MsgData[msg.MsgLen] = CHECK_WHOLE;
msg.MsgData[msg.MsgLen+1] = 0;
// 超时计数清零
pPortParam->lTimeOutCnt = 0;
pPortParam->bCloseSocket = FALSE;
// 子站数据处理
if(PROTOCOL_SLAVE == pPortParam->m_psBaoHu->PortType)
{
ProvBuban104dataProcess(commid, &msg);
return;
}
// format-i
if((msg.MsgData[2] & 0x01) == 0)
{
Buban104FormatI(&msg);
}
// format-s,format-u
else
{
// format-u
if((msg.MsgData[2] & 0x02) != 0 )
{
Buban104FormatU(&msg);
}
// format-s( 主站不会收到's'帧格式)
//else Buban104FormatS(&msg);
}
}
}
//***************************************************************
//* I帧数据的处理程序
//*参数 RTUMSG* rtumsg:接收到的数据信息
//***************************************************************
void Buban104FormatI(RTUMSG *rtumsg)
{
int commid, iSequenceInc;
BUBAN104PORTPARAM *pPortParam;
#ifdef _DEBUG_MSG_
char szbuf[256];
#endif
// length
if(rtumsg->MsgData[1] < 4)
{
return;
}
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
pPortParam->wAckSequence = (rtumsg->MsgData[4]+(rtumsg->MsgData[5] << 8)) >> 1;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// wen 2005.09.19 帧序匹配算法修改
/*
if(pPortParam->wSendSequence != pPortParam->wAckSequence )
{
pPortParam->bAckRight = FALSE;
}
//??? WEN 2002.09.17 WHY
else
{
pPortParam->bAckRight = TRUE;
}
*/
iSequenceInc = pPortParam->wSendSequence - pPortParam->wAckSequence;
if(iSequenceInc < 0)
{
iSequenceInc += MAX_SEQUENCE;
}
//不大于帧序应答尺寸(缺省值=MAX_FRAMEMATCHING_SIZE)
if((pPortParam->wSendSequence != pPortParam->wAckSequence )
&& (iSequenceInc > pPortParam->m_iFrameSize))
{
pPortParam->bAckRight = FALSE;
}
//??? WEN 2002.09.17 WHY
else
{
pPortParam->bAckRight = TRUE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
pPortParam->wRecvSequence = (rtumsg->MsgData[2]+(rtumsg->MsgData[3] << 8)) >> 1;
pPortParam->wRecvSequence += 1;
pPortParam->wRecvSequence %= MAX_SEQUENCE;
switch (rtumsg->MsgData[6])
{
case 1: // 单点遥信处理
Buban104DiDataProcess( rtumsg, 0 );
// wen 2004.09.02 修改为对于遥信变位和soe数据帧确认,以使对方能确认数据收到(拓邦公司用)
MakeBuban104Command(commid, FORMAT_S );
break;
case 2: // 单点遥信SOE处理
Buban104SoeDataProcess( rtumsg, 0 );
// wen 2004.09.02 修改为对于遥信变位和soe数据帧确认,以使对方能确认数据收到(拓邦公司用)
MakeBuban104Command(commid, FORMAT_S);
break;
case 3: // 双点遥信处理
Buban104DiDataProcess( rtumsg, 1 );
// wen 2004.09.02 修改为对于遥信变位和soe数据帧确认,以使对方能确认数据收到(拓邦公司用)
MakeBuban104Command(commid, FORMAT_S);
break;
case 4: // 双点遥信SOE处理
Buban104SoeDataProcess( rtumsg, 1 );
// wen 2004.09.02 修改为对于遥信变位和soe数据帧确认,以使对方能确认数据收到(拓邦公司用)
MakeBuban104Command(commid, FORMAT_S);
break;
case 5: // 变压器分接头位置
break;
case 6: // 变压器分接头位置带时标
break;
case 7: // 子站远动终端状态
break;
case 9: // 带品质无时标遥测
Buban104AiWithPzDataProcess( rtumsg, 0 );
break;
case 10: // 带品质带时标遥测
Buban104AiWithPzDataProcess( rtumsg, 1 );
break;
case 13:
Buban104AllFloatAiDataProcess( rtumsg );
break;
case 20: // 子站传送遥信变位帧
Buban104AutoSendDiProcess( rtumsg );
break;
case 21: // 全遥测数据处理 或变化数据
Buban104AllAiDataProcess( rtumsg );
break;
case 15: // 不带时标电度
Buban104PiDataProcess( rtumsg );
break;
case 16: // 带时标电度
Buban104PiWithTimeDataProcess( rtumsg );
break;
case 17: // 继电保护装置单个事件顺序记录帧
case 18: // 继电保护装置成组记录启动事件顺序
case 19: // 继电保护装置成组输出电路的事件顺序记录
Buban104BaoHuDataProcess( rtumsg );
break;
// wen 2004.05.27 华东104规约修改点(???)
case 30: // 带CP56Time2a时标的单点信息 M_SP_TB_1
Buban104SoeDataProcessWithCP56Time2a( rtumsg, 0 );
// wen 2004.09.02 修改为对于遥信变位和soe数据帧确认,以使对方能确认数据收到(拓邦公司用)
MakeBuban104Command( commid, FORMAT_S );
break;
case 31: // 带CP56Time2a时标的双点信息 M_DP_TB_1
Buban104SoeDataProcessWithCP56Time2a( rtumsg, 1 );
// wen 2004.09.02 修改为对于遥信变位和soe数据帧确认,以使对方能确认数据收到(拓邦公司用)
MakeBuban104Command( commid, FORMAT_S );
break;
case 32: // 带CP56Time2a时标的步位置信息 M_ST_TB_1
break;
case 33: // 带CP56Time2a时标的32比特串 M_BO_TB_1
break;
case 34: // 带CP56Time2a时标的测量值, 规一化值 M_ME_TD_1
Buban104AiWithDataProcessWithM_ME_TD_1( rtumsg );
break;
case 35: // 带CP56Time2a时标的测量值, 标度化值 M_ME_TE_1
Buban104AiWithDataProcessWithM_ME_TE_1( rtumsg );
break;
case 36: // 带CP56Time2a时标的测量值, 短浮点数 M_ME_TF_1
Buban104AiWithDataProcessWithM_ME_TF_1( rtumsg );
break;
case 37: // 带CP56Time2a时标的累计量 M_IT_TB_1
Buban104PiWithTimeDataProcessWithM_IT_TB_1( rtumsg );
break;
case 38: // 带CP56Time2a时标的继电保护装置事件 M_EP_TD_1
break;
case 39: // 带CP56Time2a时标的继电保护装置成组启动事件 M_EP_TE_1
break;
case 40: // 带CP56Time2a时标的继电保拌装置成组输出电路信息M_EP_TF_1
break;
case 45:
case 46: // 遥控返校
case 47: // 遥调返校
Buban104YkYtAck( rtumsg );
break;
case 48: // 设定确认
Buban104SetAck( rtumsg );
break;
case 100: // 总召唤确认
Buban104InitdataProecss( rtumsg );
break;
case 101: // 电度结束帧
Buban104PidataEnd( rtumsg );
break;
case 103: // 时间同步确认帧
Buban104SynTime( rtumsg );
break;
default:
#ifdef _DEBUG_MSG_
DebugPrint("接收到不认识的命令,请检查程序.\n");
#endif
break;
}
}
void Buban104FormatU(RTUMSG *rtumsg)
{
int commid;
BUBAN104PORTPARAM *pPortParam;
// length
if(rtumsg->MsgData[1] < 4)
{
return;
}
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
switch(rtumsg->MsgData[2] & 0xfc)
{
case 0x08: // 启动动作响应
InitBuban104CommandBuffer(commid);
pPortParam->bAckRight = TRUE;
pPortParam->LinkOk = TRUE;
break;
case 0x20: // 停止动作响应
pPortParam->bAckRight = TRUE;
break;
case 0x40: // 测试动作
//pPortParam->bAckRight = TRUE;
MakeBuban104Command(commid, FORMAT_U_TEST_CON);
if( !pPortParam->bAckRight )
{
pPortParam->bAckRight = TRUE;
pPortParam->wSendSequence = pPortParam->wAckSequence;
}
break;
// wen 2005.11.02 增加测试响应处理
case 0x80: // 测试响应
if(!pPortParam->bAckRight)
{
pPortParam->bAckRight = TRUE;
}
break;
default: // 错误的响应
pPortParam->bAckRight = FALSE;
break;
}
}
/* Buban104 初始化数据处理 */
void Buban104InitdataProecss(RTUMSG * rtumsg)
{
int commid;
WORD wTransCause;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
wTransCause = rtumsg->MsgData[8];
}
else
{
wTransCause = rtumsg->MsgData[8] + (rtumsg->MsgData[9] << 8);
}
switch(wTransCause)
{
case 7:
case 9://总召唤确认
break;
case 10://总召唤结束
pPortParam->Initdata = TRUE;
break;
}
}
/* 电度结束帧 */
void Buban104PidataEnd(RTUMSG * rtumsg)
{
int commid;
WORD wTransCause;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
wTransCause = rtumsg->MsgData[8];
}
else
{
wTransCause = rtumsg->MsgData[8] + (rtumsg->MsgData[9] << 8);
}
if(wTransCause & 0x0040)
{
pPortParam->Initdata = TRUE;
return;
}
switch(wTransCause)
{
case 7://总召唤确认
break;
case 10://电度召唤结束
pPortParam->Initdata = TRUE;
break;
}
}
//设定确认
void Buban104SetAck( RTUMSG *rtumsg)
{
}
//Buban104 遥控遥调返校程序
void Buban104YkYtAck(RTUMSG * rtumsg)
{
int commid;
BYTE bYkOperate;
WORD wTransCause;
YKYT_PARAM YkYtParam;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
YkYtParam.m_iYkYtPnt = (rtumsg->MsgData[11]<<8) + rtumsg->MsgData[10];
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.24
//YkYtParam.m_iYkYtPnt -= pPortParam->iYkBaseAddr;
//=======================================================================
YkYtParam.m_iYkYtPnt -= (pPortParam->iYkBaseAddr-1);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
YkYtParam.m_iYkYtPnt %= 256;
wTransCause = rtumsg->MsgData[8];
bYkOperate = rtumsg->MsgData[12];
}
else
{
YkYtParam.m_iYkYtPnt = (rtumsg->MsgData[14] << 16)
+ (rtumsg->MsgData[13]<<8) + rtumsg->MsgData[12];
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.24
//YkYtParam.m_iYkYtPnt -= pPortParam->iYkBaseAddr;
//=======================================================================
YkYtParam.m_iYkYtPnt -= (pPortParam->iYkBaseAddr-1);
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
YkYtParam.m_iYkYtPnt %= 256;
wTransCause = (rtumsg->MsgData[9]<<8) + rtumsg->MsgData[8];
bYkOperate = rtumsg->MsgData[15];
}
if(bYkOperate & 0x80) //选择返校
{
YkYtParam.m_iYkYtStep = STEP_YKYT_SELECT;
//此位为肯定或否定确认位 || 撤销确认
if((wTransCause & 0x0040) || (wTransCause == 0x0009))
{
YkYtParam.m_iYkYtOperate = 3;
}
else if(wTransCause == 0x0007)
{
if(rtumsg->MsgData[6] != 45)
{
switch(bYkOperate & 0x03)
{
case 1://控分
if(pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate == 2)
{
YkYtParam.m_iYkYtOperate = pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate;
}
else
{
YkYtParam.m_iYkYtOperate = 3;
}
break;
case 2://控合
if(pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate == 1)
{
YkYtParam.m_iYkYtOperate = pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate;
}
else
{
YkYtParam.m_iYkYtOperate = 3;
}
break;
default:
YkYtParam.m_iYkYtOperate = 3;
break;
}
}
else
{
// 控合
if( bYkOperate & 0x01 )
{
if(pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate == 1)
{
YkYtParam.m_iYkYtOperate = pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate;
}
else
{
YkYtParam.m_iYkYtOperate = 3;
}
}
// 控分
else
{
if(pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate == 2)
{
YkYtParam.m_iYkYtOperate = pPortParam->m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate;
}
else
{
YkYtParam.m_iYkYtOperate = 3;
}
}
}
}
YkYtParam.m_iYkYtUpDown = YKYT_SEND_UP;
SendYkYtCommand2(commid, &YkYtParam);
}
else //执行并完成
{
//此位为肯定或否定确认位
if((wTransCause & 0x0040) == 0)
{
switch(wTransCause)
{
case 0x0007://执行确认
break;
case 0x000a://执行完成
break;
default:
break;
}
}
}
}
/* Buban104 对时程序 */
void Buban104SynTime(RTUMSG * rtumsg)
{
int commid;
WORD wTransCause;
DAY_TIME stime;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(1 != pPortParam->m_psBaoHu->CheckTime)
{
return;
}
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
wTransCause = rtumsg->MsgData[8];
}
else
{
wTransCause = rtumsg->MsgData[8] + (rtumsg->MsgData[9]<<8);
}
if(wTransCause != 0x0007)
{
return;
}
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
stime.mSec = (rtumsg->MsgData[13]<<8) + rtumsg->MsgData[12];
stime.Sec = stime.mSec / 1000;
stime.mSec %= 1000;
stime.Min = rtumsg->MsgData[14] & 0x3F;
stime.Hour = rtumsg->MsgData[15] & 0x1F;
stime.Day = rtumsg->MsgData[16] & 0x1F;
stime.Month= rtumsg->MsgData[17] & 0x0F;
stime.Year = (rtumsg->MsgData[18] & 0x7F)+2000;
}
else
{
stime.mSec = (rtumsg->MsgData[16]<<8) + rtumsg->MsgData[15];
stime.Sec = stime.mSec / 1000;
stime.mSec %= 1000;
stime.Min = rtumsg->MsgData[17] & 0x3F;
stime.Hour = rtumsg->MsgData[18] & 0x1F;
stime.Day = rtumsg->MsgData[19] & 0x1F;
stime.Month= rtumsg->MsgData[20] & 0x0F;
stime.Year = (rtumsg->MsgData[21] & 0x7F)+2000;
}
SetLocalTimeEx(&stime);
}
/* 子站主动传送遥信变位帧 */
void Buban104AutoSendDiProcess(RTUMSG *rtumsg)
{
int i, j, dipnt, len, istart;
DI_DEF pntmsg;
WORD wStatus, wStatusBit, wTransCause;
int commid;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
wTransCause = rtumsg->MsgData[8];
istart = 10;
}
else
{
wTransCause = rtumsg->MsgData[8] + (rtumsg->MsgData[9]<<8);
istart = 12;
}
if(wTransCause == 0x0003)
{
for(i = istart; i < (2 + len); )
{
dipnt = rtumsg->MsgData[i++];
dipnt += (rtumsg->MsgData[i++]<<8);
if(VER_IEC870_5_104 == pPortParam->RtuVersion)
{
dipnt += (rtumsg->MsgData[i++]<<16);
}
dipnt -= pPortParam->iDiBaseAddr;
wStatus = rtumsg->MsgData[i++];
wStatus = (wStatus<<8) + rtumsg->MsgData[i++];
wStatusBit = rtumsg->MsgData[i++];
wStatusBit = (wStatusBit<<8) + rtumsg->MsgData[i++];
for( j = 0; j < 16; j++ )
{
if( wStatusBit & (0x0001 << j) )
{
if( wStatus & (0x0001 << j) )
pntmsg.Status = 1;
else
pntmsg.Status = 0;
SetPntMsg(commid, dipnt+j, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS);
}
}
}
}
}
// Buban104 带品质描述的遥测数据处理
void Buban104AiWithPzDataProcess(RTUMSG * rtumsg, int flag)
{
int i, aipnt, len;
AI_DEF pntmsg;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
//处理变化遥测
for(i = istart; i < (2 + len);)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
aipnt -= pPortParam->iAiBaseAddr;
pntmsg.RawValue = (short)(rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8));
// 品质描述
// rtumsg->MsgData[i+2];
i += 3;
SetPntMsg(commid, aipnt, (void *)&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
// 时标
if(flag)
{
i += 3;
}
}
}
void Buban104AllAiDataProcess(RTUMSG *rtumsg)
{
int i, aipnt, len;
AI_DEF pntmsg;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(len <= 0)
{
return;
}
aipnt = 0;
//处理变化遥测
if((rtumsg->MsgData[7] & 0x80)==0)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for(i = istart; i < len + 2;)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
aipnt -= pPortParam->iAiBaseAddr;
pntmsg.RawValue = (short)((rtumsg->MsgData[i+1]<<8) + rtumsg->MsgData[i]);
i += 2;
SetPntMsg(commid, aipnt, (void *)&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
}
return;
}
//处理全遥测
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 12;
aipnt = rtumsg->MsgData[10]+(rtumsg->MsgData[11]<<8);
}
else
{
istart = 15;
aipnt = rtumsg->MsgData[12]+(rtumsg->MsgData[13]<<8)+(rtumsg->MsgData[14]<<16);
}
aipnt -= pPortParam->iAiBaseAddr;
for(i=istart; i < (len+2); i+=2)
{
pntmsg.RawValue = (short)(rtumsg->MsgData[i] + (rtumsg->MsgData[i+1]<<8));
SetPntMsg(commid, aipnt, (void *)&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
aipnt++;
}
}
void Buban104AllFloatAiDataProcess(RTUMSG *rtumsg)
{
int i, aipnt, len;
float fValue;
AI_DEF pntmsg;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(len <= 0)
{
return;
}
aipnt = 0;
//处理变化遥测
if((rtumsg->MsgData[7] & 0x80)==0)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for(i = istart; i < len + 4;)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
aipnt -= pPortParam->iAiBaseAddr;
fValue = SequenceRtuToHostfloat((*((float *)&rtumsg->MsgData[i])));
pntmsg.RawValue = (unsigned long)fValue;
// 含有一个字节的品质描述
i += sizeof(float)+1;
SetPntMsg(commid, aipnt, (void *)&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
}
return;
}
//处理全遥测
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 12;
aipnt = rtumsg->MsgData[10]+(rtumsg->MsgData[11]<<8);
}
else
{
istart = 15;
aipnt = rtumsg->MsgData[12]+(rtumsg->MsgData[13]<<8)+(rtumsg->MsgData[14]<<16);
}
aipnt -= pPortParam->iAiBaseAddr;
for(i=istart; i < (len+2); i+=5)
{
fValue = SequenceRtuToHostfloat((*((float *)&rtumsg->MsgData[i])));
pntmsg.RawValue = (unsigned long)fValue;
SetPntMsg(commid, aipnt, (void *)&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
aipnt++;
}
}
void Buban104DiDataProcess(RTUMSG *rtumsg, int flag)
{
int i, dipnt, len;
DI_DEF pntmsg;
WORD wTransCause;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
wTransCause = rtumsg->MsgData[8];
}
else
{
wTransCause = rtumsg->MsgData[8] + (rtumsg->MsgData[9]<<8);
}
//从站主动上发 变化遥信
if(wTransCause == 0x0003)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for ( i = istart; i < 2 + len; )
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
dipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
dipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
dipnt -= pPortParam->iDiBaseAddr;
if ( flag == 0 )
pntmsg.Status = rtumsg->MsgData[i++] & 0x1;
else
{
switch ( rtumsg->MsgData[i++] & 0x3 )
{
case 1:
pntmsg.Status = 1;
break;
case 2:
pntmsg.Status = 0;
break;
default:
pntmsg.Status = 0xff;
break;
}
}
if ( pntmsg.Status != 0xff )
{
SetPntMsg(commid, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS);
}
}
return;
}
if(rtumsg->MsgData[7] & 0x80)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 12;
dipnt = rtumsg->MsgData[10]+(rtumsg->MsgData[11]<<8);
}
else
{
istart = 15;
dipnt = rtumsg->MsgData[12]+(rtumsg->MsgData[13]<<8)+(rtumsg->MsgData[14]<<16);
}
dipnt -= pPortParam->iDiBaseAddr;
for ( i = istart; i < 2 + len; i++,dipnt++ )
{
if ( flag == 0 )
pntmsg.Status = rtumsg->MsgData[i] & 0x1;
else
{
switch ( rtumsg->MsgData[i] & 0x3 )
{
case 1:
pntmsg.Status = 1;
break;
case 2:
pntmsg.Status = 0;
break;
default:
pntmsg.Status = 0xff;
break;
}
}
if(pntmsg.Status != 0xff)
{
SetPntMsg(commid, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS);
}
}
}
else
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for ( i = istart; i < 2 + len; )
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
dipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
dipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
dipnt -= pPortParam->iDiBaseAddr;
if ( flag == 0 )
pntmsg.Status = rtumsg->MsgData[i++] & 0x1;
else
{
switch ( rtumsg->MsgData[i++] & 0x3 )
{
case 1:
pntmsg.Status = 1;
break;
case 2:
pntmsg.Status = 0;
break;
default:
pntmsg.Status = 0xff;
break;
}
}
if(pntmsg.Status != 0xff)
{
SetPntMsg(commid, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS);
}
}
}
}
void Buban104SoeDataProcess(RTUMSG *rtumsg, int flag)
{
_int64 i64Millseconds;
time_t iTime;
int i, pnt, len;
char st;
int sec;
DI_DEF pntmsg;
DAY_TIME sm;
struct tm *testtm;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for ( i = istart; i < len + 2;)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
pnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
pnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
pnt -= pPortParam->iDiBaseAddr;
if ( flag == 0 )
st = rtumsg->MsgData[i++] & 0x01;
else
{
switch ( rtumsg->MsgData[i++] & 0x3 )
{
case 1:
st = 1;
break;
case 2:
st = 0;
break;
default:
st = 0x0f;
break;
}
}
if ( st == 0x0f )
continue;
sec = rtumsg->MsgData[i] + ( rtumsg->MsgData[i+1] << 8 );
pntmsg.SoeTime.mSec = sec % 1000;
pntmsg.SoeTime.Sec = sec / 1000;
pntmsg.SoeTime.Min = (rtumsg->MsgData[i+2] & 0x3f); // 分
i += 3;
GetLocalTimeEx(&sm);
if(abs(pntmsg.SoeTime.Min-sm.Min) > 50)
{
i64Millseconds = SystemTimeToMillseconds(&sm, 0);
if(i64Millseconds > 0)
{
// 减去一小时
iTime = (long)(i64Millseconds/1000) - 3600;
testtm = localtime(&iTime);
sm.Year = testtm->tm_year + 1900;
sm.Month = testtm->tm_mon + 1;
sm.Day = testtm->tm_mday;
sm.Hour = testtm->tm_hour;
sm.Min = testtm->tm_min;
sm.Sec = testtm->tm_sec;
}
}
pntmsg.SoeTime.Hour = sm.Hour;
pntmsg.SoeTime.Day = sm.Day;
pntmsg.SoeTime.Month = sm.Month;
pntmsg.SoeTime.Year = sm.Year;
pntmsg.Status = st;
SetPntMsg(commid, pnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_SOE_TIME);
}
}
void Buban104PiDataProcess( RTUMSG * rtumsg )
{
int i, point, len;
PI_DEF pntmsg;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for ( i = istart; i < 2 + len; )
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
point = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
point = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
point -= pPortParam->iPiBaseAddr;
pntmsg.RawValue = (rtumsg->MsgData[i+3]<<24) + (rtumsg->MsgData[i+2]<<16)
+ (rtumsg->MsgData[i+1]<<8) + rtumsg->MsgData[i];
//rtumsg->MsgData[i+4]; // 顺序记号
i += 5;
SetPntMsg(commid, point, (void *)&pntmsg, PI_PNT_TYPE, PNT_RAWVALUE);
}
}
void Buban104PiWithTimeDataProcess( RTUMSG *rtumsg )
{
int i, point, len;
PI_DEF pntmsg;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for ( i = istart; i < 2 + len; )
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
point = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
point = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
point -= pPortParam->iPiBaseAddr;
pntmsg.RawValue = (rtumsg->MsgData[i+3]<<24) + (rtumsg->MsgData[i+2]<<16)
+ (rtumsg->MsgData[i+1]<<8) + rtumsg->MsgData[i];
//rtumsg->MsgData[i+4]; // 顺序记号
// 3bytes 时间
i += 8;
SetPntMsg(commid, point, (void *)&pntmsg, PI_PNT_TYPE, PNT_RAWVALUE);
}
}
void Buban104BaoHuDataProcess( RTUMSG *rtumsg )
{
// 该功能不做处理
}
void Buban104DefaultBaoHuDataProcess( RTUMSG *rtumsg )
{
// 该功能不做处理
}
// 新增函数,含有 7 BYTE 的时标
//***************************************************************
//* Buban104 SOE 数据处理(7 bytes 时间) *
//***************************************************************
void Buban104SoeDataProcessWithCP56Time2a( RTUMSG *rtumsg, int flag )
{
_int64 i64Millseconds;
time_t iTime;
int i, pnt, len;
char st;
int sec;
DI_DEF pntmsg;
DAY_TIME sm;
struct tm *testtm;
int commid, istart;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
}
else
{
istart = 12;
}
for ( i = istart; i < len + 2; )
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
pnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
pnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
pnt -= pPortParam->iDiBaseAddr;
if(flag == 0)
{
st = rtumsg->MsgData[i++] & 0x01;
}
else
{
switch ( rtumsg->MsgData[i++] & 0x3 )
{
case 1:
st = 1;
break;
case 2:
st = 0;
break;
default:
st = 0x0f;
break;
}
}
if(st == 0x0f)
{
continue;
}
sec = rtumsg->MsgData[i] + (rtumsg->MsgData[i+1] << 8);
pntmsg.SoeTime.mSec = sec % 1000;
pntmsg.SoeTime.Sec = sec / 1000;
pntmsg.SoeTime.Min = (char)(rtumsg->MsgData[i+2] & 0x3f);
pntmsg.SoeTime.Hour = (char)(rtumsg->MsgData[i+3] & 0x1f);
pntmsg.SoeTime.Day = (char)(rtumsg->MsgData[i+4] & 0x1f);
//rtumsg->MsgData[i+5]; // month
//rtumsg->MsgData[i+6]; // year
i += 7;
GetLocalTimeEx(&sm);
if((pntmsg.SoeTime.Day-sm.Day) < 0)
{
i64Millseconds = SystemTimeToMillseconds(&sm, 0);
if(i64Millseconds > 0)
{
// 减去一小时
iTime = (long)(i64Millseconds/1000) - 3600;
testtm = localtime(&iTime);
sm.Year = testtm->tm_year + 1900;
sm.Month = testtm->tm_mon + 1;
sm.Day = testtm->tm_mday;
sm.Hour = testtm->tm_hour;
sm.Min = testtm->tm_min;
sm.Sec = testtm->tm_sec;
}
}
pntmsg.SoeTime.Month = sm.Month;
pntmsg.SoeTime.Year = sm.Year;
pntmsg.Status = st;
SetPntMsg(commid, pnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_SOE_TIME);
}
}
void Buban104AiWithDataProcessWithM_ME_TD_1(RTUMSG * rtumsg)
{
int i, aipnt, len;
AI_DEF pntmsg;
char szbuf[256];
int commid, istart, istep;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
istep = 11;
}
else
{
istart = 12;
istep = 12;
}
//处理变化遥测
for ( i = istart; i < 2 + len; )
{
if( ( i + istep ) > (2 + len))
{
#ifdef _WIN32
sprintf(szbuf, ">>>>>WARN(%04d): Commid_%02d (iLen=%d) is not enough in Buban104AiWithDataProcessWithM_ME_TD_1",
_getpid(), commid, len);
#else
sprintf(szbuf, ">>>>>WARN(%04d): Commid_%02d (iLen=%d) is not enough in Buban104AiWithDataProcessWithM_ME_TD_1",
getpid(), commid, len);
#endif
DebugPrint(szbuf);
break;
}
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
aipnt -= pPortParam->iAiBaseAddr;
pntmsg.RawValue = (short)((rtumsg->MsgData[i+1]<<8) + rtumsg->MsgData[i]);
SetPntMsg(commid, aipnt, (void *)&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
// 7字节时标
i += 9;
}
}
void Buban104AiWithDataProcessWithM_ME_TE_1(RTUMSG * rtumsg)
{
Buban104AiWithDataProcessWithM_ME_TD_1(rtumsg);
}
void Buban104AiWithDataProcessWithM_ME_TF_1(RTUMSG * rtumsg)
{
int i, aipnt, len;
AI_DEF pntmsg;
char szbuf[256];
float fValue;
int commid, istart, istep;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
len = (int)rtumsg->MsgData[1];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
istep = 14;
}
else
{
istart = 12;
istep = 15;
}
//处理变化遥测
for ( i = istart; i < 2 + len; )
{
if( ( i + istep ) > (2 + len))
{
#ifdef _WIN32
sprintf(szbuf, ">>>>>WARN(%04d): Commid_%02d (iLen=%d) is not enough in Buban104AiWithDataProcessWithM_ME_TF_1",
_getpid(), commid, len);
#else
sprintf(szbuf, ">>>>>WARN(%04d): Commid_%02d (iLen=%d) is not enough in Buban104AiWithDataProcessWithM_ME_TF_1",
getpid(), commid, len);
#endif
DebugPrint(szbuf);
break;
}
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
aipnt = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
aipnt -= pPortParam->iAiBaseAddr;
fValue = *((float *)&rtumsg->MsgData[i]);
SequenceRtuToHost((char *)&fValue, sizeof(float));
// 品质描述
// rtumsg->MsgData[i+1];
// 保留2位小数
pntmsg.RawValue = (int)(fValue * 100);
SetPntMsg(commid, aipnt, (void *)&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
// 7字节时标
i += 12;
}
}
//Buban104 电度数据处理with time
void Buban104PiWithTimeDataProcessWithM_IT_TB_1(RTUMSG *rtumsg)
{
int i, point, len;
AI_DEF pntmsg;
char szbuf[256];
int commid, istart, istep;
BUBAN104PORTPARAM *pPortParam;
commid = rtumsg->PortIdx;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
istart = 10;
istep = 14;
}
else
{
istart = 12;
istep = 15;
}
len = (int)rtumsg->MsgData[1];
for ( i = istart; i < 2 + len; )
{
if( ( i + istep ) > (2 + len))
{
#ifdef _WIN32
sprintf(szbuf, ">>>>>WARN(%04d): Commid_%02d (iLen=%d) is not enough in Buban104PiWithTimeDataProcessWithM_IT_TB_1",
_getpid(), commid, len);
#else
sprintf(szbuf, ">>>>>WARN(%04d): Commid_%02d (iLen=%d) is not enough in Buban104PiWithTimeDataProcessWithM_IT_TB_1",
getpid(), commid, len);
#endif
DebugPrint(szbuf);
break;
}
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
point = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8);
i += 2;
}
else
{
point = rtumsg->MsgData[i]+(rtumsg->MsgData[i+1]<<8)+(rtumsg->MsgData[i+2]<<16);
i += 3;
}
point -= pPortParam->iPiBaseAddr;
pntmsg.RawValue = (rtumsg->MsgData[i+3]<<24) + (rtumsg->MsgData[i+2]<<16)
+ (rtumsg->MsgData[i+1]<<8) + rtumsg->MsgData[i];
SetPntMsg(commid, point, (void *)&pntmsg, PI_PNT_TYPE, PNT_RAWVALUE);
// 1 BYTE (IV CA CY 顺序号)
// 7 BYTE 时标
i += 12;
}
}
//=========================以下为Buban104转发数据功能=======================//
void ProvBuban104dataProcess(int commid, RTUMSG *rtumsg)
{
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
// 数据校验错误( 附加字节的第二个字节)
if(rtumsg->MsgData[rtumsg->MsgLen+1] > 0)
{
return;
}
// format-i
if((rtumsg->MsgData[2] & 0x01) == 0)
{
if(pPortParam->LinkOk)
{
ProvBuban104FormatI(commid, rtumsg);
}
}
// format-s,format-u
else
{
// format-u
if((rtumsg->MsgData[2] & 0x02) != 0)
{
ProvBuban104FormatU( commid, rtumsg );
}
// format-s
else
{
ProvBuban104FormatS( commid, rtumsg );
}
}
}
void ProvBuban104FormatI(int commid, RTUMSG *rtumsg)
{
//WORD wLastSequence;
int iSequenceInc;
BUBAN104PORTPARAM *pPortParam;
// length
if( rtumsg->MsgData[1] < 4 )
{
return;
}
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
// 超时计数清零
pPortParam->lTimeOutCnt = 0;
pPortParam->wAckSequence = (rtumsg->MsgData[4] + (rtumsg->MsgData[5]<<8)) >> 1;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// wen 2005.09.19 帧序匹配算法修改
/*
if(pPortParam->wAckSequence == 0 )
{
wLastSequence = MAX_SEQUENCE;
}
else
{
wLastSequence = pPortParam->wAckSequence-1;
}
if((pPortParam->wSendSequence != pPortParam->wAckSequence)
&& (pPortParam->wSendSequence != wLastSequence))
{
pPortParam->bAckRight = FALSE;
}
else
{
pPortParam->bCloseSocket = FALSE;
pPortParam->bAckRight = TRUE;
}
*/
iSequenceInc = pPortParam->wSendSequence - pPortParam->wAckSequence;
if(iSequenceInc < 0)
{
iSequenceInc += MAX_SEQUENCE;
}
//不大于帧序应答尺寸(缺省值=MAX_FRAMEMATCHING_SIZE)
if((pPortParam->wSendSequence != pPortParam->wAckSequence )
&& (iSequenceInc > pPortParam->m_iFrameSize))
{
pPortParam->bAckRight = FALSE;
}
else
{
pPortParam->bCloseSocket = FALSE;
pPortParam->bAckRight = TRUE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
pPortParam->wRecvSequence = ((rtumsg->MsgData[2] + (rtumsg->MsgData[3]<<8)) >> 1)+1;
pPortParam->wRecvSequence %= MAX_SEQUENCE;
switch(rtumsg->MsgData[6])
{
case 1: // 单点遥信处理
break;
case 2: // 单点遥信SOE处理
break;
case 3: // 双点遥信处理
break;
case 4: // 单点遥信SOE处理
break;
case 5: // 变压器分接头位置
break;
case 6: // 变压器分接头位置带时标
break;
case 7: // 总召唤数据
ProvBuban104SendAllData(commid, rtumsg);
break;
case 9: // 带品质无时标遥测
break;
case 10: // 带品质带时标遥测
break;
case 21: // 全遥测数据处理 或变化数据
break;
case 15: // 不带时标电度
break;
case 16: // 带时标电度
break;
case 17:
case 18:
case 19: // 保护数据
break;
case 45: // wen 2006.07.11
case 46: // 遥控返校
case 47: // 遥调返校
//ProvBuban104YkYtData(commid, rtumsg);
break;
case 100: // 召唤数据
//ProvBuban104SendAllData(commid, rtumsg);
break;
case 101: // 召唤电度
//ProvBuban104SendPIData(commid, rtumsg);
break;
case 103: // 时间同步确认帧
//ProvBuban104ProcessTime(commid, rtumsg);
break;
}
}
void ProvBuban104FormatU(int commid, RTUMSG *rtumsg)
{
BUBAN104PORTPARAM *pPortParam;
// length
if( rtumsg->MsgData[1] != 4 )
{
return;
}
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
switch(rtumsg->MsgData[2] & 0xfc)
{
case 0x04: // 启动动作
InitBuban104CommandBuffer(commid);
pPortParam->LinkOk = TRUE;
MakeBuban104Command(commid, FORMAT_U_START_CON);
break;
case 0x10: // 停止动作
pPortParam->LinkOk = FALSE;
MakeBuban104Command(commid, FORMAT_U_STOP_CON);
break;
case 0x80: // 测试动作响应
pPortParam->bAckRight = TRUE;
// 超时计数清零
pPortParam->lTimeOutCnt = 0;
pPortParam->bCloseSocket = FALSE;
break;
case 0x40: // 测试动作
//if(!pPortParam->LinkOk)
//{
// break;
//}
pPortParam->LinkOk = TRUE;
MakeBuban104Command(commid, FORMAT_U_TEST_CON);
pPortParam->lTimeOutCnt = 0;
pPortParam->bCloseSocket = FALSE;
pPortParam->bAckRight = TRUE;
break;
default: // 错误的响应
pPortParam->bAckRight = FALSE;
break;
}
}
void ProvBuban104FormatS(int commid, RTUMSG *rtumsg)
{
//WORD wLastSequence;
int iSequenceInc;
BUBAN104PORTPARAM *pPortParam;
// length
if( rtumsg->MsgData[1] != 4 )
{
return;
}
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
pPortParam->wAckSequence = (rtumsg->MsgData[4] + (rtumsg->MsgData[5]<<8)) >> 1;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
// wen 2005.09.19 帧序匹配算法修改
/*
if(pPortParam->wAckSequence == 0)
{
wLastSequence = MAX_SEQUENCE;
}
else
{
wLastSequence = pPortParam->wAckSequence-1;
}
if((pPortParam->wSendSequence == (pPortParam->wAckSequence + 1) )
|| (pPortParam->wSendSequence == wLastSequence))
{
pPortParam->bAckRight = TRUE;
pPortParam->lTimeOutCnt = 0;
pPortParam->bCloseSocket = FALSE;
}
*/
iSequenceInc = pPortParam->wSendSequence - pPortParam->wAckSequence;
if(iSequenceInc < 0)
{
iSequenceInc += MAX_SEQUENCE;
}
//不大于帧序应答尺寸(缺省值=MAX_FRAMEMATCHING_SIZE)
if((pPortParam->wSendSequence == pPortParam->wAckSequence)
|| (iSequenceInc < pPortParam->m_iFrameSize))
{
pPortParam->bAckRight = TRUE;
pPortParam->lTimeOutCnt = 0;
pPortParam->bCloseSocket = FALSE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++//
}
//响应分组召唤和总召唤
//总召唤确认(传送原因[8]=0x07,0x09确认; =0x0a 总召唤结束)
void ProvBuban104SendAllData(int commid, RTUMSG * rtumsg)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
int iGroup, iCmdType, iLen=0;
WORD wTransCause;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
iGroup = rtumsg->MsgData[12];
wTransCause = rtumsg->MsgData[8];
iCmdType = FAST_POLL_CMD;
//总召唤应答
/*commandbuf[0] = 0x68;
iLen = 2;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 8; // 应答总召结束
commandbuf[iLen++] = 0x81; // 限定词VSQ
commandbuf[iLen++] = 9; // 传送原因
commandbuf[iLen++] = 0; // 应用服务单元公共地址
commandbuf[iLen++] = 0; // 应用服务单元公共地址
commandbuf[iLen++] = 0xFF; // 功能类型FUN
commandbuf[iLen++] = 0; // 信息序号INF
commandbuf[iLen++] = 0; // 扫描序号SCN
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLen);*/
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.23 支持浮点数遥测的传送
//ProvBuban104SendAI(commid, rtumsg, 0);
//====================================================================
//if(pPortParam->m_bProvAiType == 13)
{
ProvBuban104SendAIwithFloat(commid, rtumsg, 0);
}
/*else
{
ProvBuban104SendAI(commid, rtumsg, 0);
}*/
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//ProvBuban104SendDI(commid, rtumsg, 0);
memset(&commandbuf, 0, sizeof(commandbuf));
//总召唤结束
commandbuf[0] = 0x68;
iLen = 2;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 8; // 应答总召结束
commandbuf[iLen++] = 0x81; // 限定词VSQ
commandbuf[iLen++] = 9; // 传送原因
commandbuf[iLen++] = 0; // 应用服务单元公共地址
commandbuf[iLen++] = 0; // 应用服务单元公共地址
commandbuf[iLen++] = 0xFF; // 功能类型FUN
commandbuf[iLen++] = 0; // 信息序号INF
commandbuf[iLen++] = 0; // 扫描序号SCN
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLen);
//ProvMakeBuban104Command(commid, ASK_ALLDATA_END);
pPortParam->m_psBaoHu->DiChange = FALSE;
pPortParam->Initdata = TRUE;
}
/*
void ProvBuban104SendAllData(int commid, RTUMSG * rtumsg)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
int iGroup, iCmdType, iLen = 0;
WORD wTransCause;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if (VER_BUBAN_104 == pPortParam->RtuVersion)
{
iGroup = rtumsg->MsgData[12];
wTransCause = rtumsg->MsgData[8];
}
else
{
iGroup = rtumsg->MsgData[15];
wTransCause = rtumsg->MsgData[8] + (rtumsg->MsgData[9] << 8);
}
//分组召唤
if (iGroup != 20)
{
iGroup -= 20;
//无效组号
if ((iGroup <= 0) || (iGroup > 12))
{
return;
}
if (iGroup > 8)
{
iGroup -= 8;
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.23 支持浮点数遥测的传送
//ProvBuban104SendAI(commid, rtumsg, iGroup);
//====================================================================
if (pPortParam->m_bProvAiType == 13)
{
ProvBuban104SendAIwithFloat(commid, rtumsg, iGroup);
}
else
{
ProvBuban104SendAI(commid, rtumsg, iGroup);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
else
ProvBuban104SendDI(commid, rtumsg, iGroup);
return;
}
if (pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
//总召唤
commandbuf[0] = 0x68;
iLen = 2;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 100;
commandbuf[iLen++] = 0;
if (VER_BUBAN_104 == pPortParam->RtuVersion)
{
switch (wTransCause)
{
case 0x0006://激活
commandbuf[iLen++] = 7;
break;
case 0x0008://停止激活
default:
commandbuf[iLen++] = 9;
break;
}
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
switch (wTransCause)
{
case 0x0006://激活
commandbuf[iLen++] = 7;
commandbuf[iLen++] = 0;
break;
case 0x0008://停止激活
default:
commandbuf[iLen++] = 9;
commandbuf[iLen++] = 0;
break;
}
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 0x14;
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLen);
if (wTransCause != 0x0006)
{
return;
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.23 支持浮点数遥测的传送
//ProvBuban104SendAI(commid, rtumsg, 0);
//====================================================================
if (pPortParam->m_bProvAiType == 13)
{
ProvBuban104SendAIwithFloat(commid, rtumsg, 0);
}
else
{
ProvBuban104SendAI(commid, rtumsg, 0);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ProvBuban104SendDI(commid, rtumsg, 0);
//总召唤结束
ProvMakeBuban104Command(commid, ASK_ALLDATA_END);
pPortParam->m_psBaoHu->DiChange = FALSE;
pPortParam->Initdata = TRUE;
}
*/
void ProvBuban104SendPIData(int commid, RTUMSG * rtumsg)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
int iLen, iCmdType, iGroup;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
iGroup = rtumsg->MsgData[12] & 0x3F;
}
else
{
iGroup = rtumsg->MsgData[15] & 0x3F;
}
// wen 2006.04.03 发布时间97版和2000版组分配不同
if(pPortParam->m_iPublishYear == 1997)
{
//分组召唤
if( iGroup != 1 )
{
//无效或者扩展组号
if(( iGroup <= 0 ) || ( iGroup > 5 ))
{
return;
}
ProvBuban104SendPI(commid, rtumsg, iGroup-1);
return;
}
}
else
{
//分组召唤
if( iGroup != 5 )
{
//无效或者扩展组号
if(( iGroup <= 0 ) || ( iGroup > 5 ))
{
return;
}
ProvBuban104SendPI(commid, rtumsg, iGroup);
return;
}
}
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
//总召唤确认
commandbuf[0] = 0x68;
iLen = 2;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 101;
commandbuf[iLen++] = 0;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 7;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = rtumsg->MsgData[12];
}
else
{
commandbuf[iLen++] = 7;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = rtumsg->MsgData[15];
}
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLen);
ProvBuban104SendPI(commid, rtumsg, 0);
//总召唤结束
commandbuf[0] = 0x68;
iLen = 2;
//commandbuf[1] = 14;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 101;
commandbuf[iLen++] = 0;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 10;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = rtumsg->MsgData[12];
}
else
{
commandbuf[iLen++] = 10;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = rtumsg->MsgData[15];
}
commandbuf[1] = (BYTE)(iLen - 2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLen);
pPortParam->Initdata = TRUE;
}
void ProvBuban104ProcessTime(int commid, RTUMSG *rtumsg)
{
int iLen, iCmdType;
char commandbuf[MAX_POLLCMD_BUF_LEN];
WORD wTransCause;
DAY_TIME sCurTime;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
wTransCause = rtumsg->MsgData[8];
}
else
{
wTransCause = rtumsg->MsgData[8] + (rtumsg->MsgData[9]<<8);
}
//传送原因
switch(wTransCause)
{
case 0x0006://激活(对时)
commandbuf[0] = 0x68;
//commandbuf[1] = 20;
iLen = 2;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 103;
commandbuf[iLen++] = 1;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = 7;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 7;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
GetLocalTimeEx(&sCurTime);
sCurTime.mSec = sCurTime.Sec * 1000 + sCurTime.mSec;
commandbuf[iLen++] = sCurTime.mSec % 256;
commandbuf[iLen++] = sCurTime.mSec / 256;
commandbuf[iLen++] = (u_char)sCurTime.Min;
commandbuf[iLen++] = (u_char)sCurTime.Hour;
commandbuf[iLen++] = (u_char)sCurTime.Day;
commandbuf[iLen++] = (u_char)sCurTime.Month;
commandbuf[iLen++] = (u_char)(sCurTime.Year%100);
commandbuf[1] = (BYTE)(iLen - 2);
if(pPortParam->ProvAckOrNot)
{
iCmdType = INSERT_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char *)commandbuf, iLen);
// 对时
if(1 == pPortParam->m_psBaoHu->CheckTime)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
sCurTime.mSec = rtumsg->MsgData[12] + (rtumsg->MsgData[13] << 8);
sCurTime.Sec = sCurTime.mSec/1000;
sCurTime.mSec = sCurTime.mSec % 1000;
sCurTime.Min = rtumsg->MsgData[14] & 0x3F;
sCurTime.Hour = rtumsg->MsgData[15] & 0x1F;
sCurTime.Day = rtumsg->MsgData[16] & 0x1F;
sCurTime.Month= rtumsg->MsgData[17] & 0x0F;
sCurTime.Year = (rtumsg->MsgData[18] & 0x7F)+2000;
}
else
{
sCurTime.mSec = rtumsg->MsgData[15] + (rtumsg->MsgData[16] << 8);
sCurTime.Sec = sCurTime.mSec/1000;
sCurTime.mSec = sCurTime.mSec % 1000;
sCurTime.Min = rtumsg->MsgData[17] & 0x3F;
sCurTime.Hour = rtumsg->MsgData[18] & 0x1F;
sCurTime.Day = rtumsg->MsgData[19] & 0x1F;
sCurTime.Month= rtumsg->MsgData[20] & 0x0F;
sCurTime.Year = (rtumsg->MsgData[21] & 0x7F)+2000;
}
SetLocalTimeEx(&sCurTime);
}
break;
case 0x07://激活确认
break;
}
}
void ProvBuban104SendPI(int commid, RTUMSG *rtumsg, int iGroupNo)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
DWORD dwStartAddr;
int iLenth, iSendCount=1;
int i, j, iAllDataCount, iSendNum;
int iNo;
int iCmdType;
PI_DEF pntmsg;
PROV_PI_PNT *piprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
if(iGroupNo == 0)//总召唤
{
dwStartAddr = MAX_GROUP_PINUM*iGroupNo + pPortParam->iPiBaseAddr;
iAllDataCount = pPortParam->m_psBaoHu->PiNum;
iSendCount = (iAllDataCount+MAX_104_PINUM-1)/MAX_104_PINUM;
iCmdType = FAST_POLL_CMD;
}
else//分组召唤
{
dwStartAddr = MAX_GROUP_PINUM*(iGroupNo-1);
iAllDataCount = pPortParam->m_psBaoHu->PiNum - dwStartAddr;
dwStartAddr += pPortParam->iPiBaseAddr;
if( iAllDataCount > MAX_GROUP_PINUM)
{
iSendCount = 2;
if((iAllDataCount - MAX_GROUP_PINUM)>0)
iAllDataCount = MAX_GROUP_PINUM;
}
}
piprovptr = (PROV_PI_PNT *)pPortParam->m_psBaoHu->PiPtr;
for(i = 0; i < iSendCount; i++)
{
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 15;
commandbuf[8] = 37+iGroupNo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
iLenth = 10;
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
iLenth = 12;
}
//遥测值
if(iAllDataCount>MAX_104_PINUM)
{
iAllDataCount -= MAX_104_PINUM;
iSendNum = MAX_104_PINUM;
}
else
{
iSendNum = iAllDataCount;
}
for(j = 0; j < iSendNum; j++, dwStartAddr++)
{
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLenth++] = (char)(dwStartAddr & 0x00ff);
commandbuf[iLenth++] = (char)((dwStartAddr & 0xff00)>>8);
}
else
{
commandbuf[iLenth++] = (char)(dwStartAddr & 0x00ff);
commandbuf[iLenth++] = (char)((dwStartAddr & 0xff00)>>8);
commandbuf[iLenth++] = (char)((dwStartAddr & 0xff0000)>>16);
}
iNo = dwStartAddr - pPortParam->iPiBaseAddr;
pntmsg.RawValue = 0;
GetPntMsg(piprovptr[iNo].PortNo, piprovptr[iNo].PntNo,
(void *)&pntmsg, PI_PNT_TYPE, PNT_RAWVALUE);
piprovptr[iNo].ChangeFlag = FALSE;
commandbuf[iLenth++] = (char)(pntmsg.RawValue & 0x000000ff);
commandbuf[iLenth++] = (char)((pntmsg.RawValue & 0x0000ff00)>>8);
commandbuf[iLenth++] = (char)((pntmsg.RawValue & 0x00ff0000)>>16);
commandbuf[iLenth++] = (char)((pntmsg.RawValue & 0xff000000)>>24);
commandbuf[iLenth++] = (char)(j+1);
}
commandbuf[7] = (BYTE)j;
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
}
}
void ProvBuban104SendAI(int commid, RTUMSG *rtumsg, int iGroupNo)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
DWORD dwStartAddr;
int iLenth, iSendCount=1;
int i, j, iAllDataCount, iSendNum;
int iNo, iCmdType;
AI_DEF pntmsg;
PROV_AI_PNT *aiprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
if( iGroupNo == 0 )//总召唤
{
dwStartAddr = MAX_GROUP_AINUM*iGroupNo + pPortParam->iAiBaseAddr;
iAllDataCount = pPortParam->m_psBaoHu->AiNum;
iSendCount = (iAllDataCount+MAX_AINUM-1)/MAX_AINUM;
iCmdType = FAST_POLL_CMD;
}
else//分组召唤
{
dwStartAddr = MAX_GROUP_AINUM*(iGroupNo-1);
iAllDataCount = pPortParam->m_psBaoHu->AiNum - dwStartAddr;
dwStartAddr += pPortParam->iAiBaseAddr;
if(iAllDataCount > MAX_AINUM)
{
iSendCount = 2;
if((iAllDataCount - MAX_GROUP_AINUM) > 0)
{
iAllDataCount = MAX_GROUP_AINUM;
}
}
}
aiprovptr = (PROV_AI_PNT *)pPortParam->m_psBaoHu->AiPtr;
for( i = 0; i < iSendCount; i++ )
{
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 21;
//commandbuf[8] = rtumsg->MsgData[15];
commandbuf[8] = rtumsg->MsgData[8];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
// 信息体地址为2个字节
//*((DWORD*)(&commandbuf[12])) = dwStartAddr;
commandbuf[10] = LOBYTE(LOWORD(dwStartAddr));
commandbuf[11] = HIBYTE(LOWORD(dwStartAddr));
iLenth = 12;
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
// 信息体地址为3个字节
//*((DWORD*)(&commandbuf[12])) = dwStartAddr;
commandbuf[12] = LOBYTE(LOWORD(dwStartAddr));
commandbuf[13] = HIBYTE(LOWORD(dwStartAddr));
commandbuf[14] = LOBYTE(HIWORD(dwStartAddr));
iLenth = 15;
}
//遥测值
if(iAllDataCount > MAX_AINUM)
{
iAllDataCount -= MAX_AINUM;
iSendNum = MAX_AINUM;
}
else
{
iSendNum = iAllDataCount;
}
iNo = dwStartAddr - pPortParam->iAiBaseAddr;
for( j = 0; j < iSendNum; j++ )
{
GetPntMsg(aiprovptr[iNo+j].PortNo, aiprovptr[iNo+j].PntNo,
&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
aiprovptr[iNo+j].ChangeFlag = FALSE;
commandbuf[iLenth++] = (char)(pntmsg.RawValue);
commandbuf[iLenth++] = (char)((pntmsg.RawValue&0xff00)>>8);
}
commandbuf[7] = (BYTE)j;
commandbuf[7] |= 0x80;
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
dwStartAddr += MAX_AINUM;
}
}
void ProvBuban104SendDI(int commid, RTUMSG *rtumsg, int iGroupNo)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
DWORD dwStartAddr;
int iLenth, iSendCount=1;
int i, j, iAllDataCount, iSendNum;
int iNo, iCmdType;
DI_DEF pntmsg;
PROV_DI_PNT *diprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
if(iGroupNo == 0)//总召唤
{
dwStartAddr = MAX_GROUP_DINUM*iGroupNo + pPortParam->iDiBaseAddr;
iAllDataCount = pPortParam->m_psBaoHu->DiNum;
iSendCount = (iAllDataCount+MAX_DINUM-1)/MAX_DINUM;
iCmdType = FAST_POLL_CMD;
}
else//分组召唤
{
dwStartAddr = MAX_GROUP_DINUM*(iGroupNo-1);
iAllDataCount = pPortParam->m_psBaoHu->DiNum - dwStartAddr;
dwStartAddr += pPortParam->iDiBaseAddr;
if( iAllDataCount > MAX_GROUP_DINUM)
{
iAllDataCount = MAX_GROUP_DINUM;
}
}
diprovptr = (PROV_DI_PNT *)pPortParam->m_psBaoHu->DiPtr;
for(i=0; i<iSendCount; i++)
{
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 1;//=3,为双点
commandbuf[8] = rtumsg->MsgData[12];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[10] = LOBYTE(LOWORD(dwStartAddr));
commandbuf[11] = HIBYTE(LOWORD(dwStartAddr));
iLenth = 12;
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
// 信息体地址为3个字节
//*((DWORD*)(&commandbuf[12])) = dwStartAddr;
commandbuf[12] = LOBYTE(LOWORD(dwStartAddr));
commandbuf[13] = HIBYTE(LOWORD(dwStartAddr));
commandbuf[14] = LOBYTE(HIWORD(dwStartAddr));
iLenth = 15;
}
if(iAllDataCount > MAX_DINUM)
{
iAllDataCount -= MAX_DINUM;
iSendNum = MAX_DINUM;
}
else
{
iSendNum = iAllDataCount;
}
iNo = dwStartAddr - pPortParam->iDiBaseAddr;
for( j = 0; j < iSendNum; j++ )
{
GetPntMsg(diprovptr[iNo+j].PortNo, diprovptr[iNo+j].PntNo,
&pntmsg, DI_PNT_TYPE, PNT_STATUS);
diprovptr[iNo+j].ChangeFlag = FALSE;
commandbuf[iLenth++] = pntmsg.Status;
}
commandbuf[7] = (char)j;
commandbuf[7] |= 0x80;
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
dwStartAddr += MAX_DINUM;
}
}
void ProvBuban104SendSoe(int commid)
{
u_char commandbuf[MAX_POLLCMD_BUF_LEN];
BOOL bHaveData = FALSE;
WORD wmSec;
DWORD dwAddr;
int iLenth, iSendCount=1;
int iDataNum, iCmdType;
SOE_DEF soemsg;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(ProvHaveSoeData(commid) <= 0)
{
return;
}
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 2;//单点soe
commandbuf[8] = 3;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
}
bHaveData = TRUE;
iLenth = 12;
iDataNum = 0;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.07.12 修改soe为单个时数据丢失的问题.
/*while(ProvAndDelGetSoeData(commid, &soemsg) > 0)
{
iDataNum++;
dwAddr = (DWORD)(pPortParam->iDiBaseAddr+soemsg.iPntNo);
commandbuf[iLenth++] = LOBYTE(LOWORD(dwAddr));
commandbuf[iLenth++] = HIBYTE(LOWORD(dwAddr));
if(VER_IEC870_5_104 == pPortParam->RtuVersion)
{
commandbuf[iLenth++] = LOBYTE(HIWORD(dwAddr));
}
commandbuf[iLenth++] = soemsg.bStatus;
wmSec = soemsg.SoeTime.mSec + soemsg.SoeTime.Sec*1000;
commandbuf[iLenth++] = LOBYTE(wmSec);
commandbuf[iLenth++] = HIBYTE(wmSec);
commandbuf[iLenth++] = soemsg.SoeTime.Min & 0x3f;
if(iLenth >= 251)
{
break;
}
}*/
//===========================================================
while(ProvHaveSoeData(commid) > 0)
{
ProvAndDelGetSoeData(commid, &soemsg);
iDataNum++;
dwAddr = (DWORD)(pPortParam->iDiBaseAddr+soemsg.iPntNo);
commandbuf[iLenth++] = LOBYTE(LOWORD(dwAddr));
commandbuf[iLenth++] = HIBYTE(LOWORD(dwAddr));
if(VER_IEC870_5_104 == pPortParam->RtuVersion)
{
commandbuf[iLenth++] = LOBYTE(HIWORD(dwAddr));
}
commandbuf[iLenth++] = soemsg.bStatus;
wmSec = soemsg.SoeTime.mSec + soemsg.SoeTime.Sec*1000;
commandbuf[iLenth++] = LOBYTE(wmSec);
commandbuf[iLenth++] = HIBYTE(wmSec);
commandbuf[iLenth++] = soemsg.SoeTime.Min & 0x3f;
if(iLenth >= 248)
{
break;
}
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
commandbuf[7] = (BYTE)iDataNum;
commandbuf[1] = (BYTE)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
}
void ProvBuban104YkYtData(int commid, RTUMSG *rtumsg)
{
PROV_DI_PNT *diprovptr;
DI_DEF *diptr;
int ykytcommid, provpnt;
int ykytpnt, ykytop, step;
BYTE bYkOperate;
YKYT_PARAM YkYtParam;
BUBAN104PORTPARAM *pPortParam;
char szbuf[128];
ykytpnt = 0;
ykytop = 3;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
bYkOperate = rtumsg->MsgData[12];
ykytpnt = rtumsg->MsgData[10] + (rtumsg->MsgData[11]<<8);
}
else
{
bYkOperate = rtumsg->MsgData[15];
// wen 2005.11.27 修改最高字节信息体地址不做判断
//ykytpnt = rtumsg->MsgData[12] + (rtumsg->MsgData[13]<<8) + (rtumsg->MsgData[14]<<16);
ykytpnt = rtumsg->MsgData[12] + (rtumsg->MsgData[13]<<8);
}
if(rtumsg->MsgData[8] == 8)
{
step = STEP_YKYT_CANCEL;
}
else
{
if(bYkOperate & 0x80) //选择返校
{
step = STEP_YKYT_SELECT;
}
else
{
step = STEP_YKYT_EXEC;
}
}
if(ShmGetDispYkYtFlag())
{
#ifdef _WIN32
printf("TIP_(%04d): commid =%d recv ykyt select.\n", _getpid(), commid);
#else
printf("TIP_(%04d): commid =%d recv ykyt select.\n", getpid(), commid);
#endif
}
ykytpnt -= pPortParam->iYkBaseAddr;
ykytpnt += 1;
if(rtumsg->MsgData[6] == 45)
{
// ykytop == 1 控合, == 2 控分
ykytop = ((bYkOperate & 0x03) == 1) ? 1 : 2;
}
else if(rtumsg->MsgData[6] == 46)
{
ykytop = ((bYkOperate & 0x03) == 2) ? 1 : 2;
}
else // == 47
{
//step = STEP_YKYT_CANCEL;
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, 3, step);
return;
}
provpnt = FindProvPntFromYkYtPnt(commid, ykytpnt, pPortParam->m_psBaoHu);
if(provpnt < 0) // 控点号错
{
sprintf(szbuf, "WARN(%04d): 控点错误.\n", _getpid());
DebugPrint(szbuf);
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, 3, step);
}
else
{
diprovptr = (PROV_DI_PNT *)pPortParam->m_psBaoHu->DiPtr;
ykytcommid = diprovptr[provpnt].PortNo;
if(!SioParam[ykytcommid].m_psBaoHu)
{
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, 3, step);
return;
}
if(!SioParam[ykytcommid].m_psBaoHu->DiPtr)
{
sprintf(szbuf, "WARN(%04d): 没有控点m_psBaoHu->DiPtr=NULL.\n", _getpid());
DebugPrint(szbuf);
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, 3, step);
return;
}
diptr = (DI_DEF *)SioParam[ykytcommid].m_psBaoHu->DiPtr;
// 如果对应点没有控点或者控点不相等
if(!diptr[diprovptr[provpnt].PntNo].CtrlEnable)
{
sprintf(szbuf, "WARN(%04d): 对应点没有控点或者控点不相等.\n", _getpid());
DebugPrint(szbuf);
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, 3, step);
return;
}
if(STEP_YKYT_SELECT == step)
{
if(STEP_YKYT_SELECT == SioParam[ykytcommid].m_psBaoHu->ProvYkYtMsg.m_iYkYtStep)
{
if(!ProvPortYkYtIsTimeOut(ykytcommid, &SioParam[ykytcommid].m_psBaoHu->ProvYkYtMsg))
{
sprintf(szbuf, "WARN(%04d): 超时 failed.\n", _getpid());
DebugPrint(szbuf);
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, 3, step);
return;
}
}
}
SioParam[ykytcommid].m_psBaoHu->ProvYkYtMsg.m_iProvPntIdx = provpnt;
SioParam[ykytcommid].m_psBaoHu->ProvYkYtMsg.m_iProvPortIdx = commid;
SioParam[ykytcommid].m_psBaoHu->ProvYkYtMsg.m_iProvYkYtPointIdx = ykytpnt;
SioParam[ykytcommid].m_psBaoHu->ProvYkYtMsg.m_iYkYtPointIdx = diptr[diprovptr[provpnt].PntNo].ControlNo;
SioParam[ykytcommid].m_psBaoHu->ProvYkYtMsg.m_iYkYtOperate = ykytop;
// buf[0] --- 端口号(=commid)
// buf[1]
// buf[2]
// buf[3]
// buf[4] --- 控点号
// buf[5]
// buf[6]
// buf[7]
// buf[8] --- 操作类型(遥控:1=选择,2=执行,3=取消,7=直控;
// 遥调:4=选择,5=执行,6=取消,8=急停)
// buf[9] --- 控制状态(1=分到合2=合到分)
// (最高位为1时为返校命令, 1=成功, 0=失败)
//buf[0] = ykytcommid & 0xFF;
//buf[1] = (ykytcommid & 0xFF00) >> 8;
//buf[2] = (ykytcommid & 0xFF0000) >> 16;
//buf[3] = (ykytcommid & 0xFF000000) >> 24;
//buf[4] = diptr[diprovptr[provpnt].PntNo].ControlNo & 0xFF;
//buf[5] = (diptr[diprovptr[provpnt].PntNo].ControlNo & 0xFF00) >> 8;
//buf[6] = (diptr[diprovptr[provpnt].PntNo].ControlNo & 0xFF0000) >> 16;
//buf[7] = (diptr[diprovptr[provpnt].PntNo].ControlNo & 0xFF000000) >> 24;
//buf[8] = STEP_YKYT_SELECT;
//buf[9] = ykytop;
//SendYkYtCommand(ykytcommid, (char *)buf, 10); // 发送遥控遥调命令
YkYtParam.m_iYkYtOperate = ykytop;
YkYtParam.m_iYkYtPnt = diptr[diprovptr[provpnt].PntNo].ControlNo;
YkYtParam.m_iYkYtStep = step;
YkYtParam.m_iYkYtUpDown = YKYT_SEND_DOWN;
SendYkYtCommand2(ykytcommid, &YkYtParam);
if(STEP_YKYT_EXEC == step)
{
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, ykytop, step);
MakeProvBuban104YkYtAckMsg(commid, ykytpnt, ykytop, STEP_YKYT_NOEXEC);
}
}
}
void MakeProvBuban104YkYtAckMsg(int commid, int pnt, int op, int step)
{
int iCount, ykpoint, iLen;
char commandbuf[MAX_POLLCMD_BUF_LEN];
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
memset(commandbuf, 0, sizeof(commandbuf));
iCount = 4;
commandbuf[0] = 0x68;
commandbuf[1] = 14;
switch(pPortParam->YkMode)
{
case CONTROL_SINGAL: // 单点控制
commandbuf[6] = 45;
break;
case CONTROL_DOUBLE: // 双点控制
case CONTROL_DIRECT: // 直接控制
commandbuf[6] = 46; // 47;
break;
}
commandbuf[7] = 1;
//commandbuf[8];// 传送原因
iLen = 9;
ykpoint = (pnt-1) + pPortParam->iYkBaseAddr;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = LOBYTE(LOWORD(ykpoint));
commandbuf[iLen++] = HIBYTE(LOWORD(ykpoint));
}
else
{
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = LOBYTE(LOWORD(ykpoint));
commandbuf[iLen++] = HIBYTE(LOWORD(ykpoint));
commandbuf[iLen++] = LOBYTE(HIWORD(ykpoint));
}
switch(step)
{
case STEP_YKYT_SELECT: // 选择
commandbuf[8] = 7;
commandbuf[iLen] = 0xfc;
break;
case STEP_YKYT_EXEC: // 执行
commandbuf[8] = 7;
commandbuf[iLen] = 0x7c;
break;
case STEP_YKYT_CANCEL: // 撤销
commandbuf[8] = 9;
commandbuf[iLen] = 0xfc;
break;
default:// 结束帧
commandbuf[8] = 10;
commandbuf[iLen] = 0;
break;
}
// DCS/RCS
switch(op)
{
case 1: // 选择合
if(CONTROL_SINGAL == pPortParam->YkMode)
{
commandbuf[iLen] |= 1;
}
else
{
commandbuf[iLen] |= 2;
}
break;
case 2: // 选择分
if(CONTROL_SINGAL != pPortParam->YkMode)
{
commandbuf[iLen] |= 1;
}
break;
case 3: // 选择失败
default:
commandbuf[8] |= 0x40;
break;
}
iLen++;
PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, (char *)commandbuf, iLen);
if(ShmGetDispYkYtFlag())
{
printf("TIP_(%04d): commid =%d ykytpnt=%d, op=%d checked.\n", _getpid(), commid, pnt, op);
}
}
void ProvBuban104SendClass1(int commid)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
DWORD dwStartAddr;
int iLenth, iSendCount=1;
int j, iDataNum, iCmdType;
DI_DEF pntmsg;
PROV_DI_PNT *diprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(!pPortParam->m_psBaoHu->DiChange)
{
return;
}
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
// wen 2005.01.15 修改数据信息体起始地址
dwStartAddr = pPortParam->iDiBaseAddr;
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 1;//=3,为双点
commandbuf[8] = 3;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
iLenth = 10;
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
iLenth = 12;
}
diprovptr = (PROV_DI_PNT *)pPortParam->m_psBaoHu->DiPtr;
for(j = 0, iDataNum = 0; j<pPortParam->m_psBaoHu->DiNum; j++)
{
if(diprovptr[j].ChangeFlag)
{
iDataNum++;
commandbuf[iLenth++] = LOBYTE(LOWORD(dwStartAddr+j));
commandbuf[iLenth++] = HIBYTE(LOWORD(dwStartAddr+j));
if(VER_IEC870_5_104 == pPortParam->RtuVersion)
{
commandbuf[iLenth++] = LOBYTE(HIWORD(dwStartAddr+j));
}
GetPntMsg(diprovptr[j].PortNo, diprovptr[j].PntNo,
&pntmsg, DI_PNT_TYPE, PNT_STATUS);
diprovptr[j].ChangeFlag = FALSE;
commandbuf[iLenth++] = pntmsg.Status;
if(iLenth > 256)
{
break;
}
}
}
if(j >= pPortParam->m_psBaoHu->DiNum)
{
pPortParam->m_psBaoHu->DiChange = FALSE;
}
commandbuf[7] = (char)iDataNum;
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
}
void ProvBuban104SendClass2(int commid)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
BOOL bHaveData = FALSE;
DWORD dwStartAddr;
int iLenth, iSendCount=1;
int j, iDataNum, iCmdType;
AI_DEF pntmsg;
PROV_AI_PNT *aiprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(!pPortParam->m_psBaoHu->AiChange)
{
return;
}
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 21;
commandbuf[8] = 3;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
iLenth = 10;
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
iLenth = 12;
}
// wen 2005.01.15 修改数据信息体起始地址
dwStartAddr = pPortParam->iAiBaseAddr;
commandbuf[6] = 21;
//遥测值
aiprovptr = (PROV_AI_PNT *)pPortParam->m_psBaoHu->AiPtr;
for(j = 0, iDataNum = 0; j < pPortParam->m_psBaoHu->AiNum; j++)
{
if(aiprovptr[j].ChangeFlag)
{
iDataNum++;
bHaveData = TRUE;
commandbuf[iLenth++] = LOBYTE(LOWORD(dwStartAddr+j));
commandbuf[iLenth++] = HIBYTE(LOWORD(dwStartAddr+j));
if(VER_IEC870_5_104 == pPortParam->RtuVersion)
{
commandbuf[iLenth++] = LOBYTE(HIWORD(dwStartAddr+j));
}
GetPntMsg(aiprovptr[j].PortNo, aiprovptr[j].PntNo,
&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
aiprovptr[j].ChangeFlag = FALSE;
commandbuf[iLenth++] = (char)(pntmsg.RawValue);
commandbuf[iLenth++] = (char)((pntmsg.RawValue&0xff00)>>8);
if(iLenth >= 251)
{
break;
}
}
}
if(j >= pPortParam->m_psBaoHu->AiNum)
{
pPortParam->m_psBaoHu->AiChange = false;
}
if(bHaveData)
{
commandbuf[7] = (char)iDataNum;
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
}
}
void ProvMakeBuban104Command(int commid, u_char cmdidx)
{
int iLen;
char commandbuf[MAX_POLLCMD_BUF_LEN];
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
switch(cmdidx)
{
case ASK_SECOND_DATA: // 召唤2级数据
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.03.23 支持浮点数遥测的传送
//ProvBuban104SendClass2(commid);
//====================================================================
if(pPortParam->m_bProvAiType == 13)
{
ProvBuban104SendClass2withFloat(commid);
}
else
{
ProvBuban104SendClass2(commid);
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
break;
case ASK_FIRST_DATA: // 召唤1级数据
ProvBuban104SendClass1(commid);
break;
case ASK_ALLDATA_END: // 总召唤结束帧
commandbuf[0] = 0x68;
//commandbuf[iLen++] = 14;
iLen = 2;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 100;
commandbuf[iLen++] = 1;
commandbuf[iLen++] = 10;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
else
{
commandbuf[iLen++] = 0;
commandbuf[iLen++] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = HIBYTE(pPortParam->wLinkAddr);
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
commandbuf[iLen++] = 0;
}
commandbuf[iLen++] = 0x14;
commandbuf[1] = (BYTE)(iLen - 2);
if(pPortParam->ProvAckOrNot)
{
PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, (char *)commandbuf, iLen);
}
else
{
PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char *)commandbuf, iLen);
}
pPortParam->Initdata = TRUE;
break;
case RTU_TIME: // 时间同步
break;
case ASK_DI_DATA: // 召唤2级数据YX
break;
case ASK_AI_DATA: // 召唤2级数据YC
break;
case ASK_PI_DATA: // 召唤2级数据YM
break;
case ASK_PI: //召唤电度量
break;
case ASK_ALL_DATA: // 召唤初始化数据
break;
}
}
/*
int j // 对应数据库数据点号
int *igno // 组号
int* iItemNo 条目号
DAY_TIME* sCurTime 时间
float* pfValue 数据值
typedef struct
{
WORD Year;
u_char Month;
u_char Day;
u_char WeekDay;
u_char MonthDay;
u_char Hour;
u_char Min;
u_char Sec;
u_char reserved;
WORD mSec;
} DAY_TIME;
返回值1成功取值 -1取值失败
*/
int GetAIPntMsg(int j, int *igno, int* iItemNo, DAY_TIME* sCurTime, float* pfValue, int *iaddr)
{
*igno = 1;
*iItemNo = 1;
*iaddr = 1;
sCurTime->Hour = 12;
sCurTime->Min = 30;
sCurTime->Month = 11;
sCurTime->MonthDay = 1;
sCurTime->mSec = 600;
sCurTime->Sec = 26;
sCurTime->Year = 2023;
*pfValue = 36.6;
return 1;
}
void ProvBuban104SendAIwithFloat(int commid, RTUMSG *rtumsg, int iGroupNo)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
//DWORD dwStartAddr;
int iLenth, iSendCount=1, iaddr0=1, iaddr1=1;
int i, j, iAllDataCount, iSendNum,flag;
int iNo, iCmdType, igno,iItemNo;
float *pfValue;
DAY_TIME sCurTime;
AI_DEF pntmsg;
PROV_AI_PNT *aiprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
iCmdType = FAST_POLL_CMD;
if( iGroupNo == 0 )//总召唤
{
//dwStartAddr = MAX_GROUP_AINUM*iGroupNo + pPortParam->iAiBaseAddr;
iAllDataCount = pPortParam->m_psBaoHu->AiNum;
iCmdType = FAST_POLL_CMD;
}
//aiprovptr = (PROV_AI_PNT *)pPortParam->m_psBaoHu->AiPtr;
for( i = 0; i < iAllDataCount; /*i++*/ )
{
memset(commandbuf, 0, sizeof(commandbuf));
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 10; // 类型标识TYP
commandbuf[7] = 0x81; // 可变结构限定词VSQ
commandbuf[8] = 0x2A; // 传送原因COT
commandbuf[9] = 0; //
commandbuf[10] = 0; // 应用服务数据单元公共地址
commandbuf[11] = 254; // 功能类型FUN
commandbuf[12] = 241; // 信息序号INF
commandbuf[13] = 0; // 返回信息标识码RII
//遥测值
if(iAllDataCount-i > MAX_FLOATAINUM)
{
iSendNum = MAX_FLOATAINUM;
commandbuf[14] = (iSendNum & 0x80); // 通用分类数据集数目NGD
}
else
{
iSendNum = iAllDataCount-i;
commandbuf[14] = iSendNum; // 通用分类数据集数目NGD
}
iNo = i;
iLenth = 15;
for( j = 0; j < iSendNum; j++ )
{
pfValue = (float *)&commandbuf[iLenth+14];
flag = GetAIPntMsg(j+iNo, (unsigned int*)&igno, (unsigned int*)&iItemNo, &sCurTime, pfValue, (unsigned int*)&iaddr1);
if (0 == flag)
break;
if (-1 == flag)
continue;
if (iaddr1 == iaddr0)
;
else
{
iaddr0 = iaddr1;
if (15 == iLenth)
;
else
break;
}
commandbuf[iLenth] = igno;
commandbuf[iLenth++] = iItemNo;
commandbuf[iLenth++] = 1; // 描述类别KOD实际值
commandbuf[iLenth++] = 7; // 数据类型
commandbuf[iLenth++] = 4; // 数据宽度
commandbuf[iLenth++] = 4; // 数据数目
commandbuf[iLenth++] = sCurTime.mSec % 256;
commandbuf[iLenth++] = sCurTime.mSec / 256;
commandbuf[iLenth++] = (u_char)sCurTime.Min;
commandbuf[iLenth++] = (u_char)sCurTime.Hour;
commandbuf[iLenth++] = (u_char)sCurTime.Day;
commandbuf[iLenth++] = (u_char)sCurTime.Month;
commandbuf[iLenth++] = (u_char)(sCurTime.Year % 100);
iLenth += 12;
//*pfValue = SequenceHostToRtufloat((float)((int)pntmsg.RawValue));
//iLenth += sizeof(float);
//commandbuf[iLenth++] = 0;
}
if (15 == iLenth)
break;
commandbuf[9] = (u_char)iaddr0; //
commandbuf[10] = (u_char)(iaddr0 >> 8); // 应用服务数据单元公共地址
i += j;
if (flag == -1)
{
i = iAllDataCount;
}
if(i >= iAllDataCount)
{
commandbuf[14] = j; // 通用分类数据集数目NGD
}
else
commandbuf[14] = (j & 0x80); // 通用分类数据集数目NGD
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
}
}
/*void ProvBuban104SendAIwithFloat(int commid, RTUMSG *rtumsg, int iGroupNo)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
DWORD dwStartAddr;
int iLenth, iSendCount=1;
int i, j, iAllDataCount, iSendNum;
int iNo, iCmdType;
float *pfValue;
AI_DEF pntmsg;
PROV_AI_PNT *aiprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
if( iGroupNo == 0 )//总召唤
{
dwStartAddr = MAX_GROUP_AINUM*iGroupNo + pPortParam->iAiBaseAddr;
iAllDataCount = pPortParam->m_psBaoHu->AiNum;
iSendCount = (iAllDataCount+MAX_FLOATAINUM-1)/MAX_FLOATAINUM;
iCmdType = FAST_POLL_CMD;
}
else//分组召唤
{
dwStartAddr = MAX_GROUP_AINUM*(iGroupNo-1);
iAllDataCount = pPortParam->m_psBaoHu->AiNum - dwStartAddr;
dwStartAddr += pPortParam->iAiBaseAddr;
if(iAllDataCount > MAX_FLOATAINUM)
{
iSendCount = 2;
if((iAllDataCount - MAX_GROUP_AINUM) > 0)
{
iAllDataCount = MAX_GROUP_AINUM;
}
}
}
aiprovptr = (PROV_AI_PNT *)pPortParam->m_psBaoHu->AiPtr;
for( i = 0; i < iSendCount; i++ )
{
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 13;
//commandbuf[8] = rtumsg->MsgData[15];
commandbuf[8] = rtumsg->MsgData[8];
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
// 信息体地址为2个字节
//*((DWORD*)(&commandbuf[12])) = dwStartAddr;
commandbuf[10] = LOBYTE(LOWORD(dwStartAddr));
commandbuf[11] = HIBYTE(LOWORD(dwStartAddr));
iLenth = 12;
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
// 信息体地址为3个字节
//*((DWORD*)(&commandbuf[12])) = dwStartAddr;
commandbuf[12] = LOBYTE(LOWORD(dwStartAddr));
commandbuf[13] = HIBYTE(LOWORD(dwStartAddr));
commandbuf[14] = LOBYTE(HIWORD(dwStartAddr));
iLenth = 15;
}
//遥测值
if(iAllDataCount > MAX_FLOATAINUM)
{
iAllDataCount -= MAX_FLOATAINUM;
iSendNum = MAX_FLOATAINUM;
}
else
{
iSendNum = iAllDataCount;
}
iNo = dwStartAddr - pPortParam->iAiBaseAddr;
for( j = 0; j < iSendNum; j++ )
{
GetPntMsg(aiprovptr[iNo+j].PortNo, aiprovptr[iNo+j].PntNo,
&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
aiprovptr[iNo+j].ChangeFlag = FALSE;
pfValue = (float *)&commandbuf[iLenth];
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.07.13 修改负数的传送
//*pfValue = SequenceHostToRtufloat((float)pntmsg.RawValue);
//============================================================
*pfValue = SequenceHostToRtufloat((float)((int)pntmsg.RawValue));
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iLenth += sizeof(float);
commandbuf[iLenth++] = 0;
}
commandbuf[7] = (BYTE)j;
commandbuf[7] |= 0x80;
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
dwStartAddr += MAX_FLOATAINUM;
}
}
*/
void ProvBuban104SendClass2withFloat(int commid)
{
char commandbuf[MAX_POLLCMD_BUF_LEN];
BOOL bHaveData = FALSE;
DWORD dwStartAddr;
int iLenth, iSendCount=1;
int j, iDataNum, iCmdType;
float *pfValue;
AI_DEF pntmsg;
PROV_AI_PNT *aiprovptr;
BUBAN104PORTPARAM *pPortParam;
pPortParam = (BUBAN104PORTPARAM *)SioParam[commid].ExtInfo;
if(!pPortParam->m_psBaoHu->AiChange)
{
return;
}
if(pPortParam->ProvAckOrNot)
{
iCmdType = NORMAL_POLL_CMD;
}
else
{
iCmdType = FAST_POLL_CMD;
}
commandbuf[0] = 0x68;
commandbuf[2] = 0;
commandbuf[3] = 0;
commandbuf[4] = 0;
commandbuf[5] = 0;
commandbuf[6] = 21;
commandbuf[8] = 3;
if(VER_BUBAN_104 == pPortParam->RtuVersion)
{
commandbuf[9] = LOBYTE(pPortParam->wLinkAddr);
iLenth = 10;
}
else
{
commandbuf[9] = 0;
commandbuf[10] = LOBYTE(pPortParam->wLinkAddr);
commandbuf[11] = HIBYTE(pPortParam->wLinkAddr);
iLenth = 12;
}
// wen 2005.01.15 修改数据信息体起始地址
dwStartAddr = pPortParam->iAiBaseAddr;
commandbuf[6] = 13;
//遥测值
aiprovptr = (PROV_AI_PNT *)pPortParam->m_psBaoHu->AiPtr;
for(j = 0, iDataNum = 0; j < pPortParam->m_psBaoHu->AiNum; j++)
{
if(aiprovptr[j].ChangeFlag)
{
iDataNum++;
bHaveData = TRUE;
commandbuf[iLenth++] = LOBYTE(LOWORD(dwStartAddr+j));
commandbuf[iLenth++] = HIBYTE(LOWORD(dwStartAddr+j));
if(VER_IEC870_5_104 == pPortParam->RtuVersion)
{
commandbuf[iLenth++] = LOBYTE(HIWORD(dwStartAddr+j));
}
GetPntMsg(aiprovptr[j].PortNo, aiprovptr[j].PntNo,
&pntmsg, AI_PNT_TYPE, PNT_RAWVALUE);
aiprovptr[j].ChangeFlag = FALSE;
pfValue = (float *)&commandbuf[iLenth];
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.07.13 修改负数的传送
//*pfValue = SequenceHostToRtufloat((float)pntmsg.RawValue);
//============================================================
*pfValue = SequenceHostToRtufloat((float)((int)pntmsg.RawValue));
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
iLenth += sizeof(float);
commandbuf[iLenth++] = 0;
//4.bug_1.2.3_20060807_3/bug_2.0.1_20060807_4 104规约不能转发第二个端口的遥测数据
//不能操作251(原来使用255可能导致发送报文长度超过255一个字节不能表述)
//另外命令缓冲区应当使用char而不应当使用u_char
if(iLenth >= 251)
{
break;
}
}
}
if(j >= pPortParam->m_psBaoHu->AiNum)
{
pPortParam->m_psBaoHu->AiChange = false;
}
if(bHaveData)
{
commandbuf[7] = (char)iDataNum;
commandbuf[1] = (char)(iLenth-2);
PutPollCmdToBuf(commid, iCmdType, 0, (char *)commandbuf, iLenth);
}
}
//===========================转发数据处理结束===============================//
//===========================数据处理函数结束===============================//