//*************************************************************** //* buban104.cpp * //* aaawen 2005.09.14 * //*************************************************************** //_DEBUG_MSG_,_OS_WINDOWS_DEBUG_ #ifndef _WIN32 #include #include #include "commport.h" // #include "baohulib/serialport.h" #else #include "commport.h" #include "udpcomm.h" #include "display.h" #endif #include #include #include #include "buban101.h" #include "buban104.h" #include "scadaprotect.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; iCmdTime[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; for(i=0; im_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; iCmdTime[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; } 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); //总召唤结束 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; iMsgData[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; jm_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) { *igno = 1; *iItemNo = 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; 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 > MAX_FLOATAINUM) { iSendNum = MAX_FLOATAINUM; commandbuf[14] = (iSendNum & 0x80); // 通用分类数据集数目NGD } else { iSendNum = iAllDataCount; commandbuf[14] = iSendNum; // 通用分类数据集数目NGD } iNo = i; iLenth = 15; for( j = iNo; j < iNo+iSendNum; j++ ) { pfValue = (float *)&commandbuf[iLenth+14]; flag = GetAIPntMsg(j, &igno, &iItemNo, &sCurTime, pfValue); 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 (flag = -1) i = iAllDataCount; else i += iSendNum; 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); } } //===========================转发数据处理结束===============================// //===========================数据处理函数结束===============================//