//*************************************************************** //* buban103.cpp * //* aaawen 2004.10.19 * //*************************************************************** //_DEBUG_MSG_,_OS_WINDOWS_DEBUG_ /*#ifdef OS_LINUX #include "baohulib/commport.h" #include "baohulib/serialport.h" #else*/ #include "common.h" #include "commport.h" #include "udpcomm.h" #include "display.h" //#endif #include #include #include #ifndef _WIN32 #include #include #endif #include "buban103.h" #include "scadaprotect.h" //typedef int i_32; //typedef unsigned long u_32; 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]; /*! \brief 最大链路数量 */ const int MAX_LINK_NUM=30; /*! \brief 每条链路最大装置数量 */ const int MAX_DEV_NUM_EACH_LINK=12; /* enum Param_Type { PARAM_NO=0, PARAM_LINK, PARAM_DEV, PARAM_YC, PARAM_YX, PARAM_YM, PARAM_YK, PARAM_SYNCTIME, PARAM_ASDU10 }; */ const char *gpStrBuban103Cmd[BUBAN103_TIMER_CMD_NUM] = { "时间同步过程", "总查询过程", "电度量查询", "通用分类数据模拟量查询", "通用分类数据状态量查询" }; /*! 组织结构:链路(间隔)+装置 */ const char *gpStrBuban103ConfigInfo[] = { "*******部颁103规约开始*******", " ", " ; 轮询指令配置,所有命令召唤周期均以秒为单位。", " 时间同步过程 = 0", " 总查询过程 = 0", " 电度量查询 = 0", " 通用分类数据模拟量查询 = 0", " 通用分类数据状态量查询 = 0", " ", " 链路数量=1", " ; 缺省值=1,只支持一条链路,否则为实际的链路数量", " ", " 链路1模板文件名称 = 103template.csv", " ... ...", " 链路n模板文件名称 = 103template.csv", " ; 其中,n=配置信息中的(链路数量)对应的值", " ", " 上送遥信变位=0", " ;仅针对于转发,缺省情况下不上送", " ", "*******部颁103规约结束*******", "", // 结束标志(中间不能含有该空字符串) }; //******************************************************************** //* 读取配置函数 * //*参数:int commid : 端口号 * //******************************************************************** void Buban103ReadConfig(int commid) { int i, j, iDevId; char szSection[128], entry[256], szbuf[128]; char szPortConfig[256], szDir[256], szTemplate[256]; pBUBAN103PORTPARAM 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(BUBAN103PORTPARAM)); Buban103DispMalloc(commid, sizeof(BUBAN103PORTPARAM)); if(!SioParam[commid].ExtInfo) { #ifdef _WIN32 sprintf(szbuf, "WARN(%04d): commid_%02d ExtInfo=malloc(%d) failed.\n", _getpid(), commid, sizeof(BUBAN103PORTPARAM)); #else sprintf(szbuf, "WARN(%04d): commid_%02d ExtInfo=malloc(%d) failed.\n", getpid(), commid, sizeof(BUBAN103PORTPARAM)); #endif DebugPrint(szbuf); return; } memset(SioParam[commid].ExtInfo, 0, sizeof(BUBAN103PORTPARAM)); pPortParam = (pBUBAN103PORTPARAM)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) { if(atoi(szbuf) == 0) { pPortParam->m_bSendChangeDi = FALSE; } else { pPortParam->m_bSendChangeDi = TRUE; } } // wen 2004.07.26 增加保护装置的状态处理 if(GetPrivateProString(szSection, "链路数量", "1", szbuf, 120, szPortConfig) > 0) { pPortParam->m_iLinkNum = atoi(szbuf); } if(pPortParam->m_iLinkNum <= 1) { pPortParam->m_iLinkNum = 1; } if(pPortParam->m_iLinkNum > MAX_LINK_NUM) { pPortParam->m_iLinkNum = MAX_LINK_NUM; } pPortParam->m_psLink = (BUBAN103LINKDEF *)HEAP_MALLOC(sizeof(BUBAN103LINKDEF)*pPortParam->m_iLinkNum); Buban103DispMalloc(commid, sizeof(BUBAN103LINKDEF)*pPortParam->m_iLinkNum); memset((void *)pPortParam->m_psLink, 0, sizeof(BUBAN103LINKDEF)*pPortParam->m_iLinkNum); // 假定所有链路的配置相同 //for(i=0; im_iLinkNum; i++) i=0; { // 轮询指令配置 for(j=0; jm_psLink[i].m_sArrayCmdTime[j].m_iCmdTimerConst = (int)(atof(szbuf)*1000/TIMER_CNT); if(pPortParam->m_psLink[i].m_sArrayCmdTime[j].m_iCmdTimerConst > 5) { pPortParam->m_psLink[i].m_sArrayCmdTime[j].m_iCmdTimerCnt = pPortParam->m_psLink[i].m_sArrayCmdTime[j].m_iCmdTimerConst - 5; } } //GetPrivateProString(szSection, "超时时间", "20", szbuf, 120, szPortConfig); //pPortParam->m_psLink[i].m_u32TimeOutConst = (int)(atof(szbuf)*1000/TIMER_CNT); pPortParam->m_psLink[i].m_u32TimeOutConst = pPortParam->m_psBaoHu->RetryTime; } for(i=1; im_iLinkNum; i++) { for(j=0; jm_psLink[i].m_sArrayCmdTime[j].m_iCmdTimerConst = pPortParam->m_psLink[0].m_sArrayCmdTime[j].m_iCmdTimerConst; pPortParam->m_psLink[i].m_sArrayCmdTime[j].m_iCmdTimerCnt = pPortParam->m_psLink[0].m_sArrayCmdTime[j].m_iCmdTimerCnt; } pPortParam->m_psLink[i].m_u32TimeOutConst = pPortParam->m_psLink[0].m_u32TimeOutConst; } for(i=0; im_iLinkNum; i++) { sprintf(entry, "链路%d模板文件名称", i+1); GetPrivateProString(szSection, entry, "103template.csv", pPortParam->m_psLink[i].m_chArrayTempletFileName, sizeof(pPortParam->m_psLink[i].m_chArrayTempletFileName)-1, szPortConfig); #ifdef OS_LINUX sprintf(szTemplate, "inf/%s", pPortParam->m_psLink[i].m_chArrayTempletFileName); #else sprintf(szTemplate, "%s/inf/%s", IniFilePath, pPortParam->m_psLink[i].m_chArrayTempletFileName); #endif // 判断是主站还是子站 //InitBuban103InfoFromTempletFile(commid, szTemplate, &pPortParam->m_psLink[i]); //InitBuban103InfoFromDat(commid, &pPortParam->m_psLink[i]); if(PROTOCOL_SLAVE == pPortParam->m_psBaoHu->PortType) { // wen 2005.06.22 初始化错误退出,以前配置争取的仍然可以正确运行 //InitBuban103InfoFromTempletFileEx(commid, szTemplate, &pPortParam->m_psLink[i], FALSE); if(FALSE == InitBuban103InfoFromTempletFileEx(commid, szTemplate, &pPortParam->m_psLink[i], FALSE)) { pPortParam->m_iLinkNum = i; break; } } else { // wen 2005.06.22 初始化错误退出,以前配置争取的仍然可以正确运行 //InitBuban103InfoFromTempletFileEx(commid, szTemplate, &pPortParam->m_psLink[i], TRUE); //InitBuban103InfoFromDat(commid, &pPortParam->m_psLink[i]); if(FALSE == InitBuban103InfoFromTempletFileEx(commid, szTemplate, &pPortParam->m_psLink[i], TRUE)) { pPortParam->m_iLinkNum = i; break; } else { InitBuban103InfoFromDat(commid, &pPortParam->m_psLink[i]); } } } // wen 2005.05.17 重新计算数据库点的位置 ReCalcDevPntStart(commid, pPortParam); InitBuban103CmdBuf(commid, pPortParam); // 初始化单向链表,链表最大数量为10个 for(i=0; im_iLinkNum; i++) { if(pPortParam->m_psLink[i].m_psProvDev == NULL) { break; } for(j=0; jm_psLink[i].m_iDevNum; j++) { iDevId = (commid<<16) + (i<<8) + j; SingleListInitEx(&pPortParam->m_psLink[i].m_psProvDev[j].m_sBaoHuData, 10, iDevId); } } //Buban103DispConfig(commid, pPortParam); } //******************************************************************** //* 读取端口数据函数 * //*参数:int commid : 端口号 * //* u_char buf : 数据源缓冲区指针 * //* int len : 数据源长度 * //******************************************************************** void Buban103RecvData(int commid, u_char *buf, int len)// 规约读数据处理 { int i; pBUBAN103PORTPARAM pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif if(!IsExtInfoPtr(commid)) return; pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; for(i=0; im_psBaoHu->m_iRevStatus) { case 0:// 0x10 / 0x68 pPortParam->m_iRecvLen = 0; if(buf[i] == 0x10) { pPortParam->m_psBaoHu->m_iRevStatus = 4; pPortParam->m_psBaoHu->m_iNeedRevLength = 4; pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; } else if(buf[i] == 0x68) { pPortParam->m_psBaoHu->m_iRevStatus++; pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; } else { // 错误数据增加 SioParam[commid].ErrMsgNum++; } break; case 1: case 2: pPortParam->m_psBaoHu->m_iRevStatus++; pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; break; case 3:// 长度计算 if(buf[i] == 0x68) { if(pPortParam->m_achRecvBuf[1] != pPortParam->m_achRecvBuf[2]) { pPortParam->m_psBaoHu->m_iRevStatus=1; SioParam[commid].ErrMsgNum += pPortParam->m_iRecvLen; Buban103ProcessData(commid, pPortParam, FALSE); pPortParam->m_iRecvLen = 0; pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; } else { pPortParam->m_psBaoHu->m_iRevStatus++; pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_psBaoHu->m_iNeedRevLength = (BYTE)(pPortParam->m_achRecvBuf[1])+2; } } else { pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; pPortParam->m_psBaoHu->m_iRevStatus=5; } break; case 4:// 正确接收数据 pPortParam->m_psBaoHu->m_iNeedRevLength--; pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if(pPortParam->m_psBaoHu->m_iNeedRevLength > 0) break; if(buf[i] != 0x16) { pPortParam->m_psBaoHu->m_iRevStatus=5; break; } if(Buban103Check(pPortParam->m_achRecvBuf, pPortParam->m_iRecvLen) == TRUE) { Buban103ProcessData(commid, pPortParam, TRUE); pPortParam->m_psBaoHu->m_iRevStatus = 0; pPortParam->m_psBaoHu->RevCmdFlag = 1; } else { SioParam[commid].ErrMsgNum += pPortParam->m_iRecvLen; SioParam[commid].LostSyncCnt++; pPortParam->m_psBaoHu->m_iRevStatus = 5; } #ifndef OS_LINUX if((GetCurPort() == commid) && IsRealDataDisp()) { WatchDataPutDispBuf(commid, SDS_SIO_RECV_DATA, (BYTE *)pPortParam->m_achRecvBuf, pPortParam->m_iRecvLen); } #endif break; case 5:// 错误接收数据 default: pPortParam->m_achRecvBuf[pPortParam->m_iRecvLen++] = buf[i]; if(buf[i] == 0x16) { #ifndef OS_LINUX // wen 2004.11.22 增加显示 if((GetCurPort() == commid) && IsRealDataDisp()) { WatchDataPutDispBuf(commid, SDS_SIO_RECV_DATA, (BYTE *)pPortParam->m_achRecvBuf, pPortParam->m_iRecvLen); } #endif Buban103ProcessData(commid, pPortParam, FALSE); SioParam[commid].ErrMsgNum += pPortParam->m_iRecvLen; pPortParam->m_psBaoHu->m_iRevStatus = 0; pPortParam->m_iRecvLen = 0; } else { if(pPortParam->m_iRecvLen > 200) { #ifndef OS_LINUX // wen 2004.11.22 增加显示 if((GetCurPort() == commid) && IsRealDataDisp()) { WatchDataPutDispBuf(commid, SDS_SIO_RECV_DATA, (BYTE *)pPortParam->m_achRecvBuf, pPortParam->m_iRecvLen); } #endif Buban103ProcessData(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 Buban103Timer(int commid) { BUBAN103PORTPARAM *pPortParam; BUBAN103LINKDEF *pLinkParam; if(IsExtInfoPtr(commid) == FALSE) { return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; // wen 2005.06.22 链路数据为0直接退出 if(pPortParam->m_iLinkNum <= 0) { return; } // 如果为转发端口,则不进行轮询指令的生成。 if(PROTOCOL_SLAVE != pPortParam->m_psBaoHu->PortType) { pLinkParam = &pPortParam->m_psLink[pPortParam->m_iLinkIdx]; if(IsDevLinkOk(pLinkParam, pPortParam->m_iLinkIdx) == TRUE) { if(pLinkParam->m_uchLinkAddr != 0xFF) { if(IsLinkTimeOut(pLinkParam, 0) == TRUE) { InitBuban103CmdBuf(commid, pPortParam); } } else { if(IsLinkTimeOut(pLinkParam, pPortParam->m_iLinkIdx) == TRUE) { InitBuban103DevCmdBuf(pLinkParam, pLinkParam->m_iDevIdx); } } } //Buban103FindNextCmd(commid); if(TRUE == Buban103FindNextCmdEx(commid)) { Buban103CalcNextDev(commid, FALSE); } } Buban103SendCmdFormPollCmdBuf(commid); } //******************************************************************** //* 遥控遥调数据处理函数 * //*参数:int commid : 端口号 * //* u_char buf : 数据源缓冲区指针 * //* int len : 数据源长度 * //******************************************************************** void Buban103YkYtProcess(int commid, u_char *buf, int len) // 遥控遥调处理 { int iDirect,portno, ykytpnt; u_char asdu, dco; CASDU20 bCAsdu20; YKYT_PARAM YkYtParam; DEVDEF *pDevParam; DEVADDRPARAM sAddrParam; BUBAN103PORTPARAM *pPortParam; char szbuf[128]; // 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; //ykytpnt--; // 返校信息(反馈信号) if(iDirect) { if((buf[8] == STEP_YKYT_SELECT) || (buf[8] == STEP_YKYT_SELECT+3)) { YkYtParam.m_iYkYtPnt = ykytpnt; YkYtParam.m_iYkYtStep = buf[8]; YkYtParam.m_iYkYtUpDown = YKYT_SEND_UP; YkYtParam.m_iYkYtOperate = buf[9]; SendYkYtCommand2(commid, &YkYtParam); #ifdef _WIN32 sprintf(szbuf, "WARN(%04d): 转发遥控预令反校成功.\n", _getpid()); #else sprintf(szbuf, "WARN(%04d): 转发遥控预令反校成功.\n", getpid()); #endif DebugPrint(szbuf); return; } Buban103ProvMakeYkYtCommand(commid, buf, len); return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; // 返校失败 // 条件: 端口链路状态为假或者未找到合适的控点 if(FALSE == FindProtectDevFromYkYtPnt(pPortParam, &sAddrParam, ykytpnt)) { YkYtParam.m_iYkYtPnt = ykytpnt; YkYtParam.m_iYkYtStep = buf[8]; YkYtParam.m_iYkYtUpDown = YKYT_SEND_UP; YkYtParam.m_iYkYtOperate = 3; SendYkYtCommand2(commid, &YkYtParam); return; } else if(FALSE == IsDevLinkOk(&pPortParam->m_psLink[sAddrParam.m_iLinkIdx], sAddrParam.m_iDevIdx)) { YkYtParam.m_iYkYtPnt = ykytpnt; YkYtParam.m_iYkYtStep = buf[8]; YkYtParam.m_iYkYtUpDown = YKYT_SEND_UP; YkYtParam.m_iYkYtOperate = 3; SendYkYtCommand2(commid, &YkYtParam); return; } pDevParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_psDev[sAddrParam.m_iDevIdx]; asdu = pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Asdu; // 操作类型 switch(buf[8]) { case STEP_YKYT_SELECT: case STEP_YKYT_SELECT+3://选择 if((C_DC_NA_3 != asdu) && (C_RC_NA_3 != asdu)) {// 直控方式 YkYtParam.m_iYkYtPnt = ykytpnt; YkYtParam.m_iYkYtStep = buf[8]; YkYtParam.m_iYkYtUpDown = YKYT_SEND_UP; YkYtParam.m_iYkYtOperate = buf[9]; SendYkYtCommand2(commid, &YkYtParam); } else { ykytpnt -= pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo; bCAsdu20.nTYP = asdu; //类型标识 bCAsdu20.nVSQ = 0x01; //可变结构限定词 bCAsdu20.nCOT = 0x0c; //传送原因 bCAsdu20.nADDR = pDevParam->m_sDevParam.m_u8DevAddr; //应用服务数据单元公共地址 bCAsdu20.nFUN = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Fun;//功能类型 bCAsdu20.nINF = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Inf;//信息序号 if(buf[9] == 2) { bCAsdu20.nDCO = 0x81; //控制断路器(控分) } else { bCAsdu20.nDCO = 0x82; //控制断路器(控合) } bCAsdu20.nRII = (BYTE)sAddrParam.m_iLinkIdx;//返回信息标识符 if(pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr == 255) { MakeBuban103LinkCommand(commid, pDevParam->m_sDevParam.m_u8DevAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } else { MakeBuban103LinkCommand(commid, \ pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } YkYtParam.m_iYkYtPnt = ykytpnt; YkYtParam.m_iYkYtStep = buf[8]; YkYtParam.m_iYkYtUpDown = YKYT_SEND_UP; YkYtParam.m_iYkYtOperate = buf[9]; SendYkYtCommand2(commid, &YkYtParam); } break; case STEP_YKYT_EXEC: case STEP_YKYT_EXEC+3://执行 //pDevParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_psDev[sAddrParam.m_iDevIdx]; ykytpnt -= pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo; // 遥控遥调不仅仅只用asdu20,还有asdu64/65等 yizhonghu 20060803 //bCAsdu20.nTYP = 20; //类型标识 bCAsdu20.nTYP = asdu; //类型标识 bCAsdu20.nVSQ = 0x81; //可变结构限定词 if(asdu == 20) { bCAsdu20.nCOT = 0x14; //传送原因 bCAsdu20.nVSQ = 0x81; //可变结构限定词 } else { bCAsdu20.nCOT = 0x0c; //传送原因 bCAsdu20.nVSQ = 0x01; //可变结构限定词 } bCAsdu20.nADDR = pDevParam->m_sDevParam.m_u8DevAddr; //应用服务数据单元公共地址 bCAsdu20.nFUN = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Fun;//功能类型 bCAsdu20.nINF = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Inf;//信息序号 dco = 0; if(buf[9] == 2) { bCAsdu20.nDCO = (1 | dco); //控制断路器(控分) } else { bCAsdu20.nDCO = (2 | dco); //控制断路器(控合) } bCAsdu20.nRII = (BYTE)sAddrParam.m_iLinkIdx;//返回信息标识符 if(pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr == 255) { MakeBuban103LinkCommand(commid, pDevParam->m_sDevParam.m_u8DevAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } else { MakeBuban103LinkCommand(commid, \ pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } break; case STEP_YKYT_CANCEL: case STEP_YKYT_CANCEL+3://取消 //pDevParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_psDev[sAddrParam.m_iDevIdx]; ykytpnt -= pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo; bCAsdu20.nTYP = asdu; //类型标识 bCAsdu20.nVSQ = 0x01; //可变结构限定词 bCAsdu20.nCOT = 0x0c; //传送原因 bCAsdu20.nADDR = pDevParam->m_sDevParam.m_u8DevAddr; //应用服务数据单元公共地址 bCAsdu20.nFUN = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Fun;//功能类型 bCAsdu20.nINF = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Inf;//信息序号 dco = 0xc0; if(buf[9] == 2) { bCAsdu20.nDCO = (1 | dco); //控制断路器(控分) } else { bCAsdu20.nDCO = (2 | dco); //控制断路器(控合) } bCAsdu20.nRII = (BYTE)sAddrParam.m_iLinkIdx;//返回信息标识符 if(pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr == 255) { MakeBuban103LinkCommand(commid, pDevParam->m_sDevParam.m_u8DevAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } else { MakeBuban103LinkCommand(commid, \ pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } break; case STEP_YKYT_DIRECT:// 直控 break; case STEP_YKYT_STOP:// 急停 //pDevParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_psDev[sAddrParam.m_iDevIdx]; ykytpnt -= pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo; bCAsdu20.nTYP = asdu; //类型标识 bCAsdu20.nVSQ = 0x01; //可变结构限定词 bCAsdu20.nCOT = 0x0c; //传送原因 bCAsdu20.nADDR = pDevParam->m_sDevParam.m_u8DevAddr; //应用服务数据单元公共地址 bCAsdu20.nFUN = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Fun;//功能类型 bCAsdu20.nINF = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Inf;//信息序号 dco = 0x00; bCAsdu20.nDCO = (3 | dco); //遥调急停 bCAsdu20.nRII = (BYTE)sAddrParam.m_iLinkIdx;//返回信息标识符 if(pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr == 255) { MakeBuban103LinkCommand(commid, pDevParam->m_sDevParam.m_u8DevAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } else { MakeBuban103LinkCommand(commid, \ pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), INSERT_POLL_CMD); } break; default: break; } } //******************************************************************** //* 系统下发对时函数 * //*参数:int commid : 端口号 * //******************************************************************** void Buban103SendSystemTime(int commid) // 系统对时 { int i, j; CMDPARAM sCmdParam; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; char szbuf[128]; if(IsExtInfoPtr(commid) == FALSE) { return; } pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; if(2 != pPortParam->m_psBaoHu->CheckTime) { return; } sprintf(szbuf, "port=%d,CheckTime=%d",commid+1, pPortParam->m_psBaoHu->CheckTime); DebugPrint(szbuf); // 针对所有的装置发送对时命令 for(i=0; im_iLinkNum; i++) { pLinkParam = &pPortParam->m_psLink[i]; for(j=0; jm_iDevNum; j++) { pDevParam = &pLinkParam->m_psDev[j]; sCmdParam.m_sDevAddr.m_uchLinkAddr = pLinkParam->m_uchLinkAddr; sCmdParam.m_sDevAddr.m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; sCmdParam.m_uchFun = (u_char)pDevParam->m_sDevParam.m_sSyncTimeInfo.m_u8Fun; sCmdParam.m_uchInf = (u_char)pDevParam->m_sDevParam.m_sSyncTimeInfo.m_u8Inf; sCmdParam.m_uchRII = pDevParam->m_u8RII; MakeTimeSyn_CAsdu6(commid, &sCmdParam); } } } //******************************************************************** //* 系统退出时规约处理函数 * //*参数:int commid : 端口号 * //******************************************************************** void Buban103Exit(int commid) { int i, j, k; DBORIENTATION *pDB; GROUPDEF *pGroup; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if(SioParam[commid].ExtInfo == NULL) { return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; if(pPortParam->m_psLink == NULL) { return; } for(i=0; im_iLinkNum; i++) { pLinkParam = (BUBAN103LINKDEF *)(&pPortParam->m_psLink[i]); if(pLinkParam->m_psDev != NULL) { for(j=0; jm_iDevNum; j++) { // ai for(k=0; km_psDev[j].m_sDevParam.m_sAiDBOrientation[k]; if(pDB->m_psDataInfo != NULL) { HEAP_FREE(pDB->m_psDataInfo); pDB->m_psDataInfo = NULL; } } // di pDB = &pLinkParam->m_psDev[j].m_sDevParam.m_sDiDBOrientation; if(pDB->m_psDataInfo != NULL) { HEAP_FREE(pDB->m_psDataInfo); pDB->m_psDataInfo = NULL; } // pi pDB = &pLinkParam->m_psDev[j].m_sDevParam.m_sPiDBOrientation; if(pDB->m_psDataInfo != NULL) { HEAP_FREE(pDB->m_psDataInfo); pDB->m_psDataInfo = NULL; } // yk pDB = &pLinkParam->m_psDev[j].m_sDevParam.m_sYkDBOrientation; if(pDB->m_psDataInfo != NULL) { HEAP_FREE(pDB->m_psDataInfo); pDB->m_psDataInfo = NULL; } // group for(k=0; km_psDev[j].m_sDevParam.m_iCfgGroupNum; k++) { pGroup = &pLinkParam->m_psDev[j].m_sDevParam.m_saGroupDef[k]; if(pGroup->m_psDataInfo != NULL) { HEAP_FREE(pGroup->m_psDataInfo); pGroup->m_psDataInfo = NULL; } if(pGroup->m_psEventInfo != NULL) { HEAP_FREE(pGroup->m_psEventInfo); pGroup->m_psEventInfo = NULL; } if(pGroup->m_pu8DataLen != NULL) { HEAP_FREE(pGroup->m_pu8DataLen); pGroup->m_pu8DataLen = NULL; } if(pGroup->m_pu8DataType != NULL) { HEAP_FREE(pGroup->m_pu8DataType); pGroup->m_pu8DataType = NULL; } if(pGroup->m_pu8GIN != NULL) { HEAP_FREE(pGroup->m_pu8GIN); pGroup->m_pu8GIN = NULL; } } if(pLinkParam->m_psDev[j].m_sDisturbanceParam.m_pshValue != NULL) { HEAP_FREE(pLinkParam->m_psDev[j].m_sDisturbanceParam.m_pshValue); pLinkParam->m_psDev[j].m_sDisturbanceParam.m_pshValue = NULL; } } HEAP_FREE(pLinkParam->m_psDev); pLinkParam->m_psDev = NULL; } if(pLinkParam->m_psProvDev != NULL) { for(j=0; jm_iDevNum; j++) { if(pLinkParam->m_psProvDev[j].m_sYxInfo.m_psDataInfo != NULL) { HEAP_FREE(pLinkParam->m_psProvDev[j].m_sYxInfo.m_psDataInfo); pLinkParam->m_psProvDev[j].m_sYxInfo.m_psDataInfo = NULL; } if(pLinkParam->m_psProvDev[j].m_sYcInfo.m_psDataInfo != NULL) { HEAP_FREE(pLinkParam->m_psProvDev[j].m_sYcInfo.m_psDataInfo); pLinkParam->m_psProvDev[j].m_sYcInfo.m_psDataInfo = NULL; } if(pLinkParam->m_psProvDev[j].m_sYmInfo.m_psDataInfo != NULL) { HEAP_FREE(pLinkParam->m_psProvDev[j].m_sYmInfo.m_psDataInfo); pLinkParam->m_psProvDev[j].m_sYmInfo.m_psDataInfo = NULL; } SingleListDelAllData(&pLinkParam->m_psProvDev[j].m_sBaoHuData); } HEAP_FREE(pLinkParam->m_psProvDev); pLinkParam->m_psProvDev = NULL; } HEAP_FREE(pLinkParam->m_pbLinkOk); pLinkParam->m_pbLinkOk = NULL; HEAP_FREE(pLinkParam->m_pu32LinkOkCnt); pLinkParam->m_pu32LinkOkCnt = NULL; HEAP_FREE(pLinkParam->m_pu8CtlByte); pLinkParam->m_pu8CtlByte = NULL; } HEAP_FREE(pPortParam->m_psLink); pPortParam->m_psLink = NULL; } // 该函数用来驱动由转发端口下发到实际装置的保护命令 void Buban103BaoHuCmdProcess(int commid, RTUMSG *rtumsg, BOOL bUpData) { int iProvAddr; PROVDEVDEF *pProvDevParam; DEVADDRPARAM sAddrParam; BUBAN103PORTPARAM *pPortParam; char szbuf[128]; if((MSGTYPE_BAOHU_SCADACMD == rtumsg->MsgType) || (MSGTYPE_BAOHU_SCADADATA == rtumsg->MsgType)) { sprintf(szbuf, "commid%d 收到定值指令", commid); DebugPrint(szbuf); Buban103ScadaProtocolExchange(commid, rtumsg); return; } if(FALSE == GetPortParamPtr(commid, &pPortParam)) { return; } switch(rtumsg->MsgData[0]) { case 0x68:// 长帧 iProvAddr = rtumsg->MsgData[9]; break; case 0x10:// 短帧 default: iProvAddr = -1; break; } if(iProvAddr < 0) { return; } if(FALSE == FindProtectDevFromProvAddr(pPortParam, &sAddrParam, iProvAddr)) { return; } // 上行数据 //if(MSGTYPE_BAOHU_103DATA == rtumsg->MsgType) if(bUpData == TRUE) { // ??? 在这里存储保护数据(应该只有asdu10的数据类型) pProvDevParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_psProvDev[sAddrParam.m_iDevIdx]; SingleListAddData(&pProvDevParam->m_sBaoHuData, rtumsg->MsgData, rtumsg->MsgLen); return; } // 要进行转发数据的判断,需要在这里增加数据格式的存储,来确定转发数据的来源 pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_iBaoHuCommid = rtumsg->PortIdx; memcpy((void *)&pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_sRealAddrParam, (void *)&sAddrParam, sizeof(DEVADDRPARAM)); GetLocalTimeEx(&pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_sBaoHuCmdStartTime); pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_iBaoHuMsgType = MSGTYPE_BAOHU_103CMD; // 修改要下发的指令的地址 if(sAddrParam.m_uchLinkAddr != 0xFF) { rtumsg->MsgData[5] = sAddrParam.m_uchLinkAddr; } else { rtumsg->MsgData[5] = sAddrParam.m_uchCommAddr; } rtumsg->MsgData[9] = sAddrParam.m_uchCommAddr; PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, (char *)rtumsg->MsgData, rtumsg->MsgLen); } int Buban103GetBaohuDataBase(int commid, int iProvAddr, GROUPDEF **ppBaoHuDB) { DEVDEF *pDevParam; DEVADDRPARAM sAddrParam; BUBAN103PORTPARAM *pPortParam; if(FALSE == GetPortParamPtr(commid, &pPortParam)) { return 0; } if(FALSE == FindProtectDevFromProvAddr(pPortParam, &sAddrParam, iProvAddr)) { return 0; } pDevParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_psDev[sAddrParam.m_iDevIdx]; *ppBaoHuDB = pDevParam->m_sDevParam.m_saGroupDef; return pDevParam->m_sDevParam.m_iCfgGroupNum; } /////////////////////////通用函数接口结束/////////////////////////////// void Buban103ProvMakeYkYtCommand(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=合到分, 0=失败) // (最高位为1时,为返校命令) // 在转发遥控数据点中,只保留了要转发的控点号,实际的端口号应该是该转发点的端口 // 该转发点并没有指定虚拟的转发控点,则控点和转发点的点号一致。 int ykytpnt; u_char asdu; CASDU20 bCAsdu20; DEVDEF *pDevParam; DEVADDRPARAM sAddrParam; BUBAN103PORTPARAM *pPortParam; if((buf[8] != STEP_YKYT_EXEC)\ && (buf[8] != STEP_YKYT_EXEC+3) && (buf[8] != STEP_YKYT_DIRECT)) { return; } if(IsExtInfoPtr(commid) == FALSE) { return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; ykytpnt = buf[4]+buf[5]*256+buf[6]*65536+buf[7]*16777216; if(FALSE == FindProtectDevFromYkYtPnt(pPortParam, &sAddrParam, ykytpnt)) { return; } pDevParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_psDev[sAddrParam.m_iDevIdx]; ykytpnt -= pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo; asdu = pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Asdu; // 遥控的类型标识不仅仅有20还有64/65 yizhonghu 20060803 //bCAsdu20.nTYP = 20; //类型标识 bCAsdu20.nTYP = asdu; //类型标识 if(asdu != 20) { bCAsdu20.nVSQ = 0x01; //可变结构限定词 bCAsdu20.nCOT = 0x0c; //传送原因 } else { bCAsdu20.nVSQ = 0x81; //可变结构限定词 bCAsdu20.nCOT = 0x14; //传送原因 } bCAsdu20.nADDR = pDevParam->m_sDevParam.m_u8DevAddr; //应用服务数据单元公共地址 bCAsdu20.nFUN = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Fun;//功能类型 bCAsdu20.nINF = (u_char)pDevParam->m_sDevParam.m_sYkDBOrientation.m_psDataInfo[ykytpnt].m_u8Inf;//信息序号 if(buf[9] == 2) { bCAsdu20.nDCO = 1; //控制断路器(控分) } else { bCAsdu20.nDCO = 2; //控制断路器(控合) } bCAsdu20.nRII = pDevParam->m_u8RII;//返回信息标识符 if(pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr == 255) { MakeBuban103LinkCommand(commid, pDevParam->m_sDevParam.m_u8DevAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), FAST_POLL_CMD); } else { MakeBuban103LinkCommand(commid, \ pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_uchLinkAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu20, sizeof(CASDU20), FAST_POLL_CMD); } } //******************************************************************** //* 初始化装置参数函数 * //*参数:DEVPARAMDEF *psDevParam : 装置参数指针 * //******************************************************************** void SetProtectDevStatus(BUBAN103LINKDEF *psLinkParam, int iDevNo, BOOL bStatus) { DI_DEF pntmsg; DEVDEF *psDevDef; if(psLinkParam->m_psDev == NULL) { return; } if(bStatus == TRUE) { pntmsg.Status = 1; } else { pntmsg.Status = 0; } psDevDef = &psLinkParam->m_psDev[iDevNo]; if(psLinkParam->m_iInputStationOfDevStatus > 0) { SetPntMsg(psLinkParam->m_iInputStationOfDevStatus-1, psLinkParam->m_iInputStartPntOfDevStatus+iDevNo, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); } } //===========================以下为装置初始化函数===================== //******************************************************************** //* 初始化装置参数函数 * //*参数:DEVPARAMDEF *psDevParam : 装置参数指针 * //******************************************************************** void InitDevParam(DEVPARAMDEF *psDevParam) { psDevParam->m_u8SCN = 0; psDevParam->m_sSyncTimeInfo.m_u8Fun = 255; psDevParam->m_u8CPUNo = 1; psDevParam->m_u8FixNo = 1; } //******************************************************************** //* 读取模板文件信息函数 * //*参数:int commid : 端口号 * //* char *ptrTemplate : 模板文件名称 * //* BUBAN103LINKDEF *psLink : 要配置端口的参数指针 * //******************************************************************** BOOL InitBuban103InfoFromTempletFile(int commid, char *ptrTemplate, BUBAN103LINKDEF *psLink) { int i; char *ptr; char szBuf[512]; BOOL bVal; HDSFILE hFile; enum Param_Type ParamType; hFile = DSOpenFileEx(ptrTemplate); if(hFile == NULL) { // test sprintf(szBuf, "open<%s> is failed.", ptrTemplate); DebugPrint(szBuf); return FALSE; } // test sprintf(szBuf, "open<%s> is succeed.", ptrTemplate); DebugPrint(szBuf); ParamType = PARAM_NO; while(TRUE) { ptr = DSfgets(szBuf, sizeof(szBuf), hFile); if(!ptr) { break; } // test //DebugPrint(szBuf); if(strstr(ptr, "链路描述") != NULL) { //处理链路参数 ParamType = PARAM_LINK; } else if(strstr(ptr, "设备描述") != NULL) { ParamType = PARAM_DEV; } else if(PARAM_NO == ParamType) { continue; } switch(ParamType) { case PARAM_LINK: bVal = GetLinkParamFromTemplateFile(commid, hFile, psLink); if(TRUE == bVal) { if(psLink->m_iDevNum > 0) { psLink->m_psDev = (DEVDEF *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(DEVDEF)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(DEVDEF)); if(psLink->m_psDev == NULL) { psLink->m_iDevNum = 0; } memset((void *)psLink->m_psDev, 0, psLink->m_iDevNum*sizeof(DEVDEF)); if(psLink->m_uchLinkAddr == 0xFF) { psLink->m_pbLinkOk = (BOOL *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(BOOL)); memset((void *)psLink->m_pbLinkOk, 0, psLink->m_iDevNum*sizeof(BOOL)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(BOOL)); psLink->m_pu32LinkOkCnt = (u_32 *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(u_32)); memset((void *)psLink->m_pu32LinkOkCnt, 0, psLink->m_iDevNum*sizeof(u_32)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(u_32)); psLink->m_pu8CtlByte = (BYTE *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(u_char)); memset(psLink->m_pu8CtlByte, 0, psLink->m_iDevNum*sizeof(u_char)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(u_char)); } else { psLink->m_pbLinkOk = (BOOL *)HEAP_MALLOC(sizeof(BOOL)); psLink->m_pbLinkOk[0] = FALSE; Buban103DispMalloc(commid, sizeof(BOOL)); psLink->m_pu32LinkOkCnt = (u_32 *)HEAP_MALLOC(sizeof(u_32)); psLink->m_pu32LinkOkCnt[0] = 0; Buban103DispMalloc(commid, sizeof(u_32)); psLink->m_pu8CtlByte = (BYTE *)HEAP_MALLOC(sizeof(u_char)); psLink->m_pu8CtlByte[0] = 0; Buban103DispMalloc(commid, sizeof(u_char)); } for(i=0; im_iDevNum; i++) { InitDevParam(&psLink->m_psDev[i].m_sDevParam); } } } break; case PARAM_DEV: bVal = GetDevParamFromTemplateFile(commid, hFile, psLink); break; default: break; } } DSCloseFile(hFile); return TRUE; } BOOL InitBuban103InfoFromTempletFileEx(int commid, char *ptrTemplate, BUBAN103LINKDEF *psLink, BOOL bMaster) { char *ptr; char szBuf[512]; BOOL bVal; HDSFILE hFile; enum Param_Type ParamType; if(bMaster == TRUE) { return InitBuban103InfoFromTempletFile(commid, ptrTemplate, psLink); } hFile = DSOpenFile(ptrTemplate); if(hFile == NULL) { // test sprintf(szBuf, "open<%s> is failed.", ptrTemplate); DebugPrint(szBuf); return FALSE; } // test sprintf(szBuf, "open<%s> is succeed.", ptrTemplate); DebugPrint(szBuf); ParamType = PARAM_NO; while(TRUE) { ptr = DSfgets(szBuf, sizeof(szBuf), hFile); if(!ptr) { break; } // test //DebugPrint(szBuf); if(strstr(ptr, "链路描述") != NULL) { //处理链路参数 ParamType = PARAM_LINK; } else if(strstr(ptr, "设备描述") != NULL) { ParamType = PARAM_DEV; } else if(PARAM_NO == ParamType) { continue; } switch(ParamType) { case PARAM_LINK: bVal = GetLinkParamFromTemplateFile(commid, hFile, psLink); if(TRUE == bVal) { if(psLink->m_iDevNum > 0) { psLink->m_psProvDev = (PROVDEVDEF *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(PROVDEVDEF)); if(psLink->m_psProvDev == NULL) { psLink->m_iDevNum = 0; } memset((void *)psLink->m_psProvDev, 0, psLink->m_iDevNum*sizeof(PROVDEVDEF)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(PROVDEVDEF)); if(psLink->m_uchLinkAddr == 0xFF) { psLink->m_pbLinkOk = (BOOL *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(BOOL)); memset((void *)psLink->m_pbLinkOk, 0, psLink->m_iDevNum*sizeof(BOOL)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(BOOL)); psLink->m_pu32LinkOkCnt = (u_32 *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(u_32)); memset((void *)psLink->m_pu32LinkOkCnt, 0, psLink->m_iDevNum*sizeof(u_32)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(u_32)); psLink->m_pu8CtlByte = (BYTE *)HEAP_MALLOC(psLink->m_iDevNum*sizeof(u_char)); memset(psLink->m_pu8CtlByte, 0, psLink->m_iDevNum*sizeof(u_char)); Buban103DispMalloc(commid, psLink->m_iDevNum*sizeof(u_char)); } else { psLink->m_pbLinkOk = (BOOL *)HEAP_MALLOC(sizeof(BOOL)); psLink->m_pbLinkOk[0] = FALSE; Buban103DispMalloc(commid, sizeof(BOOL)); psLink->m_pu32LinkOkCnt = (u_32 *)HEAP_MALLOC(sizeof(u_32)); psLink->m_pu32LinkOkCnt[0] = 0; Buban103DispMalloc(commid, sizeof(u_32)); psLink->m_pu8CtlByte = (BYTE *)HEAP_MALLOC(sizeof(u_char)); psLink->m_pu8CtlByte[0] = 0; Buban103DispMalloc(commid, sizeof(u_char)); } } } break; case PARAM_DEV: bVal = GetProvDevParamFromTemplateFile(commid, hFile, psLink); break; default: break; } } DSCloseFile(hFile); return TRUE; } BOOL GetParamItem(char *pSour, char **ppDest) { if(pSour == NULL) { return FALSE; } *ppDest = strstr(pSour, ","); if(*ppDest == NULL) { return FALSE; } return TRUE; } BOOL GetParamItemEx(char *pSour, char **ppDest, const char *pSplit) { if(pSour == NULL) { return FALSE; } *ppDest = strstr(pSour, pSplit); if(*ppDest == NULL) { return FALSE; } return TRUE; } BOOL GetLinkParamFromTemplateFile(int commid, HDSFILE hFile,\ BUBAN103LINKDEF *psLink) { char *ptr, *ptrSour, *ptrDest; char szBuf[512]; int i, ilen; BOOL bRetVal; ptr = DSfgets(szBuf, sizeof(szBuf), hFile); if(ptr == NULL) { return FALSE; } ptrSour = szBuf; if(strstr(ptrSour, "LINK") == NULL) { return FALSE; } // test //DebugPrint(szBuf); bRetVal = TRUE; for(i=0; i<13; i++) { if(GetParamItem(ptrSour, &ptrDest) == FALSE) { bRetVal = FALSE; break; } *ptrDest = 0; ilen = strlen(ptrSour); switch(i) { case 0:// 链路描述 if(ilen > 0) { if(ilen >= sizeof(psLink->m_szLinkName)) { ilen = sizeof(psLink->m_szLinkName)-1; } memcpy(psLink->m_szLinkName, ptrSour, ilen); psLink->m_szLinkName[ilen] = 0; } break; case 1:// 链路标识 break; case 2:// 链路地址 if(ilen > 0) { psLink->m_uchLinkAddr = (BYTE)atoi(ptrSour); } else { psLink->m_uchLinkAddr = 255; } break; case 3:// 装置数量 if(ilen > 0) { psLink->m_iDevNum = (BYTE)atoi(ptrSour); } break; case 4:// 备用 break; case 5:// 备用 break; case 6:// 地址偏移 if(ilen > 0) { psLink->m_iProvAddrOffset = atoi(ptrSour); } break; case 7:// 数据类型 break; case 8:// 写入数据库站号 if(ilen > 0) { psLink->m_iInputStationOfDevStatus = atoi(ptrSour); } break; case 9:// 写入数据库起始点号 if(ilen > 0) { psLink->m_iInputStartPntOfDevStatus = atoi(ptrSour); } break; case 10:// 是否判断ASDU号 if(ilen > 0) { psLink->m_iJudgeAsduNo = atoi(ptrSour); } break; case 11:// 是否处理扰动数据 if(ilen > 0) { psLink->m_iDisTransDataProcess = atoi(ptrSour); } break; case 12:// 是否屏蔽未配置事件 if(ilen > 0) { psLink->m_iMaskNoMatchString = atoi(ptrSour); } break; case 13:// 一类数据问询次数(该项不可达,在循环外处理) if(ilen > 0) { psLink->m_iQueryNum_CLASS1_Const = atoi(ptrSour); } else { psLink->m_iQueryNum_CLASS1_Const = 1; } break; } ptrSour = ptrDest+1; } // 最后一项 if(bRetVal == TRUE) { // 一类数据问询次数 if(strlen(ptrSour) > 0) { psLink->m_iQueryNum_CLASS1_Const = atoi(ptrSour); } else { psLink->m_iQueryNum_CLASS1_Const = 1; } } return bRetVal; } BOOL GetDevParamFromTemplateFile(int commid, HDSFILE hFile,\ BUBAN103LINKDEF *psLink) { char *ptr, *ptrSour, *ptrDest; char szBuf[512]; int i, j, ilen, iNum; int iAiNum, iAiStart, iDiStart; int iPiStart, iYkStart, iPntNo; BOOL bRetVal; enum Param_Type ParamType; iAiStart = 0; iDiStart = 0; iPiStart = 0; iYkStart = 0; iAiNum = 0; ParamType = PARAM_NO; bRetVal = TRUE; for(i=0; im_iDevNum;) { ptr = DSfgets(szBuf, sizeof(szBuf), hFile); if(ptr == NULL) { break; } // test //DebugPrint(szBuf); if(strstr(ptr, "设备描述") != NULL) { i++; iAiNum = 0; ParamType = PARAM_NO; continue; } if(strstr(ptr, "链路描述") != NULL) { break; } ptrSour = ptr; for(j=0; j<8; j++) { if(GetParamItem(ptrSour, &ptrDest) == FALSE) { bRetVal = FALSE; break; } *ptrDest = 0; ilen = strlen(ptrSour); switch(j) { case 0:// 设备描述 if(ParamType != PARAM_NO) { break; } if(ilen > 0) { if(ilen >= sizeof(psLink->m_psDev[i].m_sDevParam.m_szDevName)) { ilen = sizeof(psLink->m_psDev[i].m_sDevParam.m_szDevName)-1; } memcpy(psLink->m_psDev[i].m_sDevParam.m_szDevName, ptrSour, ilen); psLink->m_psDev[i].m_sDevParam.m_szDevName[ilen] = 0; } break; case 1:// 设备型号 if(ParamType != PARAM_NO) { break; } if(ilen > 0) { if(ilen >= sizeof(psLink->m_psDev[i].m_sDevParam.m_szType)) { ilen = sizeof(psLink->m_psDev[i].m_sDevParam.m_szType)-1; } memcpy(psLink->m_psDev[i].m_sDevParam.m_szType, ptrSour, ilen); psLink->m_psDev[i].m_sDevParam.m_szType[ilen] = 0; } else { strcpy(psLink->m_psDev[i].m_sDevParam.m_szType, "dat103"); } break; case 2:// 设备地址 if(ParamType != PARAM_NO) { break; } if(ilen > 0) { psLink->m_psDev[i].m_sDevParam.m_u8DevAddr = (BYTE)atoi(ptrSour); } break; case 3:// 转发地址 if(PARAM_NO != ParamType) { break; } if(ilen > 0) { psLink->m_psDev[i].m_sDevParam.m_iProvAddr = atoi(ptrSour); } break; case 4:// 备用 break; case 5:// 备用 break; case 6:// 数量 if(ilen > 0) { iNum = atoi(ptrSour); } break; case 7:// 数据类型 if(iNum <= 0) { break; } if(ilen > 0) { if(strcmp(ptrSour, "YC") == 0) { ParamType = PARAM_YC; psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_iStnNo = commid+1; psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_iStartPntNo = iAiStart; psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_iPntNum = iNum; if(NULL != psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_psDataInfo) { HEAP_FREE(psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_psDataInfo); } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_psDataInfo // = (DBINFO *)HEAP_MALLOC(sizeof(DBINFO)*iNum); //memset((void *)psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_psDataInfo, // 0, sizeof(DBINFO)*iNum); //======================================================================================== psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_psDataInfo = (DBINFO *)HEAP_MALLOC(sizeof(DBINFO)); memset((void *)psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum].m_psDataInfo, 0, sizeof(DBINFO)); //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Buban103DispMalloc(commid, sizeof(DBINFO)*iNum); iAiStart += iNum; iAiNum++; iPntNo = 0; } else if(strcmp(ptrSour, "YX") == 0) { ParamType = PARAM_YX; psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation.m_iStnNo = commid+1; psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation.m_iStartPntNo = iDiStart; psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation.m_iPntNum = iNum; if(NULL != psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation.m_psDataInfo) { HEAP_FREE(psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation.m_psDataInfo); } psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation.m_psDataInfo = (DBINFO *)HEAP_MALLOC(sizeof(DBINFO)*iNum); memset((void *)psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation.m_psDataInfo, 0, sizeof(DBINFO)*iNum); Buban103DispMalloc(commid, sizeof(DBINFO)*iNum); iDiStart += iNum; iPntNo = 0; } else if(strcmp(ptrSour, "YM") == 0) { ParamType = PARAM_YM; psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation.m_iStnNo = commid+1; psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation.m_iStartPntNo = iPiStart; psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation.m_iPntNum = iNum; if(NULL != psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation.m_psDataInfo) { HEAP_FREE(psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation.m_psDataInfo); } psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation.m_psDataInfo = (DBINFO *)HEAP_MALLOC(sizeof(DBINFO)*iNum); memset((void *)psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation.m_psDataInfo, 0, sizeof(DBINFO)*iNum); Buban103DispMalloc(commid, sizeof(DBINFO)*iNum); iPiStart += iNum; iPntNo = 0; } else if(strcmp(ptrSour, "YK") == 0) { ParamType = PARAM_YK; psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation.m_iStnNo = commid+1; psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation.m_iStartPntNo = iYkStart; psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation.m_iPntNum = iNum; if(NULL != psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation.m_psDataInfo) { HEAP_FREE(psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation.m_psDataInfo); } psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation.m_psDataInfo = (DBINFO *)HEAP_MALLOC(sizeof(DBINFO)*iNum); memset((void *)psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation.m_psDataInfo, 0, sizeof(DBINFO)*iNum); Buban103DispMalloc(commid, sizeof(DBINFO)*iNum); iYkStart += iNum; iPntNo = 0; } else if(strcmp(ptrSour, "SYNCTIME") == 0) { ParamType = PARAM_SYNCTIME; iPntNo = 0; } else if(strcmp(ptrSour, "ASDU10") == 0) { ParamType = PARAM_ASDU10; psLink->m_psDev[i].m_sDevParam.m_iCfgGroupNum = iNum; iPntNo = 0; } } break; default: break; } ptrSour = ptrDest+1; } switch(ParamType) { case PARAM_YC: //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //if(TRUE == GetInfoData(ptrSour, iPntNo, // (DBORIENTATION *)(&psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation))) //{ // iPntNo++; //} //=============================================================================================== if(iAiNum > 0) { GetInfoData(ptrSour, 0, (DBORIENTATION *)(&psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[iAiNum-1])); } else { GetInfoData(ptrSour, 0, (DBORIENTATION *)(&psLink->m_psDev[i].m_sDevParam.m_sAiDBOrientation[0])); } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ break; case PARAM_YX: if(TRUE == GetInfoData(ptrSour, iPntNo, &psLink->m_psDev[i].m_sDevParam.m_sDiDBOrientation)) { iPntNo++; } break; case PARAM_YM: if(TRUE == GetInfoData(ptrSour, iPntNo, &psLink->m_psDev[i].m_sDevParam.m_sPiDBOrientation)) { iPntNo++; } break; case PARAM_YK: if(TRUE == GetInfoData(ptrSour, iPntNo, &psLink->m_psDev[i].m_sDevParam.m_sYkDBOrientation)) { iPntNo++; } break; case PARAM_SYNCTIME: GetSyncTimeInfoData(ptrSour, &psLink->m_psDev[i].m_sDevParam.m_sSyncTimeInfo); break; case PARAM_ASDU10: if(TRUE == GetGroupInfoData(ptrSour, iPntNo, &psLink->m_psDev[i].m_sDevParam)) { iPntNo++; } break; default: break; } } return bRetVal; } BOOL GetProvDevParamFromTemplateFile(int commid,HDSFILE hFile,\ BUBAN103LINKDEF *psLink) { char *ptr, *ptrSour, *ptrDest; char szBuf[512]; int i, j, ilen, iNum; int iAiNum, iAiStart, iDiStart; int iPiStart, iYkStart, iPntNo; BOOL bRetVal; enum Param_Type ParamType; iAiStart = 0; iDiStart = 0; iPiStart = 0; iYkStart = 0; iAiNum = 0; ParamType = PARAM_NO; bRetVal = TRUE; for(i=0; im_iDevNum;) { ptr = DSfgets(szBuf, sizeof(szBuf), hFile); if(ptr == NULL) { break; } // test //DebugPrint(szBuf); if(strstr(ptr, "设备描述") != NULL) { i++; iAiNum = 0; ParamType = PARAM_NO; continue; } if(strstr(ptr, "链路描述") != NULL) { break; } ptrSour = ptr; for(j=0; j<8; j++) { if(GetParamItem(ptrSour, &ptrDest) == FALSE) { bRetVal = FALSE; break; } *ptrDest = 0; ilen = strlen(ptrSour); switch(j) { case 0:// 设备描述 break; case 1:// 设备型号 break; case 2:// 设备地址 break; case 3:// 转发地址 if(PARAM_NO != ParamType) { break; } if(ilen > 0) { psLink->m_psProvDev[i].m_iProvAddr = atoi(ptrSour); } break; case 4:// 端口号&状态站号&状态点号 if(PARAM_NO != ParamType) { break; } if(ilen > 0) { psLink->m_psProvDev[i].m_iRealCommid = atoi(ptrSour); if(GetParamItemEx(ptrSour, &ptrDest, "&") == FALSE) { psLink->m_psProvDev[i].m_iStatusStn = 0; psLink->m_psProvDev[i].m_iStatusPnt = 0; break; } ptrSour = ptrDest+1; if(strlen(ptrSour) > 0) { psLink->m_psProvDev[i].m_iStatusStn = atoi(ptrSour); if(GetParamItemEx(ptrSour, &ptrDest, "&") == FALSE) { psLink->m_psProvDev[i].m_iStatusStn = 0; psLink->m_psProvDev[i].m_iStatusPnt = 0; break; } ptrSour = ptrDest+1; if(strlen(ptrSour) > 0) { psLink->m_psProvDev[i].m_iStatusPnt = atoi(ptrSour); } } } break; case 5:// 备用 break; case 6:// 数量 if(ilen > 0) { iNum = atoi(ptrSour); } break; case 7:// 数据类型 if(iNum <= 0) { break; } if(ilen > 0) { if(strcmp(ptrSour, "YC") == 0) { ParamType = PARAM_YC; psLink->m_psProvDev[i].m_sYcInfo.m_iPntNum = iNum; psLink->m_psProvDev[i].m_sYcInfo.m_iStartPntNo = 0; psLink->m_psProvDev[i].m_sYcInfo.m_iStnNo = 0; psLink->m_psProvDev[i].m_sYcInfo.m_psDataInfo = NULL; iPntNo = 0; } else if(strcmp(ptrSour, "YX") == 0) { ParamType = PARAM_YX; psLink->m_psProvDev[i].m_sYxInfo.m_iPntNum = iNum; psLink->m_psProvDev[i].m_sYxInfo.m_iStartPntNo = 0; psLink->m_psProvDev[i].m_sYxInfo.m_iStnNo = 0; if(NULL != psLink->m_psProvDev[i].m_sYxInfo.m_psDataInfo) { HEAP_FREE(psLink->m_psProvDev[i].m_sYxInfo.m_psDataInfo); } psLink->m_psProvDev[i].m_sYxInfo.m_psDataInfo = (DBINFO *)HEAP_MALLOC(sizeof(DBINFO)*iNum); memset((void *)psLink->m_psProvDev[i].m_sYxInfo.m_psDataInfo, 0, sizeof(DBINFO)*iNum); Buban103DispMalloc(commid, sizeof(DBINFO)*iNum); iPntNo = 0; } else if(strcmp(ptrSour, "YM") == 0) { ParamType = PARAM_YM; psLink->m_psProvDev[i].m_sYmInfo.m_iPntNum = iNum; psLink->m_psProvDev[i].m_sYmInfo.m_iStartPntNo = 0; psLink->m_psProvDev[i].m_sYmInfo.m_iStnNo = 0; psLink->m_psProvDev[i].m_sYmInfo.m_psDataInfo = NULL; iPntNo = 0; } else if(strcmp(ptrSour, "YK") == 0) { ParamType = PARAM_YK; iPntNo = 0; } else if(strcmp(ptrSour, "SYNCTIME") == 0) { ParamType = PARAM_SYNCTIME; iPntNo = 0; } else if(strcmp(ptrSour, "ASDU10") == 0) { ParamType = PARAM_ASDU10; psLink->m_psProvDev[i].m_iAsdu10Num = iNum; iPntNo = 0; } } break; default: break; } ptrSour = ptrDest+1; } switch(ParamType) { case PARAM_YC: break; case PARAM_YX: if(TRUE == GetInfoData(ptrSour, iPntNo, &psLink->m_psProvDev[i].m_sYxInfo)) { iPntNo++; } break; case PARAM_YM: break; case PARAM_YK: break; case PARAM_SYNCTIME: break; case PARAM_ASDU10: break; default: break; } } return bRetVal; } BOOL GetInfoData(char *pInfo, int iPntNo, DBORIENTATION *psDB) { int i; char *ptr1, *ptr2; BOOL bRetVal; if(pInfo == NULL) { return FALSE; } if(iPntNo >= psDB->m_iPntNum) { return FALSE; } if(psDB->m_psDataInfo == NULL) { return FALSE; } bRetVal = TRUE; ptr1 = pInfo; for(i=0; i<6; i++) { if(GetParamItem(ptr1, &ptr2) == FALSE) { //bRetVal = FALSE; break; } *ptr2 = 0; switch(i) { case 0:// 描述 break; case 1:// ASDU if(strlen(ptr1) > 0) { psDB->m_psDataInfo[iPntNo].m_u8Asdu = atoi(ptr1); } break; case 2:// FUN if(strlen(ptr1) > 0) { psDB->m_psDataInfo[iPntNo].m_u8Fun = atoi(ptr1); } break; case 3:// INF if(strlen(ptr1) > 0) { psDB->m_psDataInfo[iPntNo].m_u8Inf = atoi(ptr1); } break; case 4:// PROV_FUN if(strlen(ptr1) > 0) { psDB->m_psDataInfo[iPntNo].m_u8ProvFun = atoi(ptr1); } else { psDB->m_psDataInfo[iPntNo].m_u8ProvFun\ = (u_char)psDB->m_psDataInfo[iPntNo].m_u8Fun; } break; case 5:// PROV_INF if(strlen(ptr1) > 0) { psDB->m_psDataInfo[iPntNo].m_u8ProvInf = atoi(ptr1); } else { psDB->m_psDataInfo[iPntNo].m_u8ProvInf\ = (u_char)psDB->m_psDataInfo[iPntNo].m_u8Inf; } break; case 6://是否总召唤数据 if(strlen(ptr1) > 0) { psDB->m_psDataInfo[iPntNo].m_u8LoopData = atoi(ptr1); } else { psDB->m_psDataInfo[iPntNo].m_u8LoopData = 0; } break; default: bRetVal = FALSE; break; } ptr1 = ptr2+1; } // INF if(strlen(ptr1) > 0) { switch(i) { case 3:// INF psDB->m_psDataInfo[iPntNo].m_u8Inf = atoi(ptr1); psDB->m_psDataInfo[iPntNo].m_u8ProvFun\ = (u_char)psDB->m_psDataInfo[iPntNo].m_u8Fun; psDB->m_psDataInfo[iPntNo].m_u8ProvInf\ = (u_char)psDB->m_psDataInfo[iPntNo].m_u8Inf; psDB->m_psDataInfo[iPntNo].m_u8LoopData = 0; break; case 4:// PROV_FUN psDB->m_psDataInfo[iPntNo].m_u8ProvFun = atoi(ptr1); psDB->m_psDataInfo[iPntNo].m_u8ProvInf\ = (u_char)psDB->m_psDataInfo[iPntNo].m_u8Inf; psDB->m_psDataInfo[iPntNo].m_u8LoopData = 0; break; case 5:// PROV_INF psDB->m_psDataInfo[iPntNo].m_u8ProvInf = atoi(ptr1); psDB->m_psDataInfo[iPntNo].m_u8LoopData = 0; break; case 6://是否总召唤数据 psDB->m_psDataInfo[iPntNo].m_u8LoopData = atoi(ptr1); break; default: if(i < 6) { bRetVal = FALSE; } break; } } else { switch(i) { case 4:// PROV_FUN psDB->m_psDataInfo[iPntNo].m_u8ProvFun\ = (u_char)psDB->m_psDataInfo[iPntNo].m_u8Fun; case 5:// PROV_INF psDB->m_psDataInfo[iPntNo].m_u8ProvInf\ = (u_char)psDB->m_psDataInfo[iPntNo].m_u8Inf; case 6://是否总召唤数据 psDB->m_psDataInfo[iPntNo].m_u8LoopData = 0; break; default: if(i < 6) { bRetVal = FALSE; } break; } } return bRetVal; } BOOL GetSyncTimeInfoData(char *pInfo, DBINFO *psSyncInfo) { int i; char *ptr1, *ptr2; BOOL bRetVal; if(pInfo == NULL) { return FALSE; } if(psSyncInfo == NULL) { return FALSE; } bRetVal = TRUE; ptr1 = pInfo; for(i=0; i<3; i++) { if(GetParamItem(ptr1, &ptr2) == FALSE) { bRetVal = FALSE; break; } *ptr2 = 0; switch(i) { case 0:// 描述 break; case 1:// ASDU if(strlen(ptr1) > 0) { psSyncInfo->m_u8Asdu = atoi(ptr1); } break; case 2:// FUN if(strlen(ptr1) > 0) { psSyncInfo->m_u8Fun = atoi(ptr1); } break; default: bRetVal = FALSE; break; } ptr1 = ptr2+1; } // INF if(strlen(ptr1) > 0) { psSyncInfo->m_u8Inf = atoi(ptr1); } return bRetVal; } BOOL GetGroupInfoData(char *pInfo, int iPntNo, DEVPARAMDEF *psDevParam) { int i; char *ptr1, *ptr2; BOOL bRetVal; if(pInfo == NULL) { return FALSE; } if(iPntNo >= psDevParam->m_iCfgGroupNum) { return FALSE; } bRetVal = TRUE; ptr1 = pInfo; for(i=0; i<3; i++) { if(GetParamItem(ptr1, &ptr2) == FALSE) { bRetVal = FALSE; break; } *ptr2 = 0; switch(i) { case 0:// GROUPNO if(strlen(ptr1) > 0) { psDevParam->m_saGroupDef[iPntNo].m_iGroupNo = atoi(ptr1); } break; case 1:// DATATYPE if(strlen(ptr1) > 0) { psDevParam->m_saGroupDef[iPntNo].m_iDataType = atoi(ptr1); } break; case 2:// STN if(strlen(ptr1) > 0) { psDevParam->m_saGroupDef[iPntNo].m_iStationNo = atoi(ptr1); } break; default: bRetVal = FALSE; break; } ptr1 = ptr2+1; } // START_PNT if(strlen(ptr1) > 0) { psDevParam->m_saGroupDef[iPntNo].m_iStartPntNo = atoi(ptr1); } return bRetVal; } BOOL InitBuban103InfoFromDat(int commid, BUBAN103LINKDEF *psLink) { int i, j, iMallocSize; char szDatFile[256], szbuf[256]; //char szDbg[256]; char szSection[128]; GROUPDEF *psGroupParam; for(i=0; im_iDevNum; i++) { #ifdef OS_LINUX sprintf(szDatFile, "dat/%s.dat", psLink->m_psDev[i].m_sDevParam.m_szType); #else sprintf(szDatFile, "%s\\dat\\%s.dat", IniFilePath, psLink->m_psDev[i].m_sDevParam.m_szType); #endif for(j=0; jm_psDev[i].m_sDevParam.m_iCfgGroupNum; j++) { psGroupParam = &psLink->m_psDev[i].m_sDevParam.m_saGroupDef[j]; //psGroupParam->m_pu8DataLen = NULL; //psGroupParam->m_pu8DataType = NULL; //psGroupParam->m_pu8GIN = NULL; //psGroupParam->m_iPntNum = 0; psGroupParam->m_u32CurPntNo = 1; psGroupParam->m_bInit = FALSE; // (缺省为5,即第一个条目大于5的数据包为中间数据包) psGroupParam->m_iStartItemNo = 5; if(PROTECT_EVENT_PNT_TYPE == psGroupParam->m_iDataType) { psGroupParam->m_psEventInfo = (GROUPEVENTDEF *)HEAP_MALLOC(sizeof(GROUPEVENTDEF)); memset((void *)psGroupParam->m_psEventInfo, 0, sizeof(GROUPEVENTDEF)); Buban103DispMalloc(commid, sizeof(GROUPEVENTDEF)); //psGroupParam->m_psDataInfo = NULL; } else { //psGroupParam->m_psEventInfo = NULL; //psGroupParam->m_psDataInfo = NULL; sprintf(szSection, "组号%d", psGroupParam->m_iGroupNo); szbuf[0] = 0; GetPrivateProString(szSection, "数量", "0", szbuf, sizeof(szbuf), szDatFile); //sprintf(szDbg, "[%s]:[数量] = %s\n", szSection, szbuf); //DebugPrint(szDbg); psGroupParam->m_iPntNum = atoi(szbuf); if(psGroupParam->m_iPntNum > 0) { iMallocSize = psGroupParam->m_iPntNum * sizeof(GROUPDATADEF); psGroupParam->m_psDataInfo = (GROUPDATADEF *)HEAP_MALLOC(iMallocSize); memset((void *)psGroupParam->m_psDataInfo, 0, iMallocSize); Buban103DispMalloc(commid, iMallocSize); InitGroupParam(psGroupParam, szDatFile); iMallocSize = psGroupParam->m_iPntNum * sizeof(BYTE); psGroupParam->m_pu8GIN = (BYTE *)HEAP_MALLOC(iMallocSize); Buban103DispMalloc(commid, iMallocSize); if(PROTECT_FIX_PNT_TYPE == psGroupParam->m_iDataType) { psGroupParam->m_pu8DataLen = (BYTE *)HEAP_MALLOC(iMallocSize); Buban103DispMalloc(commid, iMallocSize); psGroupParam->m_pu8DataType = (BYTE *)HEAP_MALLOC(iMallocSize); Buban103DispMalloc(commid, iMallocSize); } } GetPrivateProString(szSection, "首条目号", "-1", szbuf, sizeof(szbuf), szDatFile); //sprintf(szDbg, "[%s]:[首条目号] = %s\n", szSection, szbuf); //DebugPrint(szDbg); if(atoi(szbuf) > 0) { psGroupParam->m_iStartItemNo = atoi(szbuf); } } } } return TRUE; } void InitGroupParam(GROUPDEF *psGroupParam, char *szDatFileName) { i_32 i, iNameLen, iFixDataType; char szbuf[512], szSection[128], szItem[128]; char *ptrFirst, *ptrFind; BOOL bValue; bValue = FALSE; sprintf(szSection, "组号%d", psGroupParam->m_iGroupNo); for(i=0; im_iPntNum; i++) { ptrFirst = (char *)szbuf; sprintf(szItem, "%d", i+1); if(GetPrivateProString(szSection, szItem, "未知名称", szbuf, sizeof(szbuf), szDatFileName) < 0) { strcpy(szbuf, "未知名称"); } // 名称 ptrFind = strstr(ptrFirst, ","); if(ptrFind) { *ptrFind = 0; iNameLen = strlen(ptrFirst); } else { iNameLen = strlen(ptrFirst); if(iNameLen >= sizeof(psGroupParam->m_psDataInfo[i].m_szName)) { iNameLen = sizeof(psGroupParam->m_psDataInfo[i].m_szName)-1; } memcpy(psGroupParam->m_psDataInfo[i].m_szName, ptrFirst, iNameLen); psGroupParam->m_psDataInfo[i].m_szName[iNameLen] = 0; continue; } if(iNameLen >= sizeof(psGroupParam->m_psDataInfo[i].m_szName)) { iNameLen = sizeof(psGroupParam->m_psDataInfo[i].m_szName)-1; } memcpy(psGroupParam->m_psDataInfo[i].m_szName, ptrFirst, iNameLen); psGroupParam->m_psDataInfo[i].m_szName[iNameLen] = 0; if(PROTECT_DI_PNT_TYPE == psGroupParam->m_iDataType) { psGroupParam->m_psDataInfo[i].m_fValue = (float)bValue; bValue = !bValue; } else { psGroupParam->m_psDataInfo[i].m_fValue = (float)(i+1); } // 其他信息 if(PROTECT_DI_PNT_TYPE == psGroupParam->m_iDataType) continue; if(PROTECT_AI_PNT_TYPE == psGroupParam->m_iDataType) { // 序号 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) *ptrFind = 0; else continue; // 占有位 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) *ptrFind = 0; else continue; // 系数 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) *ptrFind = 0; else continue; // 单位 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) { *ptrFind = 0; iNameLen = strlen(ptrFirst); } else { iNameLen = strlen(ptrFirst); } if(iNameLen >= sizeof(psGroupParam->m_psDataInfo[i].m_szUnit)) { iNameLen = sizeof(psGroupParam->m_psDataInfo[i].m_szUnit)-1; } memcpy(psGroupParam->m_psDataInfo[i].m_szUnit, ptrFirst, iNameLen); psGroupParam->m_psDataInfo[i].m_szUnit[iNameLen] = 0; continue; } if(PROTECT_FIX_PNT_TYPE == psGroupParam->m_iDataType) { // 类型(AI=1, DI=2) ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) *ptrFind = 0; else continue; iFixDataType = atoi(ptrFirst); psGroupParam->m_psDataInfo[i].iFixDataType = (u_char)iFixDataType; // 序号 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) *ptrFind = 0; else continue; // 占有位 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) *ptrFind = 0; else continue; // 开关量 if(iFixDataType == 2) { // 可能存在有动作描述 continue; } // 以下为模拟量初始化 // 系数(充当步长) ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); psGroupParam->m_psDataInfo[i].m_fStepValue = (float)atof(ptrFirst); if(ptrFind) *ptrFind = 0; else continue; // 单位 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); if(ptrFind) { *ptrFind = 0; iNameLen = strlen(ptrFirst); } else { iNameLen = strlen(ptrFirst); } if(iNameLen >= sizeof(psGroupParam->m_psDataInfo[i].m_szUnit)) { iNameLen = sizeof(psGroupParam->m_psDataInfo[i].m_szUnit)-1; } memcpy(psGroupParam->m_psDataInfo[i].m_szUnit, ptrFirst, iNameLen); psGroupParam->m_psDataInfo[i].m_szUnit[iNameLen] = 0; if(NULL == ptrFind) continue; // 最小值 ptrFirst = ptrFind + 1; ptrFind = strstr(ptrFirst, ","); psGroupParam->m_psDataInfo[i].m_fMinValue = (float)atof(ptrFirst); if(ptrFind) { *ptrFind = 0; } else { continue; } // 最大值 ptrFirst = ptrFind + 1; psGroupParam->m_psDataInfo[i].m_fMaxValue = (float)atof(ptrFirst); } } } void InitBuban103CmdBuf(int commid, BUBAN103PORTPARAM *psPortParam) { int i; psPortParam->m_iLinkIdx = 0; for(i=0; im_iLinkNum; i++) { InitBuban103LinkCmdBuf(&psPortParam->m_psLink[i]); } } void InitBuban103LinkCmdBuf(BUBAN103LINKDEF *psLinkParam) { int i; psLinkParam->m_bRstLinkOk = FALSE; psLinkParam->m_bGotoNext = FALSE; psLinkParam->m_iQueryNum_CLASS1_Count = 0; psLinkParam->m_iDevIdx = 0; psLinkParam->m_iQueryedAddr_CLASS1 = 0; psLinkParam->m_shCurCmdIdx = 0; if(psLinkParam->m_uchLinkAddr != 0xFF) { psLinkParam->m_pu8CtlByte[0] = 0x00; psLinkParam->m_pbLinkOk[0] = FALSE; psLinkParam->m_pu32LinkOkCnt[0] = 0; } else { for(i=0; im_iDevNum; i++) { psLinkParam->m_pu8CtlByte[i] = 0x00; psLinkParam->m_pbLinkOk[i] = FALSE; psLinkParam->m_pu32LinkOkCnt[i] = 0; } } // 初始化指令队列 for(i=0; im_sArrayCmdTime[i].m_iCmdTimerConst > 20) { psLinkParam->m_sArrayCmdTime[i].m_iCmdTimerCnt = psLinkParam->m_sArrayCmdTime[i].m_iCmdTimerConst-20; } else { psLinkParam->m_sArrayCmdTime[i].m_iCmdTimerCnt = psLinkParam->m_sArrayCmdTime[i].m_iCmdTimerConst; } } for(i=0; im_iDevNum; i++) { InitBuban103DevCmdBuf(psLinkParam, i); } } void InitBuban103DevCmdBuf(BUBAN103LINKDEF *psLinkParam, int iDevNo) { DEVDEF *psDevDef; PROVDEVDEF *psProvDevParam; SetProtectDevStatus(psLinkParam, iDevNo, FALSE); if(psLinkParam->m_psDev != NULL) { psDevDef = &psLinkParam->m_psDev[iDevNo]; } else { psDevDef = NULL; } if(psLinkParam->m_psProvDev != NULL) { psProvDevParam = &psLinkParam->m_psProvDev[iDevNo]; } else { psProvDevParam = NULL; } // 链路地址为255,则每个装置都是链路装置 if(psLinkParam->m_uchLinkAddr == 0xFF) { psLinkParam->m_pbLinkOk[iDevNo] = FALSE; psLinkParam->m_pu32LinkOkCnt[iDevNo] = 0; psLinkParam->m_pu8CtlByte[iDevNo] = 0; } if(psDevDef != NULL) { psDevDef->m_bAllQueryOk = TRUE; psDevDef->m_bInitdata = FALSE; if(psLinkParam->m_u32TimeOutConst > 10) { psDevDef->m_u32CallCnt = psLinkParam->m_u32TimeOutConst-5; } else { psDevDef->m_u32CallCnt = 0; } psDevDef->m_u8RII = 0; psDevDef->m_sDevParam.m_iFaultNo = -1; psDevDef->m_sDevParam.m_u32FuncCode = 0; if(psDevDef->m_sDisturbanceParam.m_pshValue != NULL) { HEAP_FREE(psDevDef->m_sDisturbanceParam.m_pshValue); } memset((void *)&psDevDef->m_sDisturbanceParam, 0, sizeof(BUBAN103DISTURBANCEDEF)); } if(psProvDevParam != NULL) { memset((void *)&psProvDevParam->m_sProvGroupParam, 0, sizeof(PROV_ALLITEMOFGROUPPARAM)); psProvDevParam->m_sProvGroupParam.m_bFinished = TRUE; psProvDevParam->m_sProvSoe.m_shFront = 0; psProvDevParam->m_sProvSoe.m_shRear = 0; psProvDevParam->m_sProvSoe.m_shSoeNum = 0; // 转发 psProvDevParam->m_bProvQuery = FALSE; psProvDevParam->m_iProvAsdu5Cause = 0; psProvDevParam->m_iProvQueryStepWithASDU = 0; // wen 2005.06.22 不可以在这里初始化链表 // 初始化单向链表,链表最大数量为10个 //SingleListInit(&psProvDevParam->m_sBaoHuData, 10); } } void ReCalcDevPntStart(int commid, BUBAN103PORTPARAM *psPortParam) { int i, j, k; int iAiStart, iDiStart; int iPiStart, iYkStart; BOOL bSlave; DEVDEF *pDevParam=NULL; PROVDEVDEF *pProvDevParam=NULL; iAiStart = 0; iDiStart = 0; iPiStart = 0; iYkStart = 0; if(psPortParam->m_psLink[0].m_psDev != NULL) { bSlave = FALSE; pProvDevParam = NULL; } if(psPortParam->m_psLink[0].m_psProvDev != NULL) { bSlave = TRUE; pDevParam = NULL; } for(i=0; im_iLinkNum; i++) { for(j=0; jm_psLink[i].m_iDevNum; j++) { if(FALSE == bSlave) { pDevParam = &psPortParam->m_psLink[i].m_psDev[j]; } else { pProvDevParam = &psPortParam->m_psLink[i].m_psProvDev[j]; } if(pDevParam != NULL) { // ai for(k=0; km_sDevParam.m_sAiDBOrientation[k].m_iPntNum <= 0) { break; } pDevParam->m_sDevParam.m_sAiDBOrientation[k].m_iStartPntNo = iAiStart; iAiStart += pDevParam->m_sDevParam.m_sAiDBOrientation[k].m_iPntNum; } // di if(pDevParam->m_sDevParam.m_sDiDBOrientation.m_iPntNum > 0) { pDevParam->m_sDevParam.m_sDiDBOrientation.m_iStartPntNo = iDiStart; iDiStart += pDevParam->m_sDevParam.m_sDiDBOrientation.m_iPntNum; } // pi if(pDevParam->m_sDevParam.m_sPiDBOrientation.m_iPntNum > 0) { pDevParam->m_sDevParam.m_sPiDBOrientation.m_iStartPntNo = iPiStart; iPiStart += pDevParam->m_sDevParam.m_sPiDBOrientation.m_iPntNum; } if(pDevParam->m_sDevParam.m_sYkDBOrientation.m_iPntNum > 0) { pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo = iYkStart; iYkStart += pDevParam->m_sDevParam.m_sYkDBOrientation.m_iPntNum; } } if(pProvDevParam != NULL) { // ai if(pProvDevParam->m_sYcInfo.m_iPntNum > 0) { pProvDevParam->m_sYcInfo.m_iStartPntNo = iAiStart; iAiStart += pProvDevParam->m_sYcInfo.m_iPntNum; } // di if(pProvDevParam->m_sYxInfo.m_iPntNum > 0) { pProvDevParam->m_sYxInfo.m_iStartPntNo = iDiStart; iDiStart += pProvDevParam->m_sYxInfo.m_iPntNum; } // Pi if(pProvDevParam->m_sYmInfo.m_iPntNum > 0) { pProvDevParam->m_sYmInfo.m_iStartPntNo = iPiStart; iPiStart += pProvDevParam->m_sYmInfo.m_iPntNum; } } } } } //===========================装置初始化函数结束======================= //===========================以下为指令生成函数======================= //************************************************************************** //* 生成 Buban103协议链路层命令 * //*参数:u_32 commid:RTU端口号 * //* BYTE bLinkAddr:链路地址 * //* u_char link_cmd_idx:链路层命令索引 * //* u_char *msg:应用层命令信息,即应用服务数据单元,如果使用固定 * //* 长度的帧格式,则用NULL调用 * //* u_32 len:应用层命令信息的长度,如果使用固定长度的帧格式,则用0调用* //* u_32 cmdtype: 指令缓冲区类型 * //************************************************************************** void MakeBuban103LinkCommand(u_32 commid, BYTE bLinkAddr, u_char link_cmd_idx, u_char* msg, u_32 len, u_32 cmdtype) { u_char tmp[MAX_POLL_CMD_BUF_LEN], nCs, nEnd; CLPDU_FIX bClpdu_fix; CLPDU_VARR bClpdu_varr; memset(&bClpdu_fix, 0, sizeof(CLPDU_FIX)); memset(&bClpdu_varr, 0, sizeof(CLPDU_VARR)); memset(tmp, 0, sizeof(tmp)); switch(link_cmd_idx) { case C_RLK_NA_3: // 请求链路状态 bClpdu_fix.nSTART = 0x10; bClpdu_fix.nCONTROL = C_RLK_NA_3 | 0x40; bClpdu_fix.nADDR = bLinkAddr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, (char*)&bClpdu_fix, 5); break; case C_RFB_NA_3: // 复位帧计数位 bClpdu_fix.nSTART = 0x10; bClpdu_fix.nCONTROL = C_RFB_NA_3 | 0x40; bClpdu_fix.nADDR = bLinkAddr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, (char*)&bClpdu_fix, 5); break; case C_RCU_NA_3: // 复位通讯单元 bClpdu_fix.nSTART = 0x10; bClpdu_fix.nCONTROL = C_RCU_NA_3 | 0x40; bClpdu_fix.nADDR = bLinkAddr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, (char*)&bClpdu_fix, 5); break; case C_PL1_NA_3: // 召唤1级用户数据 bClpdu_fix.nSTART = 0x10; bClpdu_fix.nCONTROL = C_PL1_NA_3 | 0x50; bClpdu_fix.nADDR = bLinkAddr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, INSERT_POLL_CMD, 0, (char*)&bClpdu_fix, 5); break; case C_PL2_NA_3: // 召唤2级用户数据 bClpdu_fix.nSTART = 0x10; bClpdu_fix.nCONTROL = C_PL2_NA_3 | 0x50; bClpdu_fix.nADDR = bLinkAddr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, NORMAL_POLL_CMD, 0, (char*)&bClpdu_fix, 5); break; case C_SD1_NA_3: // 传送数据(发送/确认帧) bClpdu_varr.nSTART1 = 0x68; bClpdu_varr.nSTART2 = 0x68; if(len != 0) { bClpdu_varr.nLEN1 = (BYTE)(len + 2); bClpdu_varr.nLEN2 = bClpdu_varr.nLEN1; } bClpdu_varr.nCONTROL = C_SD1_NA_3 | 0x50; bClpdu_varr.nADDR = bLinkAddr; memcpy(tmp,(char*)&bClpdu_varr,sizeof(bClpdu_varr)); memcpy(&tmp[6],msg,len); nCs = CalBuban103Lpc(tmp, bClpdu_varr.nLEN1); nEnd = 0x16; tmp[len+6] = nCs; tmp[len+7] = nEnd; PutPollCmdToBuf(commid, cmdtype, 0, (char*)tmp, len+8); break; case C_SD2_NA_3: // 传送数据(发送/无回答帧) bClpdu_varr.nSTART1 = 0x68; bClpdu_varr.nSTART2 = 0x68; if(len != 0) { bClpdu_varr.nLEN1 = (BYTE)(len + 2); bClpdu_varr.nLEN2 = bClpdu_varr.nLEN1; } bClpdu_varr.nCONTROL = C_SD2_NA_3 | 0x40; bClpdu_varr.nADDR = bLinkAddr; memcpy(tmp,(char*)&bClpdu_varr,sizeof(bClpdu_varr)); memcpy(&tmp[6],msg,len); nCs = CalBuban103Lpc(tmp, bClpdu_varr.nLEN1); nEnd = 0x16; tmp[len+6] = nCs; tmp[len+7] = nEnd; PutPollCmdToBuf(commid, cmdtype, 0, (char*)tmp, len+8); break; default: break; } } //************************************************************* //* 生成时间同步命令 * //*参数:u_32 commid:RTU端口号 * //* u_char addr:间隔设备地址 //************************************************************* void MakeTimeSyn_CAsdu6(u_32 commid, CMDPARAM *psCmdParam) { CASDU6 bCAsdu6; DAY_TIME sCurTime; char szbuf[128]; memset(&bCAsdu6,0,sizeof(CASDU6)); bCAsdu6.nTYP = C_SYN_TA_3; bCAsdu6.nVSQ = 0x81; bCAsdu6.nCOT = 8; bCAsdu6.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu6.nFUN = psCmdParam->m_uchFun; bCAsdu6.nINF = psCmdParam->m_uchInf; GetLocalTimeEx(&sCurTime); sCurTime.mSec = sCurTime.Sec*1000 + sCurTime.mSec; bCAsdu6.nTIME[0] = sCurTime.mSec % 256; bCAsdu6.nTIME[1] = sCurTime.mSec / 256; bCAsdu6.nTIME[2] = (u_char)sCurTime.Min; bCAsdu6.nTIME[3] = (u_char)sCurTime.Hour; //bCAsdu6.nTIME[4] = (u_char)ControlParam->CurTime.wDayOfWeek; bCAsdu6.nTIME[4] = (u_char)(sCurTime.Day&0x1F); bCAsdu6.nTIME[5] = (u_char)sCurTime.Month; bCAsdu6.nTIME[6] = (u_char)(sCurTime.Year%100); sprintf(szbuf, "对时时间为:%d年%d月%d日%d点%d分%d秒%d毫秒",sCurTime.Year,sCurTime.Month,bCAsdu6.nTIME[4],sCurTime.Hour,sCurTime.Min,sCurTime.Sec,sCurTime.mSec-sCurTime.Sec*1000); DebugPrint(szbuf); if(psCmdParam->m_sDevAddr.m_uchLinkAddr == 255) { MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr, \ C_SD2_NA_3, (u_char*)&bCAsdu6, sizeof(CASDU6), FAST_POLL_CMD); } else { MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr, \ C_SD1_NA_3, (u_char*)&bCAsdu6, sizeof(CASDU6), NORMAL_POLL_CMD); } } //************************************************************* //* 生成总查询启动命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 //************************************************************* void MakeAllQuery_CAsdu7(u_32 commid, CMDPARAM *psCmdParam) { BYTE u8SCN; CASDU7 bCAsdu7; BUBAN103PORTPARAM *pPortParam; if(SioParam[commid].ExtInfo == NULL) { return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; memset(&bCAsdu7,0,sizeof(CASDU7)); bCAsdu7.nTYP = C_TGI_NA_3; bCAsdu7.nVSQ = 0x81; bCAsdu7.nCOT = 9; bCAsdu7.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu7.nFUN = 255; bCAsdu7.nINF = 0; //扫描值需核实 u8SCN = pPortParam->m_psLink[psCmdParam->m_sDevAddr.m_iLinkIdx].m_psDev[psCmdParam->m_sDevAddr.m_iDevIdx].m_sDevParam.m_u8SCN; bCAsdu7.nSCN = u8SCN; MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr,\ C_SD1_NA_3 , (unsigned char*)&bCAsdu7, sizeof(CASDU7), NORMAL_POLL_CMD); pPortParam->m_psLink[psCmdParam->m_sDevAddr.m_iLinkIdx].m_psDev[psCmdParam->m_sDevAddr.m_iDevIdx].m_bAllQueryOk = FALSE; pPortParam->m_psLink[psCmdParam->m_sDevAddr.m_iLinkIdx].m_psDev[psCmdParam->m_sDevAddr.m_iDevIdx].m_sDevParam.m_u8SCN = (u8SCN+1) % 256; } //******************************************************************* //* 生成通用分类数据命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 //* u_char inf:信息序号,取值范围只能是248-251,其中: * //* 248:写条目 * //* 249:带确认的写条目 * //* 250:带执行的写条目 * //* 251:写条目终止 * //* unsigned char* dataset:通用分类数据集信息 * //* u_char ngd:通用分类数据集数目(数目、计数器位、后续状态位) * //******************************************************************* void MakeGenIdentData_CAsdu10(u_32 commid, CMDPARAM *psCmdParam, u_char *dataset, u_char ngd) { CASDU10 bCAsdu10; u_32 len,len1,i,start; u_char tmp[MAX_POLL_CMD_BUF_LEN]; memset(&bCAsdu10,0,sizeof(CASDU10)); bCAsdu10.nTYP = C_GD_NA_3; bCAsdu10.nVSQ = 0x81; bCAsdu10.nCOT = 40; bCAsdu10.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu10.nFUN = 254; if((psCmdParam->m_uchInf >= 248) && (psCmdParam->m_uchInf <= 251)) { bCAsdu10.nINF = psCmdParam->m_uchInf; } bCAsdu10.nRII = psCmdParam->m_uchRII; bCAsdu10.nNGD = ngd; //计算数据集的长度 start = 0; len = 0; for(i=0; i 0) && (dataset != NULL)) { memcpy((void*)&tmp[len1], dataset, len); } MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr, \ C_SD1_NA_3 , (unsigned char*)tmp, len + len1, NORMAL_POLL_CMD); } //******************************************************************* //* 生成通用分类数据命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 * //* u_char inf:信息序号,取值范围只能是248-251,其中: * //* 248:写条目 * //* 249:带确认的写条目 * //* 250:带执行的写条目 * //* 251:写条目终止 * //* unsigned char* dataset:通用分类数据集信息 * //* u_char ngd:通用分类数据集数目(数目、计数器位、后续状态位) * //* u_32 cmdtype : 指令缓冲区类型 * //******************************************************************* void MakeGenIdentData_CAsdu10Ex(u_32 commid, CMDPARAM *psCmdParam, u_char *dataset, u_char ngd, u_32 cmdtype) { CASDU10 bCAsdu10; u_32 len,len1,i,start; u_char tmp[MAX_POLL_CMD_BUF_LEN]; memset(&bCAsdu10,0,sizeof(CASDU10)); bCAsdu10.nTYP = C_GD_NA_3; bCAsdu10.nVSQ = 0x81; bCAsdu10.nCOT = 40; bCAsdu10.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu10.nFUN = 254; if((psCmdParam->m_uchInf >= 248) && (psCmdParam->m_uchInf <= 251)) { bCAsdu10.nINF = psCmdParam->m_uchInf; } bCAsdu10.nRII = psCmdParam->m_uchRII; bCAsdu10.nNGD = ngd; //计算数据集的长度 start = 0; len = 0; for(i=0; i 0) && (dataset != NULL)) { memcpy((void*)&tmp[len1], dataset, len); } MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr, \ C_SD1_NA_3 , (unsigned char*)tmp, len + len1, cmdtype); } //************************************************************* //* 生成一般命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 //* u_char inf:信息序号,取值范围为16--26 ,包括: * //* 16=自动重合闸投入/退出(ON/OFF) * //* 17=远方保护投入/退出(ON/OF) * //* 18=保护投入/退出(ON/OF) * //* 19=LED复位 * //* 23=激活特性1 * //* 24=激活特性2 * //* 25=激活特性3 * //* 26=激活特性4 * //* 其它值均为非法 * //* bool cmd:命令状态(true=合,false=开) * //************************************************************* void MakeGenCommand_CAsdu20(u_32 commid, CMDPARAM *psCmdParam, bool cmd) { CASDU20 bCAsdu20; memset(&bCAsdu20,0,sizeof(CASDU20)); bCAsdu20.nTYP = C_GRC_NA_3; bCAsdu20.nVSQ = 0x81; bCAsdu20.nCOT = 20; bCAsdu20.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu20.nFUN = 128;//需要验证确认 bCAsdu20.nINF = psCmdParam->m_uchInf; bCAsdu20.nRII = psCmdParam->m_uchRII; if(cmd) { bCAsdu20.nDCO = 0x02; } else { bCAsdu20.nDCO = 0x01; } MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr, \ C_SD1_NA_3 , (u_char *)&bCAsdu20, sizeof(CASDU20), NORMAL_POLL_CMD); } //****************************************************************** //* 生成通用分类命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 //* u_char inf:信息序号,取值范围只能是240-245,其中: * //* 240:读全部被定义的组的标题 * //* 241:读一个组的全部条目的值或属性 * //* 242:未用 * //* 243:读单个条目的目录 * //* 244:读单个条目的值或属性 * //* 245:对通用分类数据的总查询(总召唤) * //* GEN_DATAGROUP* datagroup:通用分类数据组信息 * //* u_char nog:通用分类标示数目 * //****************************************************************** void MakeGenIdentCommand_CAsdu21(u_32 commid, CMDPARAM *psCmdParam, GEN_DATAGROUP* datagroup ,u_char nog) { CASDU21 bCAsdu21; u_32 len; u_char tmp[MAX_POLL_CMD_BUF_LEN]; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif memset(&bCAsdu21, 0, sizeof(CASDU21)); bCAsdu21.nTYP = C_GC_NA_3; bCAsdu21.nVSQ = 0x81; if(psCmdParam->m_uchInf == C_INF_QUERYGENERAL) { bCAsdu21.nCOT = C_CAUSE_QUERY; } else // 通用分类读命令 { bCAsdu21.nCOT = C_CAUSE_READWITHVALIDDATA; } bCAsdu21.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu21.nFUN = FUNC_GENERALSORT; if((psCmdParam->m_uchInf >= C_INF_READGROUPTITLE) && (psCmdParam->m_uchInf <= C_INF_QUERYGENERAL)) { bCAsdu21.nINF = psCmdParam->m_uchInf; } else { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d生成通用分类命令时,INF=%d不在指定的范围内!!!", commid, psCmdParam->m_sDevAddr.m_uchLinkAddr, psCmdParam->m_sDevAddr.m_uchCommAddr, psCmdParam->m_uchInf); DebugPrint(szbuf); #endif return; } bCAsdu21.nRII = psCmdParam->m_uchRII; bCAsdu21.nNOG = nog; len = sizeof(CASDU21)-sizeof(GEN_DATAGROUP *); memcpy((void *)tmp, (void *)&bCAsdu21, len); if(nog ==0) { MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr,\ C_SD1_NA_3, tmp, len, NORMAL_POLL_CMD); } else { memcpy((void*)&tmp[len], datagroup, sizeof(GEN_DATAGROUP)*nog); len += sizeof(GEN_DATAGROUP)*nog; MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr,\ C_SD1_NA_3 , tmp, len, NORMAL_POLL_CMD); } } //************************************************************* //* 生成扰动数据传输命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 //* u_char too:命令类型,数值范围为1--255,包括: //* 1=故障的选择 //* 2=请求扰动数据 //* 3=中止扰动数据 //* 4--7 = 备用 //* 8=通道的请求 //* 9=通道的中止 //* 10--15 = 备用 //* 16=请求带标志的状态变位 //* 17=中止带标志的状态变位 //* 18--23 = 备用 //* 24=请求被记录扰动表 //* 25--31 =备用 //* 32=不带中止的扰动数据传输的结束 //* 33=由控制系统所中止的扰动数据传输的结束 //* 34=由继电保护设备(或间隔单元)所中止的扰动数据传输的结束 //* 35=不带中止的通道传输的结束 //* 36=由控制系统所中止的通道传输的结束 //* 37=由继电保护设备(或间隔单元)所中止饿通道传输的结束 //* 38=不带中止的带标志的状态变位的传输结束 //* 39=由控制系统所中止的带标志的状态变位的传输的结束 //* 40=由继电保护设备(或间隔单元)所中止的带标志的状态变位传输的结束 //* 41--63=备用 //* 64=成功地扰动数据传输(肯定) //* 65=不成功地扰动数据传输(否定) //* 66=成功地通道传输(肯定) //* 67=不成功地通道传输(否定) //* 68=成功地带标志的状态变位传输(肯定) //* 69=不成功地带标志的状态变位传输(否定) //* 70--255=备用 //* u_char tov:扰动值的类型 //* u_short fan:故障序号 //* u_char acc:实际通道序号 //************************************************************* void MakeDisTrans_CAsdu24(u_32 commid, CMDPARAM *psCmdParam, u_char too, u_char tov, u_short fan, u_char acc) { CASDU24 bCAsdu24; memset(&bCAsdu24,0,sizeof(CASDU24)); bCAsdu24.nTYP = C_ODT_NA_3; bCAsdu24.nVSQ = 0x81; bCAsdu24.nCOT = 31; bCAsdu24.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu24.nFUN = psCmdParam->m_uchFun; bCAsdu24.nTOO = too; bCAsdu24.nTOV = tov; bCAsdu24.nFAN = fan; bCAsdu24.nACC = acc; MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr, \ C_SD1_NA_3, (u_char *)&bCAsdu24, sizeof(CASDU24), INSERT_POLL_CMD); } //************************************************************* //* 生成扰动数据传输的认可命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 //* u_char too:命令类型,数值范围为1--255,包括: //* 1=故障的选择 //* 2=请求扰动数据 //* 3=中止扰动数据 //* 4--7 = 备用 //* 8=通道的请求 //* 9=通道的中止 //* 10--15 = 备用 //* 16=请求带标志的状态变位 //* 17=中止带标志的状态变位 //* 18--23 = 备用 //* 24=请求被记录扰动表 //* 25--31 =备用 //* 32=不带中止的扰动数据传输的结束 //* 33=由控制系统所中止的扰动数据传输的结束 //* 34=由继电保护设备(或间隔单元)所中止的扰动数据传输的结束 //* 35=不带中止的通道传输的结束 //* 36=由控制系统所中止的通道传输的结束 //* 37=由继电保护设备(或间隔单元)所中止饿通道传输的结束 //* 38=不带中止的带标志的状态变位的传输结束 //* 39=由控制系统所中止的带标志的状态变位的传输的结束 //* 40=由继电保护设备(或间隔单元)所中止的带标志的状态变位传输的结束 //* 41--63=备用 //* 64=成功地扰动数据传输(肯定) //* 65=不成功地扰动数据传输(否定) //* 66=成功地通道传输(肯定) //* 67=不成功地通道传输(否定) //* 68=成功地带标志的状态变位传输(肯定) //* 69=不成功地带标志的状态变位传输(否定) //* 70--255=备用 //* u_char tov:扰动值的类型 //* u_short fan:故障序号 //* u_char acc:实际通道序号 //************************************************************* void MakeDisTrans_CAsdu25(u_32 commid, CMDPARAM *psCmdParam, u_char too, u_char tov, u_short fan, u_char acc) { CASDU25 bCAsdu25; memset(&bCAsdu25,0,sizeof(CASDU25)); bCAsdu25.nTYP = C_ADT_NA_3; bCAsdu25.nVSQ = 0x81; bCAsdu25.nCOT = 31; bCAsdu25.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; bCAsdu25.nFUN = psCmdParam->m_uchFun; bCAsdu25.nTOO = too; bCAsdu25.nTOV = tov; bCAsdu25.nFAN = fan; bCAsdu25.nACC = acc; MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr,\ C_SD1_NA_3, (unsigned char*)&bCAsdu25, sizeof(CASDU25), INSERT_POLL_CMD); } //************************************************************* //* 生成脉冲电度的查询命令 * //*参数:u_32 commid:RTU端口号 * //*参数:u_char addr:间隔设备地址 //************************************************************* void MakeQCC_CAsdu88(u_32 commid, CMDPARAM *psCmdParam) { CASDU88 bCAsdu88; memset(&bCAsdu88,0,sizeof(CASDU88)); bCAsdu88.nTYP = C_CI_NA_3; bCAsdu88.nVSQ = 0x81; bCAsdu88.nCOT = C_CAUSE_CYCLE; bCAsdu88.nADDR = psCmdParam->m_sDevAddr.m_uchCommAddr; // ??? wen 2003.11.03 bu(1)---bu(6) bCAsdu88.nFUN = 1;// BU(1) bCAsdu88.nINF = 0; // 使用冻结不复位命令yizhonghu 20060803 //bCAsdu88.nQCC = 5; bCAsdu88.nQCC = 45; bCAsdu88.nRII = psCmdParam->m_uchRII; MakeBuban103LinkCommand(commid, psCmdParam->m_sDevAddr.m_uchLinkAddr,\ C_SD2_NA_3 , (unsigned char*)&bCAsdu88, sizeof(CASDU88), NORMAL_POLL_CMD); } void MakeBuban103_PL1_NA_3_Cmd(int commid, DEVADDRPARAM *psAddrParam) { BUBAN103PORTPARAM *pPortParam; BUBAN103LINKDEF *pLinkParam; if(IsExtInfoPtr(commid) == FALSE) { return; } pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = (BUBAN103LINKDEF *)&pPortParam->m_psLink[psAddrParam->m_iLinkIdx]; // 多个保护设备装置 if(pLinkParam->m_iDevNum > 1) { if(pLinkParam->m_iQueryedAddr_CLASS1 != (psAddrParam->m_iDevIdx+1)) { pLinkParam->m_iQueryedAddr_CLASS1 = psAddrParam->m_iDevIdx+1; pLinkParam->m_iQueryNum_CLASS1_Count = 1; MakeBuban103LinkCommand(commid, psAddrParam->m_uchLinkAddr,\ C_PL1_NA_3, NULL, 0, INSERT_POLL_CMD); } // 如果一条链路含有多个装置的情况 else if(pLinkParam->m_uchLinkAddr != 0xFF) { pLinkParam->m_iQueryNum_CLASS1_Count = 0; MakeBuban103LinkCommand(commid,\ psAddrParam->m_uchLinkAddr,\ C_PL1_NA_3,NULL,0,INSERT_POLL_CMD); } else { if(pLinkParam->m_iQueryNum_CLASS1_Count < pLinkParam->m_iQueryNum_CLASS1_Const) { pLinkParam->m_iQueryNum_CLASS1_Count++; MakeBuban103LinkCommand(commid, psAddrParam->m_uchLinkAddr,\ C_PL1_NA_3,NULL,0,INSERT_POLL_CMD); } else { pLinkParam->m_iQueryedAddr_CLASS1 = 0; pLinkParam->m_iQueryNum_CLASS1_Count = 0; } } } else { MakeBuban103LinkCommand(commid, psAddrParam->m_uchLinkAddr,\ C_PL1_NA_3,NULL,0,INSERT_POLL_CMD); } } BOOL IsDevLinkOk(BUBAN103LINKDEF *psLinkParam, int iDevNo) { if(psLinkParam->m_uchLinkAddr == 0xFF) { return psLinkParam->m_pbLinkOk[iDevNo]; } else { return psLinkParam->m_pbLinkOk[0]; } } void SetDevLinkOk(BUBAN103LINKDEF *psLinkParam, int iDevNo, BOOL bFlagOk) { if(psLinkParam->m_uchLinkAddr == 0xFF) { psLinkParam->m_pbLinkOk[iDevNo] = bFlagOk; psLinkParam->m_pu32LinkOkCnt[iDevNo] = 0; } else { psLinkParam->m_pbLinkOk[0] = bFlagOk; psLinkParam->m_pu32LinkOkCnt[0] = 0; } } void ClearLinkCnt(BUBAN103LINKDEF *psLinkParam, int iDevNo) { if(psLinkParam->m_uchLinkAddr == 0xFF) { psLinkParam->m_pu32LinkOkCnt[iDevNo] = 0; } else { psLinkParam->m_pu32LinkOkCnt[0] = 0; } } BYTE GetLinkAddr(BUBAN103LINKDEF *psLinkParam, int iDevNo) { if(psLinkParam->m_uchLinkAddr == 0xFF) { return psLinkParam->m_psDev[iDevNo].m_sDevParam.m_u8DevAddr; } else { return psLinkParam->m_uchLinkAddr; } } BYTE *GetLinkCtrl(BUBAN103LINKDEF *psLinkParam, int iDevNo) { if(psLinkParam->m_uchLinkAddr == 0xFF) { return &psLinkParam->m_pu8CtlByte[iDevNo]; } else { return &psLinkParam->m_pu8CtlByte[0]; } } BOOL IsLinkTimeOut(BUBAN103LINKDEF *psLinkParam, int iDevNo) { int iNo; iNo = iDevNo; psLinkParam->m_pu32LinkOkCnt[iNo]++; if(psLinkParam->m_pu32LinkOkCnt[iNo]\ >= psLinkParam->m_u32TimeOutConst) { return TRUE; } return FALSE; } //*************************************************************** //* 指令发送 * //*参数:u_32 commid : RTU端口号 * //* i_32 iBuIdx : 间隔装置索引 * //*************************************************************** void Buban103SendCmdFormPollCmdBuf(int commid) { BYTE fcb = 0x20; BYTE *pu8CtrlByte, buf[256]; i_32 len; DAY_TIME sDateTime; DEVADDRPARAM DevAddrParam; BUBAN103PORTPARAM *pPortParam; if((commid < 0) || (commid >= GetMaxPort())) { return; } if(!ShmGetPortFlag(commid, FLAG_OPEN)) { return; } pPortParam = (BUBAN103PORTPARAM *)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) { len = ReGetCmdFormPollCmdBuf(commid, buf, MAX_MSG_BUF_SIZE); if(buf[2] == 0x10) { DevAddrParam.m_uchLinkAddr = buf[4]; if(FindProtectDev(pPortParam, &DevAddrParam, TRUE) == TRUE) { if(pPortParam->m_psLink[DevAddrParam.m_iLinkIdx].m_uchLinkAddr != 0xFF) { InitBuban103LinkCmdBuf(&pPortParam->m_psLink[DevAddrParam.m_iLinkIdx]); } else { DevAddrParam.m_uchCommAddr = buf[4]; InitBuban103DevCmdBuf(&pPortParam->m_psLink[DevAddrParam.m_iLinkIdx], DevAddrParam.m_iDevIdx); } } } else if(buf[2] == 0x68) { DevAddrParam.m_uchLinkAddr = buf[7]; DevAddrParam.m_uchCommAddr = buf[11]; if(FindProtectDev(pPortParam, &DevAddrParam, FALSE) == TRUE) { InitBuban103DevCmdBuf(&pPortParam->m_psLink[DevAddrParam.m_iLinkIdx], DevAddrParam.m_iDevIdx); } } else { pPortParam->m_psBaoHu->RevCmdFlag = 1; } // 清除当前命令 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->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, MAX_MSG_BUF_SIZE); } else { len = GetCmdFormPollCmdBuf(commid, buf, MAX_MSG_BUF_SIZE); } if(len < 7) { return; } #ifndef OS_LINUX if(isUdpSocketExist() == TRUE) #endif { if(buf[2] == 0x10) { DevAddrParam.m_uchLinkAddr = buf[4]; if(FindProtectDev(pPortParam, &DevAddrParam, TRUE) == FALSE) { // 清除当前命令 ClearCmdFormPollCmdBuf(commid); //ClearCmdAllFlag(commid); return; } if(PROTOCOL_MASTER == pPortParam->m_psBaoHu->PortType) { if(pPortParam->m_psBaoHu->ReSendCmdFlag) { pu8CtrlByte = GetLinkCtrl(&pPortParam->m_psLink[DevAddrParam.m_iLinkIdx], DevAddrParam.m_iDevIdx); *pu8CtrlByte = ~(*pu8CtrlByte); } pu8CtrlByte = GetLinkCtrl(&pPortParam->m_psLink[DevAddrParam.m_iLinkIdx], DevAddrParam.m_iDevIdx); buf[3] |= (fcb & *pu8CtrlByte); *pu8CtrlByte = ~(*pu8CtrlByte); } else { if(ProvHaveClassOne(commid, &DevAddrParam, pPortParam->m_bSendChangeDi) == TRUE) { buf[3] |= 0x20; } } buf[5] = CalBuban103Lpc(&buf[3], 2); } else if(buf[2] == 0x68) { DevAddrParam.m_uchLinkAddr = buf[7]; DevAddrParam.m_uchCommAddr = buf[11]; if(0xFF != DevAddrParam.m_uchLinkAddr) { if(FindProtectDev(pPortParam, &DevAddrParam, FALSE) == FALSE) { // 清除当前命令 ClearCmdFormPollCmdBuf(commid); //ClearCmdAllFlag(commid); return; } if(PROTOCOL_MASTER == pPortParam->m_psBaoHu->PortType) { if(pPortParam->m_psBaoHu->ReSendCmdFlag) { pu8CtrlByte = GetLinkCtrl(&pPortParam->m_psLink[DevAddrParam.m_iLinkIdx], DevAddrParam.m_iDevIdx); *pu8CtrlByte = ~(*pu8CtrlByte); } pu8CtrlByte = GetLinkCtrl(&pPortParam->m_psLink[DevAddrParam.m_iLinkIdx], DevAddrParam.m_iDevIdx); buf[6] |= (fcb & *pu8CtrlByte); //if(buf[7] != 0xFF) //{ // *pu8CtrlByte = ~(*pu8CtrlByte); //} *pu8CtrlByte = ~(*pu8CtrlByte); } else { if(ProvHaveClassOne(commid, &DevAddrParam, pPortParam->m_bSendChangeDi) == TRUE) { buf[6] |= 0x20; } } } if((buf[8] == C_SYN_TA_3) && (buf[3] == 15)) { GetLocalTimeEx(&sDateTime); sDateTime.mSec = sDateTime.Sec*1000 + sDateTime.mSec; buf[14] = sDateTime.mSec % 256; buf[15] = sDateTime.mSec / 256; buf[16] = (u_char)sDateTime.Min; buf[17] = (u_char)sDateTime.Hour; buf[18] = (u_char)(sDateTime.Day&0x1F); buf[19] = (u_char)sDateTime.Month; buf[20] = (u_char)(sDateTime.Year%100); } buf[buf[3]+6] = CalBuban103Lpc(&buf[6], buf[3]); } else { // 清除当前命令 ClearCmdFormPollCmdBuf(commid); //ClearCmdAllFlag(commid); return; } SendDataToPort(commid, (char *)&buf[2], len-2); pPortParam->m_psBaoHu->SendCmdFlag = 1; pPortParam->m_psBaoHu->ReSendCmdFlag = 0; pPortParam->m_psBaoHu->RevCmdFlag = 0; } #ifdef OS_LINUX 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); // 清除当前命令 } } } /*! \brief 寻找并生成下一条命令 \param u_32 portno : RTU端口号 \param i_32 iBuIdx : 间隔装置索引 */ void Buban103FindNextCmd(int commid) { int i, j, iCurCmdIdx; BYTE *pu8CtrlByte; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if((commid < 0) || (commid >= GetMaxPort())) { return; } if(!ShmGetPortFlag(commid, FLAG_OPEN)) { return; } pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; //所有的命令定时计数器+1 for(i=0; im_iLinkNum; i++) { pLinkParam = &pPortParam->m_psLink[i]; for(j=0; jm_sArrayCmdTime[j].m_iCmdTimerConst > 0) { pLinkParam->m_sArrayCmdTime[j].m_iCmdTimerCnt++; } } } //如果命令缓冲区仍有命令,则退出本函数 if(CheckPollCmdBufEmpty(commid) <= 0) { return; } pLinkParam = &pPortParam->m_psLink[pPortParam->m_iLinkIdx]; //每个地址下发一次命令,循环进行 if(pLinkParam->m_iDevIdx >= pLinkParam->m_iDevNum-1) { pLinkParam->m_iDevIdx = 0; pPortParam->m_iLinkIdx = (pPortParam->m_iLinkIdx+1) % pPortParam->m_iLinkNum; pLinkParam = &pPortParam->m_psLink[pPortParam->m_iLinkIdx]; pLinkParam->m_iDevIdx = 0; } else { pLinkParam->m_iDevIdx++; } //判断链路的状态,如果链路服务未工作或链路服务未实现,则发送请求链路状态命令继续查询链路状态,并退出本函数 // 如果链路工作正常,则继续本函数的后续工作 pDevParam = &pLinkParam->m_psDev[pLinkParam->m_iDevIdx]; if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == FALSE) { // 一条链路一次循环只进行一次链路复位 if((pLinkParam->m_uchLinkAddr != 0xFF) && (pLinkParam->m_iDevIdx != 0)) { pLinkParam->m_iDevIdx = pLinkParam->m_iDevNum - 1; return; } pu8CtrlByte = GetLinkCtrl(pLinkParam, pLinkParam->m_iDevIdx); *pu8CtrlByte = 0; MakeBuban103LinkCommand(commid, GetLinkAddr(pLinkParam, pLinkParam->m_iDevIdx), C_RCU_NA_3, NULL, 0, NORMAL_POLL_CMD); return; } //如果发送了保护程序传送过来的命令,且仍未收到结束帧,则继续召唤二级用户数据 if(pDevParam->m_bInitdata == TRUE) { pDevParam->m_u32CallCnt++; if(pDevParam->m_u32CallCnt < pLinkParam->m_u32TimeOutConst) { if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == TRUE) { MakeBuban103LinkCommand(commid,\ GetLinkAddr(pLinkParam, pLinkParam->m_iDevIdx),\ C_PL2_NA_3, NULL, 0, NORMAL_POLL_CMD); return; } } else { pDevParam->m_u32CallCnt = 0; pDevParam->m_bInitdata = FALSE; } } //判断有否保护程序传来的命令 if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == TRUE) { // wen 2004.02.11 修改保护数据下发(暂时没有下发) //seladdr = (u_char)(*(WORD*)&gBuban103_RtuMsg.MsgData[0]); //if((gBuban103_RtuMsg.MsgLen > 0) && (gBuban103_RtuMsg.PortNumber == commid)) //{ // itmpBuIdx = FindMatchingBuIdx(commid, seladdr); // if(itmpBuIdx >= 0) // { // MakeBuban103BaohuCommand(); // Buban103PortParam[commid][selidx][iBuIdx].CallCnt = 0; // Buban103PortParam[commid][selidx][iBuIdx].RstLinkOk = true; // memset((char*)&gBuban103_RtuMsg, 0, sizeof(gBuban103_RtuMsg)); // return; // } //} } iCurCmdIdx = pLinkParam->m_shCurCmdIdx; if(pDevParam->m_bAllQueryOk == TRUE) { for(i=0; im_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerConst > 0) { if(pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerCnt\ > pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerConst) { break; } } iCurCmdIdx = (iCurCmdIdx+1) % BUBAN103_TIMER_CMD_NUM; } pLinkParam->m_shCurCmdIdx = iCurCmdIdx; if(i >= BUBAN103_TIMER_CMD_NUM) { pPortParam->m_iLinkIdx = (pPortParam->m_iLinkIdx+1) % pPortParam->m_iLinkNum; } else { MakeBuban103PollingCmd(commid, pLinkParam, iCurCmdIdx); pLinkParam->m_iDevIdx = (pLinkParam->m_iDevIdx+1) % pLinkParam->m_iDevNum; if(pLinkParam->m_iDevIdx == 0) { pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerCnt = 0; pLinkParam->m_shCurCmdIdx = (pLinkParam->m_shCurCmdIdx+1) % BUBAN103_TIMER_CMD_NUM; pPortParam->m_iLinkIdx = (pPortParam->m_iLinkIdx+1) % pPortParam->m_iLinkNum; } } } //空闲时间不停地召唤二级数据 if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == TRUE) { if(CheckPollCmdBufEmpty(commid) <= 0) { return; } MakeBuban103LinkCommand(commid,\ GetLinkAddr(pLinkParam, pLinkParam->m_iDevIdx),\ C_PL2_NA_3, NULL, 0, NORMAL_POLL_CMD); } } BOOL Buban103FindNextCmdEx(int commid) { int i, j, iCurCmdIdx; BYTE *pu8CtrlByte; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; //char szbuf[128]; if((commid < 0) || (commid >= GetMaxPort())) { return FALSE; } if(!ShmGetPortFlag(commid, FLAG_OPEN)) { return FALSE; } pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; /* char szbuf[256]; FILE *fp; DAY_TIME sTime; fp = NULL; if(commid == 6) { getcwd(szbuf, sizeof(szbuf)); sprintf(szbuf, "%s/log/cmdtime.txt", szbuf); fp = fopen(szbuf, "a"); GetLocalTimeEx(&sTime); sprintf(szbuf, "wen: %02d:%02d:%02d.%03d, commid=%d calc pollcmd count.\n", sTime.Hour, sTime.Min, sTime.Sec, sTime.mSec, commid); //DebugPrint(szbuf); if(fp) fwrite(szbuf, 1, strlen(szbuf), fp); } */ //所有的命令定时计数器+1 for(i=0; im_iLinkNum; i++) { pLinkParam = &pPortParam->m_psLink[i]; if(!IsDevLinkOk(pLinkParam, i)) { continue; } for(j=0; jm_sArrayCmdTime[j].m_iCmdTimerConst > 0) { pLinkParam->m_sArrayCmdTime[j].m_iCmdTimerCnt++; } } } //如果命令缓冲区仍有命令,则退出本函数 if(CheckPollCmdBufEmpty(commid) <= 0) { return FALSE; } pLinkParam = &pPortParam->m_psLink[pPortParam->m_iLinkIdx]; pDevParam = &pLinkParam->m_psDev[pLinkParam->m_iDevIdx]; if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == FALSE) { // 一条链路一次循环只进行一次链路复位 if((pLinkParam->m_uchLinkAddr != 0xFF)\ && (pLinkParam->m_iDevIdx != 0)) { pLinkParam->m_iDevIdx = pLinkParam->m_iDevNum - 1; return TRUE; } pu8CtrlByte = GetLinkCtrl(pLinkParam, pLinkParam->m_iDevIdx); *pu8CtrlByte = 0; MakeBuban103LinkCommand(commid, GetLinkAddr(pLinkParam, pLinkParam->m_iDevIdx), C_RCU_NA_3, NULL, 0, NORMAL_POLL_CMD); return TRUE; } //如果发送了保护程序传送过来的命令,且仍未收到结束帧,则继续召唤二级用户数据 if(pDevParam->m_bInitdata == TRUE) { pDevParam->m_u32CallCnt++; if(pDevParam->m_u32CallCnt < pLinkParam->m_u32TimeOutConst) { if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == TRUE) { MakeBuban103LinkCommand(commid,\ GetLinkAddr(pLinkParam, pLinkParam->m_iDevIdx),\ C_PL2_NA_3, NULL, 0, NORMAL_POLL_CMD); return TRUE; } } else { pDevParam->m_u32CallCnt = 0; pDevParam->m_bInitdata = FALSE; } } //判断有否保护程序传来的命令 if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == TRUE) { // wen 2004.02.11 修改保护数据下发(暂时没有下发) //seladdr = (u_char)(*(WORD*)&gBuban103_RtuMsg.MsgData[0]); //if((gBuban103_RtuMsg.MsgLen > 0) && (gBuban103_RtuMsg.PortNumber == commid)) //{ // itmpBuIdx = FindMatchingBuIdx(commid, seladdr); // if(itmpBuIdx >= 0) // { // MakeBuban103BaohuCommand(); // Buban103PortParam[commid][selidx][iBuIdx].CallCnt = 0; // Buban103PortParam[commid][selidx][iBuIdx].RstLinkOk = true; // memset((char*)&gBuban103_RtuMsg, 0, sizeof(gBuban103_RtuMsg)); // return; // } //} } if(pLinkParam->m_shCurCmdIdx < BUBAN103_TIMER_CMD_NUM) { iCurCmdIdx = pLinkParam->m_shCurCmdIdx; } else { iCurCmdIdx = 0; } if(pDevParam->m_bAllQueryOk == TRUE) { for(i=0; i= BUBAN103_TIMER_CMD_NUM) { break; } if(pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerConst > 0) { if(pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerCnt\ > pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerConst) { break; } } iCurCmdIdx++; } // 如果是一条新的轮询指令,则从第一个装置开始生成指令 if(pLinkParam->m_shCurCmdIdx != iCurCmdIdx) { pLinkParam->m_iDevIdx = 0; pLinkParam->m_shCurCmdIdx = iCurCmdIdx; } if(iCurCmdIdx < BUBAN103_TIMER_CMD_NUM) { //if(iCurCmdIdx == 0) //{ // sprintf(szbuf, "%d端口时间同步过程=%d,计数=%d",commid+1,pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerConst,\ // pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerCnt); // DebugPrint(szbuf); // } MakeBuban103PollingCmd(commid, pLinkParam, iCurCmdIdx); if(pLinkParam->m_iDevIdx >= (pLinkParam->m_iDevNum-1)) { pLinkParam->m_sArrayCmdTime[iCurCmdIdx].m_iCmdTimerCnt = 0; } return TRUE; } } //空闲时间不停地召唤二级数据 //if(IsDevLinkOk(pLinkParam, pLinkParam->m_iDevIdx) == TRUE) //{ //if(CheckPollCmdBufEmpty(commid) <= 0) //{ // return; //} // MakeBuban103LinkCommand(commid,\ // GetLinkAddr(pLinkParam, pLinkParam->m_iDevIdx),\ // C_PL2_NA_3, NULL, 0, NORMAL_POLL_CMD); // return TRUE; //} MakeBuban103LinkCommand(commid,\ GetLinkAddr(pLinkParam, pLinkParam->m_iDevIdx),\ C_PL2_NA_3, NULL, 0, NORMAL_POLL_CMD); return TRUE; } void Buban103CalcNextDev(int commid, BOOL bFlag) { DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; //printf("Buban103CalcNextDev: commid_%d\n", commid); if(FALSE == GetPortParamPtr(commid, &pPortParam)) { return; } if(!ShmGetPortFlag(commid, FLAG_OPEN)) { return; } //printf("Buban103CalcNextDev: LinkIdx=%d, LinkNum=%d\n", pPortParam->m_iLinkIdx, pPortParam->m_iLinkNum); //return; if(pPortParam->m_iLinkIdx >= pPortParam->m_iLinkNum) { pPortParam->m_iLinkIdx = 0; pLinkParam = &pPortParam->m_psLink[pPortParam->m_iLinkIdx]; pLinkParam->m_iDevIdx = 0; } else { // 常规的下一个装置计算 pLinkParam = &pPortParam->m_psLink[pPortParam->m_iLinkIdx]; if(FALSE == bFlag) { if((pLinkParam->m_uchLinkAddr != 0xFF)\ && (pLinkParam->m_iDevNum > 1)) { pDevParam = &pLinkParam->m_psDev[pLinkParam->m_iDevIdx]; if(pDevParam->m_bAllQueryOk == FALSE) { pLinkParam->m_bGotoNext = TRUE; return; } // else if(增加其他的多帧传输不进行装置切换的判断) } } // 在一个装置总召唤完成以后的计算 else { pDevParam = &pLinkParam->m_psDev[pLinkParam->m_iDevIdx]; if(pLinkParam->m_bGotoNext == FALSE) { return; } if(pDevParam->m_bAllQueryOk == TRUE) { return; } // else if(增加其他的多帧传输不进行装置切换的判断) } pLinkParam->m_bGotoNext = FALSE; pLinkParam->m_iDevIdx++; if(pLinkParam->m_iDevIdx >= pLinkParam->m_iDevNum) { pLinkParam->m_iDevIdx = 0; pPortParam->m_iLinkIdx = (pPortParam->m_iLinkIdx+1) % pPortParam->m_iLinkNum; pLinkParam = &pPortParam->m_psLink[pPortParam->m_iLinkIdx]; pLinkParam->m_iDevIdx = 0; } } } //***************************************************************************/ //* 定时轮询标准103指令生成函数 */ //*参数:u_32 commid : 厂站端口号 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //* i_32 CmdIdx : 指令生成码索引号 */ //*返回值:BOOL retval : 指令生成成功标识 */ //***************************************************************************/ void MakeBuban103PollingCmd(int commid, BUBAN103LINKDEF *psLinkParam, i_32 CmdIdx) { i_32 i; DEVDEF *pDevParam; CMDPARAM CmdParam; GEN_DATAGROUP sGenDataGroup; //#ifdef _DEBUG_MSG_ char szbuf[256]; //#endif pDevParam = &psLinkParam->m_psDev[psLinkParam->m_iDevIdx]; switch(CmdIdx) { case 0:// 时间同步 // 广播对时仅执行一次 sprintf(szbuf, "port=%d,广播对时命令下发",commid+1); DebugPrint(szbuf); psLinkParam->m_sArrayCmdTime[CmdIdx].m_iCmdTimerCnt = 0; CmdParam.m_sDevAddr.m_uchLinkAddr = 0xFF; CmdParam.m_sDevAddr.m_uchCommAddr = 0xFF; CmdParam.m_uchFun = (u_char)pDevParam->m_sDevParam.m_sSyncTimeInfo.m_u8Fun; CmdParam.m_uchInf = (u_char)pDevParam->m_sDevParam.m_sSyncTimeInfo.m_u8Inf; CmdParam.m_uchRII = pDevParam->m_u8RII; MakeTimeSyn_CAsdu6(commid, &CmdParam); // 清除当前指令,指向下一个链路 psLinkParam->m_iDevIdx = psLinkParam->m_iDevNum - 1; break; case 1:// 总查询 CmdParam.m_sDevAddr.m_uchLinkAddr = psLinkParam->m_uchLinkAddr; CmdParam.m_sDevAddr.m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; if(FALSE == FindProtectDev((BUBAN103PORTPARAM *)SioParam[commid].ExtInfo, &CmdParam.m_sDevAddr, FALSE)) { break; } MakeAllQuery_CAsdu7(commid, &CmdParam); break; case 2:// 电度量查询 CmdParam.m_sDevAddr.m_uchLinkAddr = psLinkParam->m_uchLinkAddr; CmdParam.m_sDevAddr.m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; if(FALSE == FindProtectDev((BUBAN103PORTPARAM *)SioParam[commid].ExtInfo, &CmdParam.m_sDevAddr, FALSE)) { break; } CmdParam.m_uchRII = pDevParam->m_u8RII; MakeQCC_CAsdu88(commid, &CmdParam); break; case 3:// 模拟量轮询(通用分类数据) CmdParam.m_sDevAddr.m_uchLinkAddr = psLinkParam->m_uchLinkAddr; CmdParam.m_sDevAddr.m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; if(FALSE == FindProtectDev((BUBAN103PORTPARAM *)SioParam[commid].ExtInfo, &CmdParam.m_sDevAddr, FALSE)) { break; } for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(AI_PNT_TYPE == pDevParam->m_sDevParam.m_saGroupDef[i].m_iDataType) { break; } } if(i == pDevParam->m_sDevParam.m_iCfgGroupNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 不存在通用分类数据模拟量,不能生成轮询指令!!!\n", commid, CmdParam.m_sDevAddr.m_uchLinkAddr, CmdParam.m_sDevAddr.m_uchCommAddr); //前置机站号=1 DebugPrint(szbuf); #endif break; } CmdParam.m_uchInf = C_INF_READGROUPALLITEMS; sGenDataGroup.m_u8Grp = (BYTE)pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo; sGenDataGroup.m_u8Itm = 0; sGenDataGroup.m_u8KOD = KOD_ACTUALVALUE; CmdParam.m_uchRII = pDevParam->m_u8RII; MakeGenIdentCommand_CAsdu21(commid, &CmdParam, &sGenDataGroup, 1); break; case 4:// 状态量轮询(通用分类数据) CmdParam.m_sDevAddr.m_uchLinkAddr = psLinkParam->m_uchLinkAddr; CmdParam.m_sDevAddr.m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; if(FALSE == FindProtectDev((BUBAN103PORTPARAM *)SioParam[commid].ExtInfo, &CmdParam.m_sDevAddr, FALSE)) { break; } for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(DI_PNT_TYPE == pDevParam->m_sDevParam.m_saGroupDef[i].m_iDataType) { break; } } if(i == pDevParam->m_sDevParam.m_iCfgGroupNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 不存在通用分类数据开关量,不能生成轮询指令!!!\n", commid, CmdParam.m_sDevAddr.m_uchLinkAddr, CmdParam.m_sDevAddr.m_uchCommAddr); DebugPrint(szbuf); #endif break; } CmdParam.m_uchInf = C_INF_READGROUPALLITEMS; sGenDataGroup.m_u8Grp = (BYTE)pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo; sGenDataGroup.m_u8Itm = 0; sGenDataGroup.m_u8KOD = KOD_ACTUALVALUE; CmdParam.m_uchRII = pDevParam->m_u8RII; MakeGenIdentCommand_CAsdu21(commid, &CmdParam, &sGenDataGroup, 1); break; default: break; } } //===========================指令生成函数结束========================= //===========================以下为数据处理函数======================= //*************************************************************** //* 计算 Buban103 累加和检验码 * //* 参数:BYTE* msg:准备计算的数据帧信息 * //* u_32 len:准备计算的数据帧长度 * //*************************************************************** BYTE CalBuban103Lpc(BYTE *msg, u_32 len) { u_32 i; char retval; retval = 0; for(i=0; im_iRecvLen; memcpy(msg.MsgData, psPortParam->m_achRecvBuf, msg.MsgLen); msg.MsgData[msg.MsgLen] = CHECK_WHOLE; msg.MsgData[msg.MsgLen+1] = 0; // 子站数据处理 if(PROTOCOL_SLAVE == pPortParam->m_psBaoHu->PortType) { ProvRtuProtocolDataProcess(commid, &msg); return; } // 主站数据处理 switch(msg.MsgData[0]) { case 0x68: Buban103longprocess(&msg); break; case 0x10: Buban103shortprocess(&msg); break; default: break; } } // 总召唤完成后指向下一个地址 Buban103CalcNextDev(commid, TRUE); } BOOL FindProtectDev(BUBAN103PORTPARAM *psPortParam, \ DEVADDRPARAM *psAddrParam, \ BOOL bJudgeLinkOnly) { int i, j; BYTE uchAddr; BOOL bRetVal; bRetVal = FALSE; for(i=0; im_iLinkNum; i++) { if(psPortParam->m_psLink[i].m_uchLinkAddr != 0xFF) { if(psPortParam->m_psLink[i].m_uchLinkAddr != psAddrParam->m_uchLinkAddr) { continue; } uchAddr = psAddrParam->m_uchCommAddr; if(bJudgeLinkOnly == TRUE) { bRetVal = TRUE; psAddrParam->m_iLinkIdx = i; psAddrParam->m_iDevIdx = 0; break; } } else { // 装置地址就是链路地址 uchAddr = psAddrParam->m_uchLinkAddr; if(psAddrParam->m_uchLinkAddr == 0xFF) { uchAddr = psAddrParam->m_uchCommAddr; psAddrParam->m_uchLinkAddr = uchAddr; } } for(j=0; jm_psLink[i].m_iDevNum; j++) { if(psPortParam->m_psLink[i].m_psDev != NULL) { if(psPortParam->m_psLink[i].m_psDev[j].m_sDevParam.m_u8DevAddr == uchAddr) { break; } } else if(psPortParam->m_psLink[i].m_psProvDev != NULL) { if(psPortParam->m_psLink[i].m_psProvDev[j].m_iProvAddr == (int)uchAddr) { break; } } } if(j < psPortParam->m_psLink[i].m_iDevNum) { psAddrParam->m_iLinkIdx = i; psAddrParam->m_iDevIdx = j; bRetVal = TRUE; break; } } return bRetVal; } BOOL FindProtectDevFromProvAddr(BUBAN103PORTPARAM *psPortParam, \ DEVADDRPARAM *psAddrParam, \ int iProvAddr) { int i, j; BOOL bRetVal; DEVDEF *pDevParam; PROVDEVDEF *pProvDevParam; bRetVal = FALSE; for(i=0; im_iLinkNum; i++) { for(j=0; jm_psLink[i].m_iDevNum; j++) { if(psPortParam->m_psLink[i].m_psDev != NULL) { pDevParam = &psPortParam->m_psLink[i].m_psDev[j]; if(iProvAddr == pDevParam->m_sDevParam.m_iProvAddr) { psAddrParam->m_iDevIdx = j; psAddrParam->m_iLinkIdx = i; psAddrParam->m_uchLinkAddr = psPortParam->m_psLink[i].m_uchLinkAddr; psAddrParam->m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; bRetVal = TRUE; break; } } else if(psPortParam->m_psLink[i].m_psProvDev != NULL) { pProvDevParam = &psPortParam->m_psLink[i].m_psProvDev[j]; if(iProvAddr == pProvDevParam->m_iProvAddr) { psAddrParam->m_iDevIdx = j; psAddrParam->m_iLinkIdx = i; psAddrParam->m_uchLinkAddr = 0; psAddrParam->m_uchCommAddr = 0; bRetVal = TRUE; break; } } else { return FALSE; } } if(bRetVal == TRUE) { break; } } return bRetVal; } BOOL FindProtectDevFromPntNo(BUBAN103PORTPARAM *psPortParam, \ DEVADDRPARAM *psAddrParam, \ DBINFO *psDBInfo,\ int iPntNo, int itype) { int i, j, inum, ipnt; BOOL bRetVal, bProv; DEVDEF *pDevParam=NULL; PROVDEVDEF *pProvDevParam=NULL; DBORIENTATION *pDataUnit=NULL; bRetVal = FALSE; if(psPortParam->m_psLink[0].m_psDev != NULL) { pProvDevParam = NULL; bProv = FALSE; } else if(psPortParam->m_psLink[0].m_psProvDev != NULL) { pDevParam = NULL; bProv = TRUE; } else { return FALSE; } for(i=0; im_iLinkNum; i++) { for(j=0; jm_psLink[i].m_iDevNum; j++) { if(bProv == FALSE) { pDevParam = &psPortParam->m_psLink[i].m_psDev[j]; switch(itype) { case AI_PNT_TYPE: pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[0]; break; case DI_PNT_TYPE: pDataUnit = &pDevParam->m_sDevParam.m_sDiDBOrientation; break; case PI_PNT_TYPE: pDataUnit = &pDevParam->m_sDevParam.m_sPiDBOrientation; break; default: pDataUnit = NULL; break; } } else { pProvDevParam = &psPortParam->m_psLink[i].m_psProvDev[j]; switch(itype) { case DI_PNT_TYPE: pDataUnit = &pProvDevParam->m_sYxInfo; break; case AI_PNT_TYPE: case PI_PNT_TYPE: default: pDataUnit = NULL; break; } } if(pDataUnit == NULL) { continue; } if(AI_PNT_TYPE == itype) { for(inum=0; inum= 0) && (ipnt < pDataUnit[inum].m_iPntNum)) { pDataUnit = &pDataUnit[inum]; bRetVal = TRUE; break; } } } else { if(pDataUnit->m_iPntNum <= 0) { break; } ipnt = iPntNo - pDataUnit->m_iStartPntNo; if((ipnt >= 0) && (ipnt < pDataUnit->m_iPntNum)) { bRetVal = TRUE; } } if(TRUE == bRetVal) { break; } } if(bRetVal == TRUE) { break; } } if(TRUE == bRetVal) { psAddrParam->m_iDevIdx = j; psAddrParam->m_iLinkIdx = i; psAddrParam->m_uchLinkAddr = psPortParam->m_psLink[i].m_uchLinkAddr; //if(pDevParam != NULL) //{ // psAddrParam->m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; //} //else if(pProvDevParam != NULL) //{ // psAddrParam->m_uchCommAddr = (BYTE)pProvDevParam->m_iProvAddr; //} //else //{ // bRetVal = FALSE; //} if(FALSE == bProv) { psAddrParam->m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; } else { psAddrParam->m_uchCommAddr = (BYTE)pProvDevParam->m_iProvAddr; } if(psDBInfo != NULL) { memcpy((void *)psDBInfo, (void *)&pDataUnit->m_psDataInfo[ipnt], sizeof(DBINFO)); } } return bRetVal; } BOOL FindProtectDevFromYkYtPnt(BUBAN103PORTPARAM *psPortParam, \ DEVADDRPARAM *psAddrParam, \ int iYkYtPnt) { int i, j, iYkNo; BOOL bRetVal; DEVDEF *pDevParam; bRetVal = FALSE; for(i=0; im_iLinkNum; i++) { for(j=0; jm_psLink[i].m_iDevNum; j++) { pDevParam = &psPortParam->m_psLink[i].m_psDev[j]; if(pDevParam->m_sDevParam.m_sYkDBOrientation.m_iPntNum <= 0) { continue; } iYkNo = iYkYtPnt - pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo; if(iYkNo < 0) { continue; } if(iYkNo < pDevParam->m_sDevParam.m_sYkDBOrientation.m_iPntNum) { psAddrParam->m_iDevIdx = j; psAddrParam->m_iLinkIdx = i; psAddrParam->m_uchLinkAddr = psPortParam->m_psLink[i].m_uchLinkAddr; psAddrParam->m_uchCommAddr = pDevParam->m_sDevParam.m_u8DevAddr; bRetVal = TRUE; break; } } if(bRetVal == TRUE) { break; } } return bRetVal; } int FindYkPointFromDev(DBORIENTATION *psYkYtDBUnit, BYTE u8Fun, BYTE u8Inf) { int i, iYkNo; if(psYkYtDBUnit->m_iPntNum <= 0) { return -1; } for(i=0; im_iPntNum; i++) { if((psYkYtDBUnit->m_psDataInfo[i].m_u8Fun == u8Fun)\ && (psYkYtDBUnit->m_psDataInfo[i].m_u8Inf == u8Inf)) { break; } } if(i >= psYkYtDBUnit->m_iPntNum) { return -1; } iYkNo = psYkYtDBUnit->m_iStartPntNo+i; return iYkNo; } BOOL GetSpecialPtr(int commid, DEVADDRPARAM *psDevAddrParam,\ BUBAN103PORTPARAM **ppsPortParam,\ BUBAN103LINKDEF **ppsLinkParam, DEVDEF **ppsDevParam) { if(IsExtInfoPtr(commid) == FALSE) { return FALSE; } // wen 2005.06.22 修改指针判断为直接赋值 /* if((*ppsPortParam) != NULL) { *ppsPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; } if((*ppsLinkParam) != NULL) { *ppsLinkParam = &((*ppsPortParam)->m_psLink[psDevAddrParam->m_iLinkIdx]); } if((*ppsDevParam) != NULL) { *ppsDevParam = &((*ppsLinkParam)->m_psDev[psDevAddrParam->m_iDevIdx]); } */ if(ppsPortParam != NULL) { *ppsPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; } if(ppsLinkParam != NULL) { *ppsLinkParam = &((*ppsPortParam)->m_psLink[psDevAddrParam->m_iLinkIdx]); } if(ppsDevParam != NULL) { *ppsDevParam = &((*ppsLinkParam)->m_psDev[psDevAddrParam->m_iDevIdx]); } return TRUE; } BOOL GetSpecialProvPtr(int commid, DEVADDRPARAM *psDevAddrParam,\ BUBAN103PORTPARAM **ppsPortParam,\ BUBAN103LINKDEF **ppsLinkParam, PROVDEVDEF **ppsProvDevParam) { if(IsExtInfoPtr(commid) == FALSE) { return FALSE; } // wen 2005.06.22 修改指针判断为直接赋值 /* if((*ppsPortParam) != NULL) { *ppsPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; } if((*ppsLinkParam) != NULL) { *ppsLinkParam = &((*ppsPortParam)->m_psLink[psDevAddrParam->m_iLinkIdx]); } if((*ppsProvDevParam) != NULL) { *ppsProvDevParam = &((*ppsLinkParam)->m_psProvDev[psDevAddrParam->m_iDevIdx]); } */ if(ppsPortParam != NULL) { *ppsPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; } if(ppsLinkParam != NULL) { *ppsLinkParam = &((*ppsPortParam)->m_psLink[psDevAddrParam->m_iLinkIdx]); } if(ppsProvDevParam != NULL) { *ppsProvDevParam = &((*ppsLinkParam)->m_psProvDev[psDevAddrParam->m_iDevIdx]); } return TRUE; } BOOL GetPortParamPtr(int commid, BUBAN103PORTPARAM **ppsPortParam) { if(IsExtInfoPtr(commid) == FALSE) { return FALSE; } // wen 2005.06.22 修改指针判断为直接赋值 /* if((*ppsPortParam) != NULL) { *ppsPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; } else { printf("*ppsPortParam is NULL.\n"); return FALSE; } */ if(ppsPortParam != NULL) { *ppsPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; } else { return FALSE; } return TRUE; } BOOL GetOneValueOfASDU10(BYTE *pu8SourData, VALUEDEF *psValue, BYTE u8DataType, BYTE u8DataLen) { BOOL bRetVal; BYTE i, u8Len; float fValue; double dfValue; psValue->m_unValue.m_dwValue = 0; psValue->m_iDataType = DT_NO; u8Len = u8DataLen; bRetVal = TRUE; switch(u8DataType) { case DATAID_OS8ASCII: // 8位ASCII psValue->m_iDataType = DT_STRING; if(u8Len >= MAXSTRINGLEN) { u8Len = MAXSTRINGLEN-1; } for(i=0; im_szValue[i] = pu8SourData[i]; } psValue->m_szValue[i] = 0; psValue->m_iDataNum = u8Len; break; case DATAID_BSTRING: // 8位2进制数 psValue->m_iDataType = DT_CONTROL; psValue->m_iDataNum = u8Len; u8Len = (u8DataLen+7) / 8; if(u8Len > sizeof(DWORD)) { u8Len = sizeof(DWORD); psValue->m_iDataNum = u8Len*8; } for(i=0; im_unValue.m_dwValue += (pu8SourData[i] << (i*8)); } break; case DATAID_UI: // 无符号整数 psValue->m_iDataType = DT_UINT; for(i=0; im_unValue.m_uValue += (pu8SourData[i] << (i*8)); } break; case DATAID_INT: // 整数 case DATAID_EXDATA_0X24: psValue->m_iDataType = DT_INT; for(i=0; im_unValue.m_iValue += (pu8SourData[i] << (i*8)); } break; case DATAID_UFLOAT: // 无符号浮点数 psValue->m_iDataType = DT_FLOAT; fValue = *(float *)(pu8SourData); SequenceRtuToHost((char *)(&fValue), sizeof(float)); psValue->m_unValue.m_fValue = fabs(fValue); break; case DATAID_FLOAT: // 浮点数 psValue->m_iDataType = DT_FLOAT; fValue = *(float *)(pu8SourData); SequenceRtuToHost((char *)(&fValue), sizeof(float)); psValue->m_unValue.m_fValue = fValue; break; case DATAID_754SHORT: // R32.23 IEEE 标准754短实数 psValue->m_iDataType = DT_FLOAT; fValue = *(float *)(pu8SourData); SequenceRtuToHost((char *)(&fValue), sizeof(float)); psValue->m_unValue.m_fValue = fValue; break; case DATAID_754REAL: // R64.53 IEEE 标准754实数 psValue->m_iDataType = DT_FLOAT; dfValue = *(double *)(pu8SourData); SequenceRtuToHost((char *)(&dfValue), sizeof(dfValue)); psValue->m_unValue.m_fValue = dfValue; break; case DATAID_DOUBLE: // 双点信息 psValue->m_iDataType = DT_BINARY; psValue->m_iDataNum = 2; psValue->m_unValue.m_dwValue = pu8SourData[0] & 0x03; break; case DATAID_SINGLE: // 单点信息 psValue->m_iDataType = DT_BINARY; psValue->m_iDataNum = 1; psValue->m_unValue.m_dwValue = pu8SourData[0] & 0x01; break; case DATAID_13BITS: // 带品质描述的被测值(13BITS) psValue->m_iDataType = DT_UINT; psValue->m_unValue.m_uValue = pu8SourData[0]; psValue->m_unValue.m_uValue = (pu8SourData[1] & 0x1f) * 256; break; case DATAID_WITHTIME: // 带时标的报文 case DATAID_WITHTIMESPACE:// 带相对时标的报文 case DATAID_SORTIDNO: // 通用分类标识序号 case DATAID_STRUCT: // 数据结构 default: bRetVal = FALSE; break; } return bRetVal; } int FindAiGroupIdx(DBORIENTATION *pAiDB, int iMaxNum, BYTE u8Asdu, BYTE u8Fun, BYTE u8Inf) { int idx; for(idx = 0; idx < iMaxNum; idx++) { if(pAiDB[idx].m_psDataInfo == NULL) { continue; } if(u8Asdu == pAiDB[idx].m_psDataInfo[0].m_u8Asdu) { if((u8Fun == pAiDB[idx].m_psDataInfo[0].m_u8Fun)\ && (u8Inf == pAiDB[idx].m_psDataInfo[0].m_u8Inf)) { break; } } } return idx; } //*************************************************************** //* 接收的数据为固定帧长时的处理程序 //*参数 RTUMSG* rtumsg:接收到的数据信息 //*************************************************************** void Buban103shortprocess(RTUMSG *rtumsg) { BOOL bHaveClass1; int commid; DEVADDRPARAM sDevAddrParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; sDevAddrParam.m_uchLinkAddr = rtumsg->MsgData[2]; sDevAddrParam.m_uchCommAddr = 0; if(FindProtectDev(pPortParam, &sDevAddrParam, TRUE) == FALSE) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 不在端口配置保护范围内!!!", commid, sDevAddrParam.m_uchLinkAddr, sDevAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif return; } else { //printf("find is right and exit.\n"); //return; #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d linkidx=%d, iDevIdx=%d.", commid, sDevAddrParam.m_uchLinkAddr, sDevAddrParam.m_uchCommAddr, sDevAddrParam.m_iLinkIdx, sDevAddrParam.m_iDevIdx); DebugPrint(szbuf); #endif //Buban103DispConfig(commid, pPortParam); //return; pLinkParam = &pPortParam->m_psLink[sDevAddrParam.m_iLinkIdx]; SetProtectDevStatus(pLinkParam, sDevAddrParam.m_iDevIdx, TRUE); ClearLinkCnt(pLinkParam, sDevAddrParam.m_iDevIdx); } bHaveClass1 = FALSE; if(rtumsg->MsgData[1] & 0x10) { pLinkParam->m_iQueryedAddr_CLASS1 = 0; pLinkParam->m_iQueryNum_CLASS1_Count = 0; } else { if(rtumsg->MsgData[1] & 0x20) { bHaveClass1 = TRUE; MakeBuban103_PL1_NA_3_Cmd(commid, &sDevAddrParam); } else { pLinkParam->m_iQueryedAddr_CLASS1 = 0; pLinkParam->m_iQueryNum_CLASS1_Count = 0; } } switch(rtumsg->MsgData[1] & 0x0f) { case M_CON_NA_3://确认帧 SetDevLinkOk(pLinkParam, sDevAddrParam.m_iDevIdx, TRUE); if(pLinkParam->m_bRstLinkOk == TRUE) { pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bInitdata = TRUE; } break; case M_BY_NA_3://忙帧(确认帧) pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bInitdata = TRUE; break; case M_NV_NA_3://无所要求的数据帧回答 if(FALSE == bHaveClass1) { pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bInitdata = TRUE; pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bAllQueryOk = TRUE; } break; case M_LKR_NA_3_1://链路工作正常 SetDevLinkOk(pLinkParam, sDevAddrParam.m_iDevIdx, TRUE); break; case M_LKR_NA_3_2://链路服务未工作 SetDevLinkOk(pLinkParam, sDevAddrParam.m_iDevIdx, FALSE); break; case M_LKR_NA_3_3://链路服务未实现 SetDevLinkOk(pLinkParam, sDevAddrParam.m_iDevIdx, FALSE); break; default: #ifdef _DEBUG_MSG_ //OutputDebugString("接收到不认识的命令,请检查程序.\n"); DebugPrint("接收到不认识的命令,请检查程序.\n"); #endif break; } } //*************************************************************** //* 接收的数据为可变帧长时的处理程序 //*参数 RTUMSG* rtumsg:接收到的数据信息 //*************************************************************** void Buban103longprocess(RTUMSG *rtumsg) { int commid; DEVADDRPARAM sDevAddrParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; sDevAddrParam.m_uchLinkAddr = rtumsg->MsgData[5]; sDevAddrParam.m_uchCommAddr = rtumsg->MsgData[9]; if(FindProtectDev(pPortParam, &sDevAddrParam, FALSE) == FALSE) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 不在端口配置保护范围内!!!", commid, sDevAddrParam.m_uchLinkAddr, sDevAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif return; } else { pLinkParam = &pPortParam->m_psLink[sDevAddrParam.m_iLinkIdx]; SetProtectDevStatus(pLinkParam, sDevAddrParam.m_iDevIdx, TRUE); ClearLinkCnt(pLinkParam, sDevAddrParam.m_iDevIdx); } if(rtumsg->MsgData[4] & 0x10) { pLinkParam->m_iQueryedAddr_CLASS1 = 0; pLinkParam->m_iQueryNum_CLASS1_Count = 0; } else { if(rtumsg->MsgData[4] & 0x20) { MakeBuban103_PL1_NA_3_Cmd(commid, &sDevAddrParam); } else { if(pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bAllQueryOk == FALSE) { pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bAllQueryOk = TRUE; } pLinkParam->m_iQueryedAddr_CLASS1 = 0; pLinkParam->m_iQueryNum_CLASS1_Count = 0; } } switch(rtumsg->MsgData[6])//类型标识域 { case M_TM_TA_3: // 1带时标的报文 Buban103TMprocess(rtumsg, &sDevAddrParam); break; case M_TMR_TA_3: // 2带相对时间的时标报文 Buban103TMRprocess(rtumsg, &sDevAddrParam); break; case M_MEI_NA_3: // 3被测值I报文 Buban103MEIprocess(rtumsg, &sDevAddrParam); break; case M_TME_TA_3: // 4带相对时间的有时标的被测值报文 Buban103TMEprocess(rtumsg, &sDevAddrParam); break; case M_IRC_NA_3: // 5标识报文 Buban103IRCprocess(rtumsg, &sDevAddrParam); break; case M_SYN_TA_3: // 6时间同步报文 Buban103SynTime(rtumsg, &sDevAddrParam); break; case M_TGI_NA_3: // 8总查询(总召唤)中止报文 pLinkParam->m_bRstLinkOk = FALSE; pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bInitdata = FALSE; pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bAllQueryOk = TRUE; break; case M_MEII_NA_3: // 9被测值II报文 Buban103MEIINAprocess(rtumsg, &sDevAddrParam); break; case M_GD_NTA_3: // 10通用分类数据报文 //如果NGD的COUNT位为零,则表示该批通用分类数据传输结束 if((rtumsg->MsgData[13] & 0x80) == 0) { pLinkParam->m_bRstLinkOk = FALSE; pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bInitdata = FALSE; } Buban103GDprocess(rtumsg, &sDevAddrParam); break; case M_GI_NTA_3: // 11通用分类标识报文 Buban103GIprocess(rtumsg, &sDevAddrParam); break; // wen 2003.10.27 增加扰动数据的处理 case M_LRD_TA_3: // 23被记录扰动表报文 Buban103LRDprocess(rtumsg); break; case M_RTD_TA_3: // 26扰动数据传输准备就绪报文 Buban103RTDprocess(rtumsg); break; case M_RTC_NA_3: // 27被记录的通道传输准备就绪报文 Buban103RTCprocess(rtumsg); break; case M_RTT_NA_3: // 28带标志的状态变位的传输准备就绪报文 Buban103RTTprocess(rtumsg); break; case M_TOT_TA_3: // 29带标志的状态变位传输报文 Buban103TOTprocess(rtumsg); break; case M_TOV_NA_3: // 30传输扰动值报文 Buban103TOVprocess(rtumsg); break; case M_EOT_TA_3: // 31传输结束报文 Buban103EOTprocess(rtumsg); pLinkParam->m_bRstLinkOk = FALSE; pLinkParam->m_psDev[sDevAddrParam.m_iDevIdx].m_bInitdata = FALSE; break; case M_MEIII_TA_3: // 32带时标的被测值Ⅲ Buban103MEIIITAprocess(rtumsg, &sDevAddrParam); break; case M_MEIV_TA_3: // 33带时标的被测值Ⅳ Buban103MEIVTAprocess(rtumsg, &sDevAddrParam); break; case M_MEV_TA_3: // 34带时标的被测值Ⅴ Buban103MEVTAprocess(rtumsg, &sDevAddrParam); break; case M_MEVI_TA_3: // 35带时标的被测值Ⅵ Buban103MEVITAprocess(rtumsg, &sDevAddrParam); break; case M_IT_NA_3: // 36电能脉冲计数值 Buban103ITNAprocess(rtumsg, &sDevAddrParam); break; case M_IT_TA_3: // 37带时标的电能脉冲计数值 //Buban103MEITTAprocess(rtumsg, &sDevAddrParam); break; case M_ST_NA_3: // 38步位置信息 Buban103STNAprocess(rtumsg, &sDevAddrParam); break; case M_ST_TA_3: // 39带时标的步位置信息 //Buban103STTAprocess(rtumsg, &sDevAddrParam); break; case M_SP_NA_3: // 40单点状态信息 Buban103SPNAprocess(rtumsg, &sDevAddrParam); break; case M_SP_TA_3: // 41带时标的单点状态信息 Buban103SPTAprocess(rtumsg, &sDevAddrParam); break; case M_DP_NA_3: // 42双点状态信息 Buban103DPNAprocess(rtumsg, &sDevAddrParam); break; case M_DP_TA_3: // 43带时标的双点状态信息 Buban103DPTAprocess(rtumsg, &sDevAddrParam); break; case M_SS_NA_3: // 44单点状态和状态变位检出 Buban103SSNAprocess(rtumsg, &sDevAddrParam); break; case M_SS_TA_3: // 45带时标的单点状态和状态变位检出 Buban103SSTAprocess(rtumsg, &sDevAddrParam); break; case M_DS_NA_3: // 46双点状态和状态变位检出 Buban103DSNAprocess(rtumsg, &sDevAddrParam); break; case M_DS_TA_3: // 47带时标的双点状态和状态变位检出 Buban103DSTAprocess(rtumsg, &sDevAddrParam); break; case M_WL_TA_3: // 48水位 Buban103WLTAprocess(rtumsg, &sDevAddrParam); break; case M_MEVII_NA_3: // 50被测值Ⅶ Buban103MEVIINAprocess(rtumsg, &sDevAddrParam); break; case C_DC_NA_3: // 64控制断路器命令 Buban103YkAck(rtumsg, &sDevAddrParam); break; case C_RC_NA_3: // 65升降命令 Buban103YtAck(rtumsg, &sDevAddrParam); break; case C_SE_NA_3: // 66设定命令 break; case C_CC_NA_3: // 67控制命令 break; case M_EX_PI_3: // 205西门子公司扩展电度数据 Buban103EXPIprocess(rtumsg, &sDevAddrParam); break; default: #ifdef _DEBUG_MSG_ DebugPrint("接收到不认识的命令,请检查程序.\n"); #endif break; } } void Buban103TMprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) // 可变结构限定词(VSQ)=0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) //rtumsg->MsgData[11]; // DPI //rtumsg->MsgData[12]; // 四个八位位组二进制时间 //rtumsg->MsgData[13]; // 附加信息 //rtumsg->MsgData[17]; Buban103TMprocessOfSoe(rtumsg, psDevAddrParam); // wen 2004.01.12 上送给保护管理程序 //Buban103TMprocessOfPEvent(rtumsg, psDevAddrParam); } void Buban103TMprocessOfSoe(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int i, dipnt, commid, iYkNo; BYTE buf[16], st; // 事件发生时间毫秒数 time_t iTime; WORD wMillSeconds; struct tm *ptrtm; DI_DEF pntmsg; SOE_DEF sSoeData; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) //rtumsg->MsgData[11]; // DPI //rtumsg->MsgData[12]; // 四个八位位组二进制时间 //rtumsg->MsgData[13]; // 附加信息 //rtumsg->MsgData[17]; commid = rtumsg->PortIdx; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; pDevParam = &pLinkParam->m_psDev[psDevAddrParam->m_iDevIdx]; pDataUnit = &pDevParam->m_sDevParam.m_sDiDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU1信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } for(i=0; im_iPntNum; i++) { // wen 2004.04.11 增加asdu类型判断 if(pLinkParam->m_iJudgeAsduNo != 0) { if(M_TM_TA_3 != pDataUnit->m_psDataInfo[i].m_u8Asdu) { continue; } } if((pDataUnit->m_psDataInfo[i].m_u8Fun == rtumsg->MsgData[10])\ && (pDataUnit->m_psDataInfo[i].m_u8Inf == rtumsg->MsgData[11])) { break; } } if(i >= pDataUnit->m_iPntNum) { //遥控遥调返校 if(M_CAUSE_REMOTE != rtumsg->MsgData[8]) { return; } iYkNo = FindYkPointFromDev(&pDevParam->m_sDevParam.m_sYkDBOrientation, rtumsg->MsgData[10], rtumsg->MsgData[11]); if(iYkNo >= 0) { // 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=失败) // 在转发遥控数据点中,只保留了要转发的控点号,实际的端口号应该是该转发点的端口 // 该转发点并没有指定虚拟的转发控点,则控点和转发点的点号一致。 buf[0] = (BYTE)(commid & 0xFF); buf[1] = (BYTE)((commid & 0xFF00) << 8); buf[2] = (BYTE)((commid & 0xFF0000) << 16); buf[3] = (BYTE)((commid & 0xFF000000) << 24); buf[4] = (BYTE)(iYkNo & 0xFF); buf[5] = (BYTE)((iYkNo & 0xFF00) << 8); buf[6] = (BYTE)((iYkNo & 0xFF0000) << 16); buf[7] = (BYTE)((iYkNo & 0xFF000000) << 24); buf[8] = STEP_YKYT_EXEC; buf[9] = rtumsg->MsgData[12] | 0x80; if(ShmGetDispYkYtFlag()) { #ifdef _DEBUG_MSG_ //sprintf(szbuf, "端口%d 链路地址=%d 装置地址%d RII=0x%02x, 遥控点号=%d, op=0x%02x!!!\n", // commid, rtumsg->MsgData[5], rtumsg->MsgData[9], rtumsg->MsgData[13], iYkNo, rtumsg->MsgData[12]); //DebugPrint(szbuf); sprintf(szbuf, "TIP_(%04d): commid=%d linkaddr=%d devaddr=%d RII=0x%02x ykytpnt=%d, op=0x%02x.\n", _getpid(), commid, rtumsg->MsgData[5], rtumsg->MsgData[9], rtumsg->MsgData[13], iYkNo, rtumsg->MsgData[12]); DebugPrint(szbuf); #endif } Buban103YkYtProcess(commid, buf, 10); } return; } dipnt = pDataUnit->m_iStartPntNo + i; st = rtumsg->MsgData[12] & 0x03; if((st == 0) || (st == 3)) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d 链路地址=%d 装置地址%d RII=%d, 点号=%d, status=%d!!!\n", commid, rtumsg->MsgData[5], rtumsg->MsgData[9], dipnt, rtumsg->MsgData[12]); DebugPrint(szbuf); #endif return; } st--; pntmsg.Status = st; // 属于自发或者突发事件就是soe //if(rtumsg->MsgData[8] == M_CAUSE_AUTOSEND) if(rtumsg->MsgData[8] != M_CAUSE_QUERY) { // 事件发生时间毫秒数 time(&iTime); ptrtm = localtime(&iTime); if(ptrtm->tm_hour < (rtumsg->MsgData[16] & 0x1f)) { iTime -= 24 * 3600; ptrtm = localtime(&iTime); } ptrtm->tm_hour = rtumsg->MsgData[16] & 0x1f; ptrtm->tm_min = rtumsg->MsgData[15] & 0x3f; wMillSeconds = rtumsg->MsgData[13] + rtumsg->MsgData[14]*256; ptrtm->tm_sec = wMillSeconds / 1000; wMillSeconds %= 1000; sSoeData.bStatus = st; sSoeData.iPntNo = dipnt; sSoeData.u8Type = 1;// ASDU1 sSoeData.wFaultNo = 0; sSoeData.u8ProvFun = pDataUnit->m_psDataInfo[i].m_u8ProvFun; sSoeData.u8ProvInf = pDataUnit->m_psDataInfo[i].m_u8ProvInf; sSoeData.wRelativeTime = 0; sSoeData.SoeTime.Year = ptrtm->tm_year+1900; sSoeData.SoeTime.Month = (BYTE)(ptrtm->tm_mon+1); sSoeData.SoeTime.Day = (BYTE)(ptrtm->tm_mday); sSoeData.SoeTime.Hour = (BYTE)(ptrtm->tm_hour); sSoeData.SoeTime.Min = (BYTE)(ptrtm->tm_min); sSoeData.SoeTime.Sec = (BYTE)(ptrtm->tm_sec); sSoeData.SoeTime.mSec = wMillSeconds; SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&sSoeData, DI_PNT_TYPE, PNT_SOE_TIME_EX); } SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); } void Buban103TMRprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) //rtumsg->MsgData[11]; // DPI //rtumsg->MsgData[12]; // 相对时间 //rtumsg->MsgData[13]; // 故障序号 //rtumsg->MsgData[15]; // 四个八位位组二进制时间 //rtumsg->MsgData[17]; // 附加信息 //rtumsg->MsgData[21]; Buban103TMRprocessOfSoe(rtumsg, psDevAddrParam); // wen 2004.01.12 上送给保护管理程序 //Buban103TMRprocessOfPEvent(rtumsg, psDevAddrParam); } void Buban103TMRprocessOfSoe(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int i, dipnt, commid; BYTE st; // 事件发生时间毫秒数 time_t iTime; WORD wMillSeconds, wTime, wFault; struct tm *ptrtm; DI_DEF pntmsg; SOE_DEF sSoeData; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) //rtumsg->MsgData[11]; // DPI //rtumsg->MsgData[12]; // 相对时间 //rtumsg->MsgData[13]; // 故障序号 //rtumsg->MsgData[15]; // 四个八位位组二进制时间 //rtumsg->MsgData[17]; // 附加信息 //rtumsg->MsgData[21]; commid = rtumsg->PortIdx; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; pDevParam = &pLinkParam->m_psDev[psDevAddrParam->m_iDevIdx]; pDataUnit = &pDevParam->m_sDevParam.m_sDiDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU2信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } for(i=0; im_iPntNum; i++) { // wen 2004.04.11 增加asdu类型判断 if(pLinkParam->m_iJudgeAsduNo != 0) { if(M_TMR_TA_3 != pDataUnit->m_psDataInfo[i].m_u8Asdu) { continue; } } if((pDataUnit->m_psDataInfo[i].m_u8Fun == rtumsg->MsgData[10])\ && (pDataUnit->m_psDataInfo[i].m_u8Inf == rtumsg->MsgData[11])) { break; } } if(i >= pDataUnit->m_iPntNum) { return; } dipnt = pDataUnit->m_iStartPntNo + i; if(rtumsg->MsgData[8] == M_CAUSE_QUERY) { // 相对时间和故障序号是无关的 } else { // 相对时间和故障序号是相关的 } st = rtumsg->MsgData[12] & 0x03; if((st == 0) || (st == 3)) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d 链路地址=%d 装置地址%d 点号=%d, status=%d!!!\n", commid, rtumsg->MsgData[5], rtumsg->MsgData[9], dipnt, rtumsg->MsgData[12]); DebugPrint(szbuf); #endif return; } wTime = rtumsg->MsgData[13] + rtumsg->MsgData[14]*256; wFault= rtumsg->MsgData[15] + rtumsg->MsgData[16]*256; st--; pntmsg.Status = st; // 属于自发或者突发事件就是soe //if(rtumsg->MsgData[8] == M_CAUSE_AUTOSEND) if(rtumsg->MsgData[8] != M_CAUSE_QUERY) { // 事件发生时间毫秒数 time(&iTime); ptrtm = localtime(&iTime); if(ptrtm->tm_hour < (rtumsg->MsgData[20] & 0x1f)) { iTime -= 24 * 3600; ptrtm = localtime(&iTime); } ptrtm->tm_hour = rtumsg->MsgData[20] & 0x1f; ptrtm->tm_min = rtumsg->MsgData[19] & 0x3f; wMillSeconds = rtumsg->MsgData[17] + rtumsg->MsgData[18]*256; ptrtm->tm_sec = wMillSeconds / 1000; wMillSeconds %= 1000; sSoeData.bStatus = st; sSoeData.iPntNo = dipnt; sSoeData.u8Type = 2;// ASDU2 sSoeData.wFaultNo = wFault; sSoeData.wRelativeTime = wTime; sSoeData.u8ProvFun = pDataUnit->m_psDataInfo[i].m_u8ProvFun; sSoeData.u8ProvInf = pDataUnit->m_psDataInfo[i].m_u8ProvInf; sSoeData.SoeTime.Year = ptrtm->tm_year+1900; sSoeData.SoeTime.Month = (BYTE)(ptrtm->tm_mon+1); sSoeData.SoeTime.Day = (BYTE)(ptrtm->tm_mday); sSoeData.SoeTime.Hour = (BYTE)(ptrtm->tm_hour); sSoeData.SoeTime.Min = (BYTE)(ptrtm->tm_min); sSoeData.SoeTime.Sec = (BYTE)(ptrtm->tm_sec); sSoeData.SoeTime.mSec = wMillSeconds; SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&sSoeData, DI_PNT_TYPE, PNT_SOE_TIME_EX); } SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); } void Buban103MEIprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int commid; int i, aipnt, iNum, idx; AI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) //rtumsg->MsgData[11]; // B相电流 //rtumsg->MsgData[12]; // AB相线电流 //rtumsg->MsgData[14]; // 有功功率 //rtumsg->MsgData[16]; // 无功功率 //rtumsg->MsgData[18]; commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // wen 2004.02.04 配置与测量值类型不固定关联 // 总共7组被测值 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*for(idx = 0; idx < DEV_AI_MAXNUM; idx++) { if(pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo == NULL) { continue; } if(M_MEI_NA_3 == pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo[0].m_u8Asdu) { break; } }*/ //=================================================================================================== idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_MEI_NA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU3(%d,%d) 测量值Ⅰ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU3(%d,%d) 测量值Ⅰ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } //if((rtumsg->MsgData[10] != pDataUnit->m_psDataInfo[0].m_u8Fun)\ // || (rtumsg->MsgData[11] != pDataUnit->m_psDataInfo[0].m_u8Inf)) //{ // return; //} iNum = rtumsg->MsgData[7] & 0x7f; if(iNum > pDataUnit->m_iPntNum) { iNum = pDataUnit->m_iPntNum; } aipnt = pDataUnit->m_iStartPntNo; for(i=0; iMsgData[12+2*i]&0xf8) + rtumsg->MsgData[13+2*i] * 256); pntmsg.RawValue /= 8; SetPntMsg(pDataUnit->m_iStnNo-1, aipnt+i, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); } } void Buban103TMEprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int commid; int idx; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) //rtumsg->MsgData[11]; // DPI //rtumsg->MsgData[12]; // 相对时间 //rtumsg->MsgData[13]; // 故障序号 //rtumsg->MsgData[15]; // 四个八位位组二进制时间 //rtumsg->MsgData[17]; // 附加信息 //rtumsg->MsgData[21]; return; commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // wen 2004.02.04 配置与测量值类型不固定关联 // 总共7组被测值 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*for(idx = 0; idx < DEV_AI_MAXNUM; idx++) { if(pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo == NULL) { continue; } if(M_TME_TA_3 == pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo[0].m_u8Asdu) { break; } }*/ //=================================================================================================== idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_TME_TA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU4(%d,%d) 不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU4(%d,%d) 不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } } void Buban103IRCprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int commid; CMDPARAM sCmdParam; // 传送原因 if(rtumsg->MsgData[8] == M_CAUSE_POWERON) { commid = rtumsg->PortIdx; memcpy((void *)&sCmdParam.m_sDevAddr, (void *)psDevAddrParam, sizeof(DEVADDRPARAM)); sCmdParam.m_uchFun = 255; sCmdParam.m_uchInf = 0; MakeAllQuery_CAsdu7(commid, &sCmdParam); } } void Buban103MEIINAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) //rtumsg->MsgData[11]; // A相电流 //rtumsg->MsgData[12]; // B相电流 //rtumsg->MsgData[14]; // C相电流 //rtumsg->MsgData[16]; // A相电压 //rtumsg->MsgData[18]; // B相电压 //rtumsg->MsgData[20]; // C相电压 //rtumsg->MsgData[22]; // 有功功率 //rtumsg->MsgData[24]; // 无功功率 //rtumsg->MsgData[26]; // 频率 //rtumsg->MsgData[28]; int commid; int i, aipnt, iNum, idx; AI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // 总共7组被测值 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*for(idx = 0; idx < DEV_AI_MAXNUM; idx++) { if(pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo == NULL) { continue; } if(M_MEII_NA_3 == pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo[0].m_u8Asdu) { break; } }*/ //=================================================================================================== idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_MEII_NA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU9(%d,%d) 测量值Ⅱ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU9(%d,%d) 测量值Ⅱ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } //if((rtumsg->MsgData[10] != pDataUnit->m_psDataInfo[0].m_u8Fun)\ // || (rtumsg->MsgData[11] != pDataUnit->m_psDataInfo[0].m_u8Inf)) //{ // return; //} iNum = rtumsg->MsgData[7] & 0x7f; if(iNum > pDataUnit->m_iPntNum) { iNum = pDataUnit->m_iPntNum; } aipnt = pDataUnit->m_iStartPntNo; for(i=0; iMsgData[12+2*i] & 0x01); // 品质描述,数据无效 //if(rtumsg->MsgData[12+2*i] & 0x02); // 最低3位为品质描述 pntmsg.RawValue = (short)((rtumsg->MsgData[12+2*i]&0xf8) + rtumsg->MsgData[13+2*i] * 256); pntmsg.RawValue /= 8; SetPntMsg(pDataUnit->m_iStnNo-1, aipnt+i, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); } } void Buban103MEIIITAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) // = 144 --- 147 //rtumsg->MsgData[11]; // L2电流 //rtumsg->MsgData[12]; // L1-L2电流 //rtumsg->MsgData[14]; // 有功功率 //rtumsg->MsgData[16]; // 无功功率 //rtumsg->MsgData[18]; // 被测谐波值1(3 BYTES) //rtumsg->MsgData[20]; // ... ... // 被测谐波值N(3 BYTES) // 四个八位位组的二进制时标 int commid; int i, aipnt, iNum, idx; AI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // 总共7组被测值 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*for(idx = 0; idx < DEV_AI_MAXNUM; idx++) { if(pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo == NULL) { continue; } if(M_MEIII_TA_3 == pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo[0].m_u8Asdu) { break; } }*/ //=================================================================================================== idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_MEIII_TA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU32(%d,%d) 测量值Ⅲ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU32(%d,%d) 测量值Ⅲ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } //if((rtumsg->MsgData[10] != pDataUnit->m_psDataInfo[0].m_u8Fun)\ // || (rtumsg->MsgData[11] != pDataUnit->m_psDataInfo[0].m_u8Inf)) //{ // return; //} iNum = rtumsg->MsgData[7] & 0x7f; if(iNum > pDataUnit->m_iPntNum) { iNum = pDataUnit->m_iPntNum; } aipnt = pDataUnit->m_iStartPntNo; // wen 2003.11.01 大于4以后的为谐波值和二进制时标 iNum = 4; for(i=0; iMsgData[12+2*i]&0xf8) + rtumsg->MsgData[13+2*i] * 256); pntmsg.RawValue /= 8; SetPntMsg(pDataUnit->m_iStnNo-1, aipnt+i, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); } } void Buban103MEIVTAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) = 148 //rtumsg->MsgData[11]; // L1电流 //rtumsg->MsgData[12]; // L2电流 //rtumsg->MsgData[14]; // L3电流 //rtumsg->MsgData[16]; // Ul1电压 //rtumsg->MsgData[18]; // Ul2电压 //rtumsg->MsgData[20]; // Ul3电压 //rtumsg->MsgData[22]; // 有功功率 //rtumsg->MsgData[24]; // 无功功率 //rtumsg->MsgData[26]; // 频率 //rtumsg->MsgData[28]; // 被测谐波值1(3 BYTES) //rtumsg->MsgData[30]; // ... ... // 被测谐波值N(3 BYTES) // 四个八位位组的二进制时标 int commid; int i, aipnt, iNum, idx; AI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // 总共7组被测值 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*for(idx = 0; idx < DEV_AI_MAXNUM; idx++) { if(pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo == NULL) { continue; } if(M_MEIV_TA_3 == pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo[0].m_u8Asdu) { break; } }*/ //=================================================================================================== idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_MEIV_TA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU33(%d,%d) 测量值Ⅳ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU33(%d,%d) 测量值Ⅳ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } //if((rtumsg->MsgData[10] != pDataUnit->m_psDataInfo[0].m_u8Fun)\ // || (rtumsg->MsgData[11] != pDataUnit->m_psDataInfo[0].m_u8Inf)) //{ // return; //} iNum = rtumsg->MsgData[7] & 0x7f; if(iNum > pDataUnit->m_iPntNum) { iNum = pDataUnit->m_iPntNum; } aipnt = pDataUnit->m_iStartPntNo; // wen 2003.11.01 大于9以后的为谐波值和二进制时标 iNum = 9; for(i=0; iMsgData[12+2*i]&0xf8) + rtumsg->MsgData[13+2*i] * 256); pntmsg.RawValue /= 8; SetPntMsg(pDataUnit->m_iStnNo-1, aipnt+i, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); } } // 被测值V报文 void Buban103MEVTAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) // = 144 --- 147 //rtumsg->MsgData[11]; // 以下值为向量 // L2电流 //rtumsg->MsgData[12]; // L1-L2电流 //rtumsg->MsgData[16]; // 有功功率 //rtumsg->MsgData[20]; // 无功功率 //rtumsg->MsgData[24]; // 被测谐波值1(4 BYTES) //rtumsg->MsgData[28]; // ... ... // 被测谐波值N(4 BYTES) // 四个八位位组的二进制时标 int commid; int aipnt, iNum, idx; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // 总共7组被测值 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*for(idx = 0; idx < DEV_AI_MAXNUM; idx++) { if(pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo == NULL) { continue; } if(M_MEV_TA_3 == pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo[0].m_u8Asdu) { break; } }*/ //=================================================================================================== idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_MEV_TA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU34(%d,%d) 测量值Ⅴ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU34(%d,%d) 测量值Ⅴ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } //if((rtumsg->MsgData[10] != pDataUnit->m_psDataInfo[0].m_u8Fun)\ // || (rtumsg->MsgData[11] != pDataUnit->m_psDataInfo[0].m_u8Inf)) //{ // return; //} iNum = rtumsg->MsgData[7] & 0x7f; if(iNum > pDataUnit->m_iPntNum) { iNum = pDataUnit->m_iPntNum; } aipnt = pDataUnit->m_iStartPntNo; } // 被测值VI报文 void Buban103MEVITAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF) = 148 //rtumsg->MsgData[11]; // L1电流 //rtumsg->MsgData[12]; // L2电流 //rtumsg->MsgData[16]; // L3电流 //rtumsg->MsgData[20]; // Ul1电压 //rtumsg->MsgData[24]; // Ul2电压 //rtumsg->MsgData[28]; // Ul3电压 //rtumsg->MsgData[32]; // 视在功率 //rtumsg->MsgData[36]; // 频率 //rtumsg->MsgData[38]; // 频率变化率 df/dt //rtumsg->MsgData[40]; // 被测谐波值向量1(3 BYTES) //rtumsg->MsgData[42]; // ... ... // 被测谐波值向量N(3 BYTES) // 四个八位位组的二进制时标 int commid; int aipnt, iNum, idx; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // 总共7组被测值 //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ /*for(idx = 0; idx < DEV_AI_MAXNUM; idx++) { if(pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo == NULL) { continue; } if(M_MEVI_TA_3 == pDevParam->m_sDevParam.m_sAiDBOrientation[idx].m_psDataInfo[0].m_u8Asdu) { break; } }*/ //=================================================================================================== idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_MEVI_TA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU35(%d,%d) 测量值Ⅵ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU35(%d,%d) 测量值Ⅵ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } //if((rtumsg->MsgData[10] != pDataUnit->m_psDataInfo[0].m_u8Fun)\ // || (rtumsg->MsgData[11] != pDataUnit->m_psDataInfo[0].m_u8Inf)) //{ // return; //} iNum = rtumsg->MsgData[7] & 0x7f; if(iNum > pDataUnit->m_iPntNum) { iNum = pDataUnit->m_iPntNum; } aipnt = pDataUnit->m_iStartPntNo; } // 被测值VII报文 void Buban103MEVIINAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(92 --- 148) //rtumsg->MsgData[11]; // 被测值1 //rtumsg->MsgData[12]; // 被测值2 //rtumsg->MsgData[14]; // ... ... // 被测值n //rtumsg->MsgData[10+2*N]; int commid; int i, aipnt, iNum, idx; AI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // 总共7组被测值 idx = FindAiGroupIdx(pDevParam->m_sDevParam.m_sAiDBOrientation, DEV_AI_MAXNUM, M_MEVII_NA_3, rtumsg->MsgData[10], rtumsg->MsgData[11]); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(idx >= DEV_AI_MAXNUM) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU50(%d,%d) 测量值Ⅶ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } else { pDataUnit = &pDevParam->m_sDevParam.m_sAiDBOrientation[idx]; } if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU50(%d,%d) 测量值Ⅶ不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, rtumsg->MsgData[10], rtumsg->MsgData[11]); DebugPrint(szbuf); #endif return; } iNum = rtumsg->MsgData[7] & 0x7f; if(iNum > pDataUnit->m_iPntNum) { iNum = pDataUnit->m_iPntNum; } aipnt = pDataUnit->m_iStartPntNo; // wen 2003.11.01 大于9以后的为谐波值和二进制时标 // 南瑞103没有此要求 20060803 yizhonghu // iNum = 9; for(i=0; iMsgData[12+2*i]&0xf8) + rtumsg->MsgData[13+2*i] * 256); pntmsg.RawValue /= 8; SetPntMsg(pDataUnit->m_iStnNo-1, aipnt+i, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); } } void Buban103STNAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=1 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(76 --- 79) //rtumsg->MsgData[11]; // 带瞬变状态指示的值(VTI) //rtumsg->MsgData[12]; // 品质描述(QDS) //rtumsg->MsgData[13]; int commid; int aipnt; AI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } pDataUnit = &pDevParam->m_sDevParam.m_sStepDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU38 步位置信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } aipnt = pDataUnit->m_iStartPntNo + rtumsg->MsgData[11] - 76; if(rtumsg->MsgData[12] & 0x80) { // 设备在瞬变状态 } else { // 设备未在瞬变状态 } pntmsg.RawValue = rtumsg->MsgData[12]&0x7F; SetPntMsg(pDataUnit->m_iStnNo-1, aipnt, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); //品质描述(QDS) rtumsg->MsgData[13]; } void Buban103SPNAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int i, dipnt, commid; BYTE st; DI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的单点信息1 //rtumsg->MsgData[12]; // 附加信息 //rtumsg->MsgData[13]; commid = rtumsg->PortIdx; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; pDevParam = &pLinkParam->m_psDev[psDevAddrParam->m_iDevIdx]; pDataUnit = &pDevParam->m_sDevParam.m_sDiDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU1信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } for(i=0; im_iPntNum; i++) { // asdu类型判断 if(pLinkParam->m_iJudgeAsduNo != 0) { if(M_SP_NA_3 != pDataUnit->m_psDataInfo[i].m_u8Asdu) { continue; } } if((pDataUnit->m_psDataInfo[i].m_u8Fun == rtumsg->MsgData[10])\ && (pDataUnit->m_psDataInfo[i].m_u8Inf == rtumsg->MsgData[11])) { break; } } if(i >= pDataUnit->m_iPntNum) { return; } dipnt = pDataUnit->m_iStartPntNo + i; st = rtumsg->MsgData[12] & 0x01; pntmsg.Status = st; SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); } void Buban103SPTAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { Buban103SPTAprocessOfSoe(rtumsg, psDevAddrParam); } void Buban103SPTAprocessOfSoe(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int i, dipnt, commid; BYTE st; // 事件发生时间毫秒数 time_t iTime; WORD wMillSeconds; struct tm *ptrtm; DI_DEF pntmsg; SOE_DEF sSoeData; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的单点信息1 //rtumsg->MsgData[12]; // 带品质描述的单点信息1变化时间(4 bytes) //rtumsg->MsgData[13]; // 带品质描述的单点信息2 //rtumsg->MsgData[17]; // 带品质描述的单点信息2变化时间(4 bytes) //rtumsg->MsgData[18]; // ... ... // 带品质描述的单点信息n //rtumsg->MsgData[12+5*(n-1)]; // 带品质描述的单点信息n变化时间(4 bytes) //rtumsg->MsgData[12+5*(n-1)+1]; // 附加信息 //rtumsg->MsgData[12+5*n]; commid = rtumsg->PortIdx; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; pDevParam = &pLinkParam->m_psDev[psDevAddrParam->m_iDevIdx]; pDataUnit = &pDevParam->m_sDevParam.m_sDiDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU1信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } for(i=0; im_iPntNum; i++) { // asdu类型判断 if(pLinkParam->m_iJudgeAsduNo != 0) { if(M_SP_TA_3 != pDataUnit->m_psDataInfo[i].m_u8Asdu) { continue; } } if((pDataUnit->m_psDataInfo[i].m_u8Fun == rtumsg->MsgData[10])\ && (pDataUnit->m_psDataInfo[i].m_u8Inf == rtumsg->MsgData[11])) { break; } } if(i >= pDataUnit->m_iPntNum) { return; } dipnt = pDataUnit->m_iStartPntNo + i; st = rtumsg->MsgData[12] & 0x01; pntmsg.Status = st; // 属于自发或者突发事件就是soe if(rtumsg->MsgData[8] != M_CAUSE_QUERY) { // 事件发生时间毫秒数 time(&iTime); ptrtm = localtime(&iTime); if(ptrtm->tm_hour < (rtumsg->MsgData[16] & 0x1f)) { iTime -= 24 * 3600; ptrtm = localtime(&iTime); } ptrtm->tm_hour = rtumsg->MsgData[16] & 0x1f; ptrtm->tm_min = rtumsg->MsgData[15] & 0x3f; wMillSeconds = rtumsg->MsgData[13] + rtumsg->MsgData[14]*256; ptrtm->tm_sec = wMillSeconds / 1000; wMillSeconds %= 1000; sSoeData.bStatus = st; sSoeData.iPntNo = dipnt; sSoeData.u8Type = 1;// ASDU1 sSoeData.wFaultNo = 0; sSoeData.u8ProvFun = pDataUnit->m_psDataInfo[i].m_u8ProvFun; sSoeData.u8ProvInf = pDataUnit->m_psDataInfo[i].m_u8ProvInf; sSoeData.wRelativeTime = 0; sSoeData.SoeTime.Year = ptrtm->tm_year+1900; sSoeData.SoeTime.Month = (BYTE)(ptrtm->tm_mon+1); sSoeData.SoeTime.Day = (BYTE)(ptrtm->tm_mday); sSoeData.SoeTime.Hour = (BYTE)(ptrtm->tm_hour); sSoeData.SoeTime.Min = (BYTE)(ptrtm->tm_min); sSoeData.SoeTime.Sec = (BYTE)(ptrtm->tm_sec); sSoeData.SoeTime.mSec = wMillSeconds; SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&sSoeData, DI_PNT_TYPE, PNT_SOE_TIME_EX); } SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); } void Buban103DPNAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的双点信息1 //rtumsg->MsgData[12]; // 带品质描述的双点信息2 //rtumsg->MsgData[13]; // ... ... // 带品质描述的双点信息n //rtumsg->MsgData[12+n-1]; // 附加信息 //rtumsg->MsgData[12+n]; } void Buban103DPTAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的单点信息1 //rtumsg->MsgData[12]; // 带品质描述的单点信息1变化时间(4 bytes) //rtumsg->MsgData[13]; // 带品质描述的单点信息2 //rtumsg->MsgData[17]; // 带品质描述的单点信息2变化时间(4 bytes) //rtumsg->MsgData[18]; // ... ... // 带品质描述的单点信息n //rtumsg->MsgData[12+5*(n-1)]; // 带品质描述的单点信息n变化时间(4 bytes) //rtumsg->MsgData[12+5*(n-1)+1]; // 附加信息 //rtumsg->MsgData[12+5*n]; Buban103DPTAprocessOfSoe(rtumsg, psDevAddrParam); } void Buban103DPTAprocessOfSoe(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的单点信息1 //rtumsg->MsgData[12]; // 带品质描述的单点信息1变化时间(4 bytes) //rtumsg->MsgData[13]; // 带品质描述的单点信息2 //rtumsg->MsgData[17]; // 带品质描述的单点信息2变化时间(4 bytes) //rtumsg->MsgData[18]; // ... ... // 带品质描述的单点信息n //rtumsg->MsgData[12+5*(n-1)]; // 带品质描述的单点信息n变化时间(4 bytes) //rtumsg->MsgData[12+5*(n-1)+1]; // 附加信息 //rtumsg->MsgData[12+5*n]; } void Buban103SSNAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int i, j, dipnt, commid; BYTE st, len; WORD wStatusBit; DI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的单点信息1状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[12]; // QDS //rtumsg->MsgData[16]; // 带品质描述的单点信息2状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[17]; // QDS //rtumsg->MsgData[21]; // ... ... // 带品质描述的单点信息n状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[12+5*(n-1)]; // QDS //rtumsg->MsgData[12+5*(n-1)+4]; // 附加信息 //rtumsg->MsgData[12+5*n]; commid = rtumsg->PortIdx; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; pDevParam = &pLinkParam->m_psDev[psDevAddrParam->m_iDevIdx]; pDataUnit = &pDevParam->m_sDevParam.m_sDiDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU1信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } for(i=0; im_iPntNum; i++) { // asdu类型判断 if(pLinkParam->m_iJudgeAsduNo != 0) { if(M_SS_NA_3 != pDataUnit->m_psDataInfo[i].m_u8Asdu) { continue; } } if((pDataUnit->m_psDataInfo[i].m_u8Fun == rtumsg->MsgData[10])\ && (pDataUnit->m_psDataInfo[i].m_u8Inf == rtumsg->MsgData[11])) { break; } } if(i >= pDataUnit->m_iPntNum) { return; } dipnt = pDataUnit->m_iStartPntNo + i; len = (int)rtumsg->MsgData[1]; st = rtumsg->MsgData[12] & 0x01; pntmsg.Status = st; SetPntMsg(pDataUnit->m_iStnNo-1, dipnt, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); for ( i = 10; i < 4 + len; i += 5, dipnt += 16 ) { wStatusBit = rtumsg->MsgData[i+3]; wStatusBit = (wStatusBit<<8) + rtumsg->MsgData[i+2]; for( j = 0; j < 16; j++ ) { if( wStatusBit & (0x0001 << j) ) pntmsg.Status = 1; else pntmsg.Status = 0; SetPntMsg(commid, dipnt+j, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); } } } void Buban103SSTAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ) & 0x7f = 测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的单点信息1状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[12]; // QDS //rtumsg->MsgData[16]; // 四个八位位组的二进制时标 //rtumsg->MsgData[17]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[21]; // 带品质描述的单点信息2状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[22]; // QDS //rtumsg->MsgData[26]; // 四个八位位组的二进制时标 //rtumsg->MsgData[27]; // ... ... // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11+10*(n-1)]; // 带品质描述的单点信息n状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[11+10*(n-1)+1]; // QDS //rtumsg->MsgData[11+10*(n-1)+5]; // 四个八位位组的二进制时标 //rtumsg->MsgData[11+10*(n-1)+6]; // 附加信息 //rtumsg->MsgData[11+10*n]; } void Buban103DSNAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的双点信息1状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[12]; // QDS //rtumsg->MsgData[16]; // 带品质描述的双点信息2状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[17]; // QDS //rtumsg->MsgData[21]; // ... ... // 带品质描述的双点信息n状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[12+5*(n-1)]; // QDS //rtumsg->MsgData[12+5*(n-1)+4]; // 附加信息 //rtumsg->MsgData[12+5*n]; } void Buban103DSTAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ) & 0x7f = 测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11]; // 带品质描述的双点信息1状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[12]; // QDS //rtumsg->MsgData[16]; // 四个八位位组的二进制时标 //rtumsg->MsgData[17]; // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[21]; // 带品质描述的双点信息2状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[22]; // QDS //rtumsg->MsgData[26]; // 四个八位位组的二进制时标 //rtumsg->MsgData[27]; // ... ... // 信息序号(INF)(149 --- 238) //rtumsg->MsgData[11+10*(n-1)]; // 带品质描述的双点信息n状态和状态变化检出=SCD(4 BYTE) //rtumsg->MsgData[11+10*(n-1)+1]; // QDS //rtumsg->MsgData[11+10*(n-1)+5]; // 四个八位位组的二进制时标 //rtumsg->MsgData[11+10*(n-1)+6]; // 附加信息 //rtumsg->MsgData[11+10*n]; } void Buban103WLTAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int commid; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU48 水位信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif } void Buban103ITNAprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP) //rtumsg->MsgData[6]; // 可变结构限定词(VSQ)=测量量数目 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN) //rtumsg->MsgData[10]; // 信息序号(INF)(6 --- 31) //rtumsg->MsgData[11]; // 二进制计数器读数CR1(5 BYTES) //rtumsg->MsgData[12]; // 二进制计数器读数CR2 //rtumsg->MsgData[17]; // ... ... // 二进制计数器读数CRn //rtumsg->MsgData[12+5*(N-1)]; // 返回信息标识符(RII) //rtumsg->MsgData[12+5*N]; int commid; int i, pipnt, iNum; PI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } pDataUnit = &pDevParam->m_sDevParam.m_sPiDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU36 电度量信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } iNum = rtumsg->MsgData[7] & 0x7f; pipnt = pDataUnit->m_iStartPntNo + rtumsg->MsgData[11] - 6; for(i=0; iMsgData[12+5*i+4] & 0x80) { continue; } // 最低3位为品质描述 pntmsg.RawValue = rtumsg->MsgData[12+5*i] + (rtumsg->MsgData[13+5*i] << 8) + (rtumsg->MsgData[13+5*i] << 16) + (rtumsg->MsgData[13+5*i] << 24); SetPntMsg(pDataUnit->m_iStnNo-1, pipnt+i, (void *)&pntmsg, PI_PNT_TYPE, PNT_RAWVALUE); } } // 通用分类数据报文(包括所有的定值、模拟量、开关量(压板、开入开出等)) void Buban103GDprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP):10 //rtumsg->MsgData[6]; // 可变结构限定词(VSQ):0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN): 254(0xfe) //rtumsg->MsgData[10]; // 信息序号(INF): // 读组标题 : 240 // 读一个组的全部条目的值或属性 : 241 // 读单个条目的目录 : 243 // 读单个条目的值或属性 : 244 // 对通用分类数据总查询中止 : 245 //rtumsg->MsgData[11]; // 返回信息标识符(RII) //rtumsg->MsgData[12]; // 通用分类数据集数目 //rtumsg->MsgData[13]; // 以下为多个通用分类数据 // 通用分类标识序号(GIN):条目号和组号 //rtumsg->MsgData[14]; // 描述类别(KOD) // 无所指定的描述类别 : KOD_NOSPECIFIED(0) // 实际值 : KOD_ACTUALVALUE(1) // 缺省值 : KOD_DEFAULTVALUE(2) // 量程(最大值、最小值、步长) : KOD_RANGE(3) // 备用 : KOD_BACKUP1(4) // 精度(n,m) : KOD_PRECISION(5) // 因子 : KOD_FACTOR(6) // 参比 : KOD_REFERENCE(7) // 列表 : KOD_ENUMERATION(8) // 量纲 : KOD_DIMENSION(9) // 描述 : KOD_DESCRIPTION(10) // 备用 : KOD_BACKUP2(11) // 口令条目 : KOD_PASSWORD(12) // 只读 : KOD_READONLY(13) // 只写 : KOD_WRITEONLY(14) // 备用 : KOD_BACKUP3(15) // 备用 : KOD_BACKUP4(16) // 备用 : KOD_BACKUP5(17) // 备用 : KOD_BACKUP6(18) // 相应的功能类型和信息序号 : KOD_CORFUNCANDINF(19) // 相应的事件 : KOD_COREVENT(20) // 列表的文本阵列 : KOD_ENUMTEXTARRAY(21) // 列表的值阵列 : KOD_ENUMVALUEARRAY(22) // 相关联的条目 : KOD_RELATEDENTRIES(23) //rtumsg->MsgData[16]; // 数据类型描述 //rtumsg->MsgData[17]; //DATAID_NO : 无数据 //DATAID_OS8ASCII : 8位ASCII //DATAID_BSTRING : 8位2进制数 //DATAID_UIX : 无符号整数 //DATAID_INT : 整数 //DATAID_UFLOAT : 无符号浮点数 //DATAID_FLOAT : 浮点数 //DATAID_754SHORT : R32.23 IEEE 标准754短实数 //DATAID_754REAL : R64.53 IEEE 标准754实数 //DATAID_DOUBLE : 双点信息 //DATAID_SINGLE : 单点信息 //DATAID_13BITS : 带品质描述的被测值(13BITS) //DATAID_SORTIDNO : 通用分类标识序号 //DATAID_WITHTIME : 带时标的报文 //DATAID_WITHTIMESPACE : 带相对时标的报文 //DATAID_STRUCT : 数据结构 // 数据尺寸 //rtumsg->MsgData[18] // 数量 //rtumsg->MsgData[19] // 数据值(长度根据以上描述) // 2 ... n 个通用分类数据 int commid; int i, iGroupNo, iCfgGroupIdx; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } // 数据转发在这里处理 if(rtumsg->MsgData[12] == RII_PROV_ID) { if(pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid >= 0) { if(psDevAddrParam->m_uchCommAddr ==\ pLinkParam->m_sBaoHuCmdParam.m_sRealAddrParam.m_uchCommAddr) { // 判断超时时间为5分钟 if(JudgeTimeOut(&pLinkParam->m_sBaoHuCmdParam.m_sBaoHuCmdStartTime, 5*60) == FALSE) { if(MSGTYPE_BAOHU_103CMD == pLinkParam->m_sBaoHuCmdParam.m_iBaoHuMsgType) { // 转储数据到转发端口 rtumsg->MsgData[9] = (BYTE)pDevParam->m_sDevParam.m_iProvAddr; rtumsg->PortIdx = pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid; rtumsg->MsgType = MSGTYPE_BAOHU_103DATA; PutBaohuDataToPort(rtumsg); } else if(MSGTYPE_BAOHU_SCADACMD == pLinkParam->m_sBaoHuCmdParam.m_iBaoHuMsgType) { //rtumsg->MsgData[9] = (BYTE)pDevParam->m_sDevParam.m_iProvAddr; //rtumsg->PortIdx = pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid; rtumsg->MsgType = MSGTYPE_BAOHU_SCADADATA; // 按内部保护格式转换 Buban103ScadaProtocolExchange(commid, rtumsg); } // 没有后续数据 if((rtumsg->MsgData[13] & 0x80) == 0) { pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid = -1; pLinkParam->m_sBaoHuCmdParam.m_iBaoHuMsgType = 0; } return; } else { pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid = -1; } } } } //组 号 iGroupNo = rtumsg->MsgData[14]; for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo == iGroupNo) { iCfgGroupIdx = i; break; } } if(i >= pDevParam->m_sDevParam.m_iCfgGroupNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10 通用分类数据处理时,Group=%d不在处理范围内!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, iGroupNo); DebugPrint(szbuf); #endif return ; } switch(pDevParam->m_sDevParam.m_saGroupDef[iCfgGroupIdx].m_iDataType) { // 处理模拟量 case AI_PNT_TYPE: Buban103GDprocessWithAI(rtumsg, psDevAddrParam, iCfgGroupIdx); break; // 处理开关量 case DI_PNT_TYPE: Buban103GDprocessWithDI(rtumsg, psDevAddrParam, iCfgGroupIdx); break; // 处理电度量 case PI_PNT_TYPE: Buban103GDprocessWithPI(rtumsg, psDevAddrParam, iCfgGroupIdx); break; // 处理保护模拟量 case PROTECT_AI_PNT_TYPE: Buban103GDprocessWithPAI(rtumsg, psDevAddrParam, iCfgGroupIdx); break; // 处理保护开关量 case PROTECT_DI_PNT_TYPE: Buban103GDprocessWithPDI(rtumsg, psDevAddrParam, iCfgGroupIdx); break; // 处理保护定值 case PROTECT_FIX_PNT_TYPE: Buban103GDprocessWithPFIX(rtumsg, psDevAddrParam, iCfgGroupIdx); break; // 处理保护事件 case PROTECT_EVENT_PNT_TYPE: Buban103GDprocessWithPEVENT(rtumsg, psDevAddrParam, iCfgGroupIdx); break; default: #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10处理时, Group=%d数据类型(=%d)不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pDevParam->m_sDevParam.m_saGroupDef[iCfgGroupIdx].m_iGroupNo, pDevParam->m_sDevParam.m_saGroupDef[iCfgGroupIdx].m_iDataType); DebugPrint(szbuf); #endif break; } } void Buban103YkAck(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP):64 //rtumsg->MsgData[6]; // 可变结构限定词(VSQ):0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; //M_CAUSE_REMOTE : // 远方操作 // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN): 1 //rtumsg->MsgData[10]; // 信息序号(INF): 48 --- 75 //rtumsg->MsgData[11]; // 信息序号(DCC) //rtumsg->MsgData[12]; // 返回信息标识符(RII) //rtumsg->MsgData[13]; int commid; int iYkNo; BYTE buf[16]; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } if(pDevParam->m_sDevParam.m_sYkDBOrientation.m_iPntNum <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU64 未配置遥控点!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } iYkNo = rtumsg->MsgData[11] - 48 + pDevParam->m_sDevParam.m_iYkStartPnt; if(iYkNo >= 0) { // 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=失败) // 在转发遥控数据点中,只保留了要转发的控点号,实际的端口号应该是该转发点的端口 // 该转发点并没有指定虚拟的转发控点,则控点和转发点的点号一致。 buf[0] = (BYTE)(commid & 0xFF); buf[1] = (BYTE)((commid & 0xFF00) << 8); buf[2] = (BYTE)((commid & 0xFF0000) << 16); buf[3] = (BYTE)((commid & 0xFF000000) << 24); buf[4] = (BYTE)(iYkNo & 0xFF); buf[5] = (BYTE)((iYkNo & 0xFF00) << 8); buf[6] = (BYTE)((iYkNo & 0xFF0000) << 16); buf[7] = (BYTE)((iYkNo & 0xFF000000) << 24); switch((rtumsg->MsgData[12] & 0xc0) >> 6) { case 0:// buf[8] = STEP_YKYT_EXEC; break; case 2: buf[8] = STEP_YKYT_SELECT; break; case 3: buf[8] = STEP_YKYT_CANCEL; break; default: buf[8] = STEP_YKYT_NOEXEC; break; } switch(rtumsg->MsgData[12] & 0x03) { case 0: case 3: buf[8] = STEP_YKYT_NOEXEC; break; default: buf[9] = (rtumsg->MsgData[12] & 0x03) | 0x80; break; } if(ShmGetDispYkYtFlag()) { #ifdef _DEBUG_MSG_ //sprintf(szbuf, "端口%d 链路地址=%d 装置地址%d RII=0x%02x, 遥控点号=%d, op=0x%02x!!!\n", // commid, rtumsg->MsgData[5], rtumsg->MsgData[9], rtumsg->MsgData[13], iYkNo, rtumsg->MsgData[12]); //DebugPrint(szbuf); sprintf(szbuf, "TIP_(%04d): commid=%d linkaddr=%d devaddr=%d RII=0x%02x ykpnt=%d, op=0x%02x.\n", _getpid(), commid, rtumsg->MsgData[5], rtumsg->MsgData[9], rtumsg->MsgData[13], iYkNo, rtumsg->MsgData[12]); DebugPrint(szbuf); #endif } Buban103YkYtProcess(commid, buf, 10); } } void Buban103YtAck(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP):65 //rtumsg->MsgData[6]; // 可变结构限定词(VSQ):0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; //M_CAUSE_REMOTE : // 远方操作 // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN): 1 //rtumsg->MsgData[10]; // 信息序号(INF): 48 --- 75 //rtumsg->MsgData[11]; // 信息序号(RCC) //rtumsg->MsgData[12]; // 返回信息标识符(RII) //rtumsg->MsgData[13]; int commid; int iYtNo; BYTE buf[16]; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } if(pDevParam->m_sDevParam.m_sYkDBOrientation.m_iPntNum <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10 未配置遥控点!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } iYtNo = rtumsg->MsgData[11] - 48 + pDevParam->m_sDevParam.m_iYtStartPnt; if(iYtNo >= 0) { // 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=失败) // 在转发遥控数据点中,只保留了要转发的控点号,实际的端口号应该是该转发点的端口 // 该转发点并没有指定虚拟的转发控点,则控点和转发点的点号一致。 buf[0] = (BYTE)(commid & 0xFF); buf[1] = (BYTE)((commid & 0xFF00) << 8); buf[2] = (BYTE)((commid & 0xFF0000) << 16); buf[3] = (BYTE)((commid & 0xFF000000) << 24); buf[4] = (BYTE)(iYtNo & 0xFF); buf[5] = (BYTE)((iYtNo & 0xFF00) << 8); buf[6] = (BYTE)((iYtNo & 0xFF0000) << 16); buf[7] = (BYTE)((iYtNo & 0xFF000000) << 24); switch((rtumsg->MsgData[12] & 0xc0) >> 6) { case 0:// buf[8] = STEP_YT_EXEC; break; case 2: buf[8] = STEP_YT_SELECT; break; case 3: buf[8] = STEP_YT_CANCEL; break; default: buf[8] = STEP_YKYT_NOEXEC; break; } switch(rtumsg->MsgData[12] & 0x03) { case 0: case 3: buf[8] = STEP_YKYT_NOEXEC; break; default: buf[9] = (rtumsg->MsgData[12] & 0x03) | 0x80; break; } if(ShmGetDispYkYtFlag()) { #ifdef _DEBUG_MSG_ //sprintf(szbuf, "端口%d 链路地址=%d 装置地址%d RII=0x%02x, 遥调点号=%d, op=0x%02x!!!\n", // commid, rtumsg->MsgData[5], rtumsg->MsgData[9], rtumsg->MsgData[13], iYtNo, rtumsg->MsgData[12]); //DebugPrint(szbuf); sprintf(szbuf, "TIP_(%04d): commid=%d linkaddr=%d devaddr=%d RII=0x%02x ytpnt=%d, op=0x%02x.\n", _getpid(), commid, rtumsg->MsgData[5], rtumsg->MsgData[9], rtumsg->MsgData[13], iYtNo, rtumsg->MsgData[12]); DebugPrint(szbuf); #endif } Buban103YkYtProcess(commid, buf, 10); } } void Buban103GDprocessWithAI(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid; BYTE u8KOD, u8INF, u8NGD, u8DataType; BYTE u8DataNum, u8DataLen; int aipnt, aistart, stn, iOffset; AI_DEF pntmsg; VALUEDEF sValue; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } iOffset = 14; if(iOffset >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(AI)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } stn = pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iStationNo; if(stn <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(AI)_Group=%d 信息不写入数据库!!!",\ commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr,\ pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iGroupNo); DebugPrint(szbuf); #endif } u8INF = rtumsg->MsgData[11]; u8NGD = rtumsg->MsgData[13] & 0x3f; aistart = pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iStartPntNo; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(AI)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(AI)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif break; } // 组号和条目号 aipnt = aistart + rtumsg->MsgData[iOffset+1]; iOffset += 2; u8KOD = rtumsg->MsgData[iOffset++]; if(KOD_ACTUALVALUE != u8KOD) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(AI)处理时,KOD=%d不在处理范围内,只处理实际值数据!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 3; continue; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; jMsgData[iOffset], &sValue, u8DataType, u8DataLen)) { switch(sValue.m_iDataType) { case DT_UINT:// 无符号整型数 pntmsg.RawValue = (WORD)sValue.m_unValue.m_uValue; SetPntMsg(stn-1, aipnt+j, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); break; case DT_INT: pntmsg.RawValue = (WORD)sValue.m_unValue.m_iValue; SetPntMsg(stn-1, aipnt+j, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); break; case DT_FLOAT: pntmsg.RawValue = (WORD)sValue.m_unValue.m_fValue; SetPntMsg(stn-1, aipnt+j, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); break; case DT_CONTROL: pntmsg.RawValue = (WORD)sValue.m_unValue.m_dwValue; SetPntMsg(stn-1, aipnt+j, &pntmsg, AI_PNT_TYPE, PNT_RAWVALUE); break; case DT_NO:// 无数据 case DT_STRING: case DT_BINARY: default: break; } } iOffset += u8DataLen; } } } void Buban103GDprocessWithDI(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid; BYTE u8KOD, u8INF, u8NGD, u8DataType; BYTE u8DataNum, u8DataLen; int dipnt, distart, stn, iOffset; DI_DEF pntmsg; VALUEDEF sValue; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } iOffset = 14; if(iOffset >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(DI)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } stn = pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iStationNo; if(stn <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(DI)_Group=%d 信息不写入数据库!!!",\ commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr,\ pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iGroupNo); DebugPrint(szbuf); #endif } u8INF = rtumsg->MsgData[11]; u8NGD = rtumsg->MsgData[13] & 0x3f; distart = pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iStartPntNo; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(DI)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(DI)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif break; } // 组号和条目号 dipnt = distart + rtumsg->MsgData[iOffset+1]; iOffset += 2; u8KOD = rtumsg->MsgData[iOffset++]; if(KOD_ACTUALVALUE != u8KOD) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(DI)处理时,KOD=%d不在处理范围内,只处理实际值数据!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 3; continue; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; jMsgData[iOffset], &sValue, u8DataType, u8DataLen)) { switch(sValue.m_iDataType) { case DT_BINARY: if(sValue.m_iDataNum > 1) { if((sValue.m_unValue.m_dwValue > 0)\ && (sValue.m_unValue.m_dwValue < 3)) { pntmsg.Status = (BYTE)(sValue.m_unValue.m_dwValue - 1); } else { pntmsg.Status = 0; } } else { pntmsg.Status = (BYTE)(sValue.m_unValue.m_dwValue); } SetPntMsg(stn-1, dipnt+j, &pntmsg, DI_PNT_TYPE, PNT_STATUS); break; case DT_UINT:// 无符号整型数 if(sValue.m_unValue.m_uValue != 0) { pntmsg.Status = 1; } else { pntmsg.Status = 0; } SetPntMsg(stn-1, dipnt+j, &pntmsg, DI_PNT_TYPE, PNT_STATUS); break; case DT_INT: if(sValue.m_unValue.m_iValue != 0) { pntmsg.Status = 1; } else { pntmsg.Status = 0; } SetPntMsg(stn-1, dipnt+j, &pntmsg, DI_PNT_TYPE, PNT_STATUS); break; case DT_FLOAT: case DT_CONTROL: case DT_NO:// 无数据 case DT_STRING: default: break; } } iOffset += u8DataLen; } } } void Buban103GDprocessWithPI(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid; BYTE u8KOD, u8INF, u8NGD, u8DataType; BYTE u8DataNum, u8DataLen; int pipnt, pistart, stn, iOffset; PI_DEF pntmsg; VALUEDEF sValue; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } iOffset = 14; if(iOffset >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(PI)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } stn = pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iStationNo; if(stn <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(PI)_Group=%d 信息不写入数据库!!!",\ commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr,\ pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iGroupNo); DebugPrint(szbuf); #endif } u8INF = rtumsg->MsgData[11]; u8NGD = rtumsg->MsgData[13] & 0x3f; pistart = pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx].m_iStartPntNo; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(PI)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(PI)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif break; } // 组号和条目号 pipnt = pistart + rtumsg->MsgData[iOffset+1]; iOffset += 2; u8KOD = rtumsg->MsgData[iOffset++]; if(KOD_ACTUALVALUE != u8KOD) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(PI)处理时,KOD=%d不在处理范围内,只处理实际值数据!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 3; continue; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; jMsgData[iOffset], &sValue, u8DataType, u8DataLen)) { switch(sValue.m_iDataType) { case DT_UINT:// 无符号整型数 pntmsg.RawValue = sValue.m_unValue.m_uValue; SetPntMsg(stn-1, pipnt+j, &pntmsg, PI_PNT_TYPE, PNT_RAWVALUE); break; case DT_INT: pntmsg.RawValue = sValue.m_unValue.m_iValue; SetPntMsg(stn-1, pipnt+j, &pntmsg, PI_PNT_TYPE, PNT_RAWVALUE); break; case DT_FLOAT: pntmsg.RawValue = (u_long)sValue.m_unValue.m_fValue; SetPntMsg(stn-1, pipnt+j, &pntmsg, PI_PNT_TYPE, PNT_RAWVALUE); break; case DT_CONTROL: case DT_NO:// 无数据 case DT_BINARY: case DT_STRING: default: break; } } iOffset += u8DataLen; } } } void Buban103GDprocessWithPAI(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid, iItemNum, iStrLen; BYTE u8KOD, u8INF, u8DataType; BYTE u8DataNum, u8DataLen, u8ItemNo; int iOffset; double fValue; BOOL bFirst, bNumChanged; VALUEDEF sValue; GROUPDEF *pGroupParam; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } bNumChanged = FALSE; bFirst = TRUE; iOffset = 14; pGroupParam = &pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx]; if((iOffset+3) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } u8INF = rtumsg->MsgData[11]; u8KOD = rtumsg->MsgData[16]; pGroupParam->m_u8NGD = rtumsg->MsgData[13]; if(pGroupParam->m_iPntNum <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据空间为零!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } // 只处理实际值 if(KOD_ACTUALVALUE != u8KOD) { return; } iItemNum = pGroupParam->m_u8NGD & 0x3F; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 组 号 // 条目号 u8ItemNo = rtumsg->MsgData[iOffset+1]; iOffset += 2; if(TRUE == bFirst) { if(u8ItemNo == 0) { pGroupParam->m_u32CurPntNo = 1; } else if(u8ItemNo <= pGroupParam->m_iStartItemNo) { pGroupParam->m_u32CurPntNo = 1; } if((M_INF_WRITEITEMWITHACK == u8INF) && (pGroupParam->m_bInit == FALSE)) { for(j=0; jm_iPntNum; j++) { if(pGroupParam->m_pu8GIN[j] == u8ItemNo) { break; } } if(j >= pGroupParam->m_iPntNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,不匹配的GIN=%d!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8ItemNo, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } pGroupParam->m_u32CurPntNo = j+1; } bFirst = FALSE; } if(u8KOD != rtumsg->MsgData[iOffset]) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,数据KOD=%d与要求的KOD=%d不符!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo, rtumsg->MsgData[iOffset], u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 4; continue; } else { iOffset++; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; j<(int)u8DataNum; j++) { if((int)pGroupParam->m_u32CurPntNo > pGroupParam->m_iPntNum) { break; } if(pGroupParam->m_bInit == FALSE) { //pGroupParam->m_pu8DataLen[pGroupParam->m_u32CurPntNo-1] = u8DataLen; //pGroupParam->m_pu8DataType[pGroupParam->m_u32CurPntNo-1] = u8DataType; pGroupParam->m_pu8GIN[pGroupParam->m_u32CurPntNo-1] = u8ItemNo+j; } if(GetOneValueOfASDU10(&rtumsg->MsgData[iOffset], &sValue, u8DataType, u8DataLen) == FALSE) { iOffset += u8DataLen; continue; } iOffset += u8DataLen; switch(sValue.m_iDataType) { case DT_UINT:// 无符号整型数 fValue = sValue.m_unValue.m_uValue; break; case DT_INT: fValue = sValue.m_unValue.m_iValue; break; case DT_FLOAT: fValue = sValue.m_unValue.m_fValue; break; case DT_CONTROL: fValue = sValue.m_unValue.m_dwValue; break; case DT_STRING: fValue = -1; break; case DT_BINARY: fValue = sValue.m_unValue.m_dwValue; break; case DT_NO:// 无数据 default: fValue = -1; break; } if(pGroupParam->m_bInit == FALSE) { if((u8ItemNo == 0) && (j == 0)) { if((fValue > 0) && (KOD_ACTUALVALUE == u8KOD)) { if((int)fValue > pGroupParam->m_iPntNum) { //pGroupParam->m_iPntNum = (int)sValue.m_unValue.m_uValue; bNumChanged = TRUE; } else { pGroupParam->m_iPntNum = (int)fValue; } } } } if(TRUE == bNumChanged) { //freeallfixmemory } if(DT_STRING != sValue.m_iDataType) { pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].m_fValue = (float)fValue; } else { // 描述或者量纲 if(KOD_DESCRIPTION == u8KOD) { iStrLen = sizeof(pGroupParam->m_psDataInfo->m_szName)-1; if(iStrLen > sValue.m_iDataNum) { iStrLen = sValue.m_iDataNum; } memcpy(pGroupParam->m_psDataInfo->m_szName, sValue.m_szValue, iStrLen); pGroupParam->m_psDataInfo->m_szName[iStrLen] = 0; } else if(KOD_DIMENSION == u8KOD) { iStrLen = sizeof(pGroupParam->m_psDataInfo->m_szUnit)-1; if(iStrLen > sValue.m_iDataNum) { iStrLen = sValue.m_iDataNum; } memcpy(pGroupParam->m_psDataInfo->m_szUnit, sValue.m_szValue, iStrLen); pGroupParam->m_psDataInfo->m_szUnit[iStrLen] = 0; } } if(pGroupParam->m_bInit == FALSE) { pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].m_u32DataID = u8DataType; } pGroupParam->m_u32CurPntNo++; } } if(pGroupParam->m_iPntNum > 0) { if((int)pGroupParam->m_u32CurPntNo >= pGroupParam->m_iPntNum) { pGroupParam->m_bInit = TRUE; pGroupParam->m_u32CurPntNo = 1; } } } void Buban103GDprocessWithPDI(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { Buban103GDprocessWithPAI(rtumsg, psDevAddrParam, iGroupIdx); } void Buban103GDprocessWithPFIX(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid, iItemNum, iStrLen; BYTE u8KOD, u8INF, u8DataType; BYTE u8DataNum, u8DataLen, u8ItemNo; int iOffset; double fValue; BOOL bFirst, bNumChanged; VALUEDEF sValue; GROUPDEF *pGroupParam; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } bNumChanged = FALSE; bFirst = TRUE; iOffset = 14; pGroupParam = &pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx]; if((iOffset+3) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } u8INF = rtumsg->MsgData[11]; u8KOD = rtumsg->MsgData[16]; pGroupParam->m_u8NGD = rtumsg->MsgData[13]; if(pGroupParam->m_iPntNum > 0) { if(pGroupParam->m_pu8DataLen == NULL) { pGroupParam->m_pu8DataLen = (BYTE *)HEAP_MALLOC(pGroupParam->m_iPntNum*sizeof(BYTE)); Buban103DispMalloc(commid, pGroupParam->m_iPntNum*sizeof(BYTE)); } if(pGroupParam->m_pu8DataType == NULL) { pGroupParam->m_pu8DataType = (BYTE *)HEAP_MALLOC(pGroupParam->m_iPntNum*sizeof(BYTE)); Buban103DispMalloc(commid, pGroupParam->m_iPntNum*sizeof(BYTE)); } if(pGroupParam->m_pu8GIN == NULL) { pGroupParam->m_pu8GIN = (BYTE *)HEAP_MALLOC(pGroupParam->m_iPntNum*sizeof(BYTE)); Buban103DispMalloc(commid, pGroupParam->m_iPntNum*sizeof(BYTE)); } } else { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据空间为零!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } // 只处理实际值 if(KOD_ACTUALVALUE != u8KOD) { return; } iItemNum = pGroupParam->m_u8NGD & 0x3F; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 组 号 // 条目号 u8ItemNo = rtumsg->MsgData[iOffset+1]; iOffset += 2; if(TRUE == bFirst) { if(u8ItemNo == 0) { pGroupParam->m_u32CurPntNo = 1; } else if(u8ItemNo <= pGroupParam->m_iStartItemNo) { pGroupParam->m_u32CurPntNo = 1; } if((M_INF_WRITEITEMWITHACK == u8INF) && (pGroupParam->m_bInit == FALSE)) { for(j=0; jm_iPntNum; j++) { if(pGroupParam->m_pu8GIN[j] == u8ItemNo) { break; } } if(j >= pGroupParam->m_iPntNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,不匹配的GIN=%d!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8ItemNo, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } pGroupParam->m_u32CurPntNo = j+1; } bFirst = FALSE; } if(u8KOD != rtumsg->MsgData[iOffset]) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,数据KOD=%d与要求的KOD=%d不符!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo, rtumsg->MsgData[iOffset], u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 4; continue; } else { iOffset++; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; j<(int)u8DataNum; j++) { if((int)pGroupParam->m_u32CurPntNo > pGroupParam->m_iPntNum) { break; } if(pGroupParam->m_bInit == FALSE) { pGroupParam->m_pu8DataLen[pGroupParam->m_u32CurPntNo-1] = u8DataLen; pGroupParam->m_pu8DataType[pGroupParam->m_u32CurPntNo-1] = u8DataType; pGroupParam->m_pu8GIN[pGroupParam->m_u32CurPntNo-1] = u8ItemNo+j; } if(GetOneValueOfASDU10(&rtumsg->MsgData[iOffset], &sValue, u8DataType, u8DataLen) == FALSE) { iOffset += u8DataLen; continue; } iOffset += u8DataLen; switch(sValue.m_iDataType) { case DT_UINT:// 无符号整型数 fValue = sValue.m_unValue.m_uValue; break; case DT_INT: fValue = sValue.m_unValue.m_iValue; break; case DT_FLOAT: fValue = sValue.m_unValue.m_fValue; break; case DT_CONTROL: fValue = sValue.m_unValue.m_dwValue; break; case DT_STRING: fValue = -1; break; case DT_BINARY: fValue = sValue.m_unValue.m_dwValue; break; case DT_NO:// 无数据 default: fValue = -1; break; } if(pGroupParam->m_bInit == FALSE) { if((u8ItemNo == 0) && (j == 0)) { if((fValue > 0) && (KOD_ACTUALVALUE == u8KOD)) { if((int)fValue > pGroupParam->m_iPntNum) { //pGroupParam->m_iPntNum = (int)sValue.m_unValue.m_uValue; bNumChanged = TRUE; } else { pGroupParam->m_iPntNum = (int)fValue; } } } } if(TRUE == bNumChanged) { //freeallfixmemory } if(DT_STRING != sValue.m_iDataType) { pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].m_fValue = (float)fValue; } else { // 描述或者量纲 if(KOD_DESCRIPTION == u8KOD) { iStrLen = sizeof(pGroupParam->m_psDataInfo->m_szName)-1; if(iStrLen > sValue.m_iDataNum) { iStrLen = sValue.m_iDataNum; } memcpy(pGroupParam->m_psDataInfo->m_szName, sValue.m_szValue, iStrLen); pGroupParam->m_psDataInfo->m_szName[iStrLen] = 0; } else if(KOD_DIMENSION == u8KOD) { iStrLen = sizeof(pGroupParam->m_psDataInfo->m_szUnit)-1; if(iStrLen > sValue.m_iDataNum) { iStrLen = sValue.m_iDataNum; } memcpy(pGroupParam->m_psDataInfo->m_szUnit, sValue.m_szValue, iStrLen); pGroupParam->m_psDataInfo->m_szUnit[iStrLen] = 0; } } if(pGroupParam->m_bInit == FALSE) { pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].m_u32DataID = u8DataType; } pGroupParam->m_u32CurPntNo++; } } if(pGroupParam->m_iPntNum > 0) { if((int)pGroupParam->m_u32CurPntNo >= pGroupParam->m_iPntNum) { pGroupParam->m_bInit = TRUE; pGroupParam->m_u32CurPntNo = 1; } } // wen 2004.01.06 写定值确认 if((M_CAUSE_WRITEACK == rtumsg->MsgData[8]) || (M_CAUSE_WRITECONFIRM == rtumsg->MsgData[8])) { //ptrProHead->uFuncCode = hWRITEFIXACK; //RtuProtocolBaoHuCommand(&msg); } else if(M_CAUSE_WRITENAK == rtumsg->MsgData[8]) { //ptrProHead->uFuncCode = hWRITEFIXNAK; //RtuProtocolBaoHuCommand(&msg); } } void Buban103GDprocessWithPEVENT(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, k, commid, iItemNum; BYTE u8KOD, u8INF, u8DataType; BYTE u8DataNum, u8DataLen, u8ItemNo; int iOffset; BOOL bFirst, bNumChanged; time_t iTime; WORD wMillSeconds, wTime, wFault; struct tm *ptrtm; SOE_DEF sSoeData; DBORIENTATION *pDataUnit; GROUPDEF *pGroupParam; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } bNumChanged = FALSE; bFirst = TRUE; iOffset = 14; pGroupParam = &pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx]; pDataUnit = &pDevParam->m_sDevParam.m_sDiDBOrientation; if((iOffset+3) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } u8INF = rtumsg->MsgData[11]; u8KOD = rtumsg->MsgData[16]; pGroupParam->m_u8NGD = rtumsg->MsgData[13]; // 只处理实际值 if(KOD_ACTUALVALUE != u8KOD) { return; } iItemNum = pGroupParam->m_u8NGD & 0x3F; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 组 号 // 条目号 u8ItemNo = rtumsg->MsgData[iOffset+1]; iOffset += 2; if(u8KOD != rtumsg->MsgData[iOffset]) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,数据KOD=%d与要求的KOD=%d不符!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo, rtumsg->MsgData[iOffset], u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 4; continue; } else { iOffset++; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; j<(int)u8DataNum; j++) { if((int)pGroupParam->m_u32CurPntNo > pGroupParam->m_iPntNum) { break; } for(k=0; km_iPntNum; k++) { if((pDataUnit->m_psDataInfo[k].m_u8Asdu == 10)\ && (pDataUnit->m_psDataInfo[k].m_u8Inf == (u8ItemNo+j))\ && (pDataUnit->m_psDataInfo[k].m_u8Fun == pGroupParam->m_iGroupNo)) { break; } } if(k >= pDataUnit->m_iPntNum) { iOffset += u8DataLen; continue; } switch(u8DataType) { case DATAID_WITHTIME: // 带时标的报文 switch(rtumsg->MsgData[iOffset] & 0x03) { case 1: sSoeData.bStatus = 0; break; case 2: sSoeData.bStatus = 1; break; case 3: case 0: default: sSoeData.bStatus = 0; break; } time(&iTime); ptrtm = localtime(&iTime); if(ptrtm->tm_hour < (rtumsg->MsgData[iOffset+4] & 0x1f)) { iTime -= 24 * 3600; ptrtm = localtime(&iTime); } ptrtm->tm_hour = rtumsg->MsgData[iOffset+4] & 0x1f; ptrtm->tm_min = rtumsg->MsgData[iOffset+3] & 0x3f; wMillSeconds = rtumsg->MsgData[iOffset+1] + rtumsg->MsgData[iOffset+2]*256; ptrtm->tm_sec = wMillSeconds / 1000; sSoeData.iPntNo = pDataUnit->m_iStartPntNo+k; sSoeData.u8Type = 1;// ASDU1 sSoeData.wFaultNo = 0; sSoeData.u8ProvFun = pDataUnit->m_psDataInfo[k].m_u8ProvFun; sSoeData.u8ProvInf = pDataUnit->m_psDataInfo[k].m_u8ProvInf; sSoeData.wRelativeTime = 0; sSoeData.SoeTime.Year = ptrtm->tm_year+1900; sSoeData.SoeTime.Month = (BYTE)(ptrtm->tm_mon+1); sSoeData.SoeTime.Day = (BYTE)(ptrtm->tm_mday); sSoeData.SoeTime.Hour = (BYTE)(ptrtm->tm_hour); sSoeData.SoeTime.Min = (BYTE)(ptrtm->tm_min); sSoeData.SoeTime.Sec = (BYTE)(ptrtm->tm_sec); sSoeData.SoeTime.mSec = wMillSeconds; SetPntMsg(pDataUnit->m_iStnNo-1, pDataUnit->m_iStartPntNo+k, (void *)&sSoeData, DI_PNT_TYPE, PNT_SOE_TIME_EX); break; case DATAID_WITHTIMESPACE:// 带相对时标的报文 switch(rtumsg->MsgData[iOffset] & 0x03) { case 1: sSoeData.bStatus = 0; break; case 2: sSoeData.bStatus = 1; break; case 3: case 0: default: sSoeData.bStatus = 0; break; } wTime = rtumsg->MsgData[iOffset+1] + rtumsg->MsgData[iOffset+2]*256; wFault= rtumsg->MsgData[iOffset+3] + rtumsg->MsgData[iOffset+4]*256; time(&iTime); ptrtm = localtime(&iTime); if(ptrtm->tm_hour < (rtumsg->MsgData[iOffset+8] & 0x1f)) { iTime -= 24 * 3600; ptrtm = localtime(&iTime); } ptrtm->tm_hour = rtumsg->MsgData[iOffset+8] & 0x1f; ptrtm->tm_min = rtumsg->MsgData[iOffset+7] & 0x3f; wMillSeconds = rtumsg->MsgData[iOffset+5] + rtumsg->MsgData[iOffset+6]*256; ptrtm->tm_sec = wMillSeconds / 1000; sSoeData.iPntNo = pDataUnit->m_iStartPntNo+k; sSoeData.u8Type = 2;// ASDU2 sSoeData.wFaultNo = wFault; sSoeData.u8ProvFun = pDataUnit->m_psDataInfo[k].m_u8ProvFun; sSoeData.u8ProvInf = pDataUnit->m_psDataInfo[k].m_u8ProvInf; sSoeData.wRelativeTime = wTime; sSoeData.SoeTime.Year = ptrtm->tm_year+1900; sSoeData.SoeTime.Month = (BYTE)(ptrtm->tm_mon+1); sSoeData.SoeTime.Day = (BYTE)(ptrtm->tm_mday); sSoeData.SoeTime.Hour = (BYTE)(ptrtm->tm_hour); sSoeData.SoeTime.Min = (BYTE)(ptrtm->tm_min); sSoeData.SoeTime.Sec = (BYTE)(ptrtm->tm_sec); sSoeData.SoeTime.mSec = wMillSeconds; SetPntMsg(pDataUnit->m_iStnNo-1, pDataUnit->m_iStartPntNo+k, (void *)&sSoeData, DI_PNT_TYPE, PNT_SOE_TIME_EX); break; default: break; } iOffset += u8DataLen; } } } void Buban103GIprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { // 类型标识(TYP):11 //rtumsg->MsgData[6]; // 可变结构限定词(VSQ):0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; //M_CAUSE_READWITHVALIDDATA : 对通用分类读命令有效数据响应 //M_CAUSE_READWITHINVALIDDATA : 对通用分类读命令无效数据响应 // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN): 254(0xfe) //rtumsg->MsgData[10]; // 信息序号(INF): // 读单个条目的目录 : 243 //rtumsg->MsgData[11]; // 返回信息标识符(RII) //rtumsg->MsgData[12]; // 通用分类标识序号(GIN):条目号和组号 //rtumsg->MsgData[13]; // 描述元素的数目(NDE) //rtumsg->MsgData[15]; // 以下为多个通用分类数据 // 描述类别(KOD) // 无所指定的描述类别 : KOD_NOSPECIFIED(0) // 实际值 : KOD_ACTUALVALUE(1) // 缺省值 : KOD_DEFAULTVALUE(2) // 量程(最大值、最小值、步长) : KOD_RANGE(3) // 备用 : KOD_BACKUP1(4) // 精度(n,m) : KOD_PRECISION(5) // 因子 : KOD_FACTOR(6) // 参比 : KOD_REFERENCE(7) // 列表 : KOD_ENUMERATION(8) // 量纲 : KOD_DIMENSION(9) // 描述 : KOD_DESCRIPTION(10) // 备用 : KOD_BACKUP2(11) // 口令条目 : KOD_PASSWORD(12) // 只读 : KOD_READONLY(13) // 只写 : KOD_WRITEONLY(14) // 备用 : KOD_BACKUP3(15) // 备用 : KOD_BACKUP4(16) // 备用 : KOD_BACKUP5(17) // 备用 : KOD_BACKUP6(18) // 相应的功能类型和信息序号 : KOD_CORFUNCANDINF(19) // 相应的事件 : KOD_COREVENT(20) // 列表的文本阵列 : KOD_ENUMTEXTARRAY(21) // 列表的值阵列 : KOD_ENUMVALUEARRAY(22) // 相关联的条目 : KOD_RELATEDENTRIES(23) //rtumsg->MsgData[16]; // 数据类型描述 //rtumsg->MsgData[17]; //DATAID_NO : 无数据 //DATAID_OS8ASCII : 8位ASCII //DATAID_BSTRING : 字符串 //DATAID_UIX : 无符号整数 //DATAID_INT : 整数 //DATAID_UFLOAT : 无符号浮点数 //DATAID_FLOAT : 浮点数 //DATAID_754SHORT : R32.23 IEEE 标准754短实数 //DATAID_754REAL : R64.53 IEEE 标准754实数 //DATAID_DOUBLE : 双点信息 //DATAID_SINGLE : 单点信息 //DATAID_13BITS : 带品质描述的被测值(13BITS) //DATAID_SORTIDNO : 通用分类标识序号 //DATAID_WITHTIME : 带时标的报文 //DATAID_WITHTIMESPACE : 带相对时标的报文 //DATAID_STRUCT : 数据结构 // 数据尺寸 //rtumsg->MsgData[18] // 数量 //rtumsg->MsgData[19] // 通用分类标识数据(GID) // 长度根据以上描述 // 2 ... n 个通用分类数据 } void Buban103SynTime(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { //char szDbg[128]; int commid; DAY_TIME stime; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; //DebugPrint("sync time."); commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } //DebugPrint("sync time hello1."); // 如果非时间同步原因,则不进行对时 if(M_CAUSE_CHECKTIME != rtumsg->MsgData[8]) { return; } //DebugPrint("sync time hello2."); // 上对时 if(1 != pPortParam->m_psBaoHu->CheckTime) { return; } stime.mSec = rtumsg->MsgData[12] + rtumsg->MsgData[13]*256; stime.Sec = stime.mSec / 1000; stime.mSec = 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; //sprintf(szDbg, "time:%04d-%02d-%02d_%02d:%02d:%02d.%03d\n", // stime.Year, stime.Month, stime.Day, stime.Hour, // stime.Min, stime.Sec, stime.mSec); //DebugPrint(szDbg); SetLocalTimeEx(&stime); } void Buban103EXPIprocess(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int i, commid; int pipnt; PI_DEF pntmsg; DBORIENTATION *pDataUnit; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } pDataUnit = &pDevParam->m_sDevParam.m_sPiDBOrientation; if(pDataUnit->m_iStnNo < 1) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d SIEMENS扩展电度信息不写入数据库!!!", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr); DebugPrint(szbuf); #endif return; } for(i=0; im_iPntNum; i++) { if((pDataUnit->m_psDataInfo[i].m_u8Fun == rtumsg->MsgData[10])\ && (pDataUnit->m_psDataInfo[i].m_u8Inf == rtumsg->MsgData[11])) { break; } } if(i >= pDataUnit->m_iPntNum) { return; } pipnt = pDataUnit->m_iStartPntNo + i; pntmsg.RawValue = rtumsg->MsgData[12] + rtumsg->MsgData[13]*256\ +rtumsg->MsgData[14]*256*256 + (rtumsg->MsgData[15]&0x0f)*256*256*256; // 符号位 if(rtumsg->MsgData[15] & 0x10) { pntmsg.RawValue |= 0xF0000000; } SetPntMsg(pDataUnit->m_iStnNo-1, pipnt, (void *)&pntmsg, PI_PNT_TYPE, PNT_RAWVALUE); } // 扰动数据处理开始 // 扰动数据表处理 void Buban103LRDprocess(RTUMSG *rtumsg) {} // 扰动数据传输准备就绪 void Buban103RTDprocess(RTUMSG *rtumsg) {} // 带标志的状态变位传输准备就绪 void Buban103RTTprocess(RTUMSG *rtumsg) {} // 带标志的状态变位传输 void Buban103TOTprocess(RTUMSG *rtumsg) {} // 被记录的通道传输准备就绪 void Buban103RTCprocess(RTUMSG *rtumsg) {} // 传送扰动值 void Buban103TOVprocess(RTUMSG *rtumsg) {} // 带标志的状态变位、通道、扰动数据传输结束 void Buban103EOTprocess(RTUMSG *rtumsg) {} // 扰动数据处理结束 // 写通道扰动数据到文件中 BOOL Buban103WriteACCDatatoFile(RTUMSG *rtumsg) { return FALSE; } // 读录波数据文件头 void Buban103GetFileHead(char *ptrDataHead, size_t *piNOF, size_t *piNOC, size_t *piNOE, size_t *piINT) {} // 读录波数据记录时间 //void Buban103GetTime(char *ptrDataHead, SYSTEMTIME *ptrtm) //{} // 读录波数据模拟量头 void Buban103ProcessAiHead(char *ptrDataHead, DISTURBANCEAIDATA *pAiData) {} // 转换临时文件为可用文件 void Buban103tmpFileChangetodatFile(char *sztmpFileName) {} // 生成CFG文件 //void Buban103MakeCFGFile(int iStationNo, pDISTURBANCEDIDATA ptrDi, pDISTURBANCEAIDATA ptrAi, FILE *fp, char *szInfFile, SYSTEMTIME *tm) //{} // 生成DAT文件 void Buban103MakeDATFile(pDISTURBANCEDIDATA ptrDi, pDISTURBANCEAIDATA ptrAi, FILE *fp) {} //=========================以下为Buban103转发数据功能=======================// //***************************************************************************/ //* 插入SOE数据函数 */ //*参数: u_32 commid : 厂站端口号 */ //* u_32 selidx : 端口索引号 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //* PROV_SOE *pSoeMsg : 转发SOE数据 */ //*返回值:BOOL retval : 插入SOE数据时是否覆盖(缓冲区是否已满) */ //***************************************************************************/ BOOL ProvInsertSoe(u_32 commid, DEVADDRPARAM *psDevAddrParam, SOE_DEF *pSoeMsg) { BOOL bReturn; short front, rear; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if(FALSE == GetSpecialProvPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pProvDevParam)) { return FALSE; } front = pProvDevParam->m_sProvSoe.m_shFront; rear = pProvDevParam->m_sProvSoe.m_shRear; if(pProvDevParam->m_sProvSoe.m_shSoeNum >= PROV_SOE_MAX) { // 缓冲区已满 memcpy((void *)&pProvDevParam->m_sProvSoe.m_sSoeData[rear], (void *)pSoeMsg, sizeof(SOE_DEF)); pProvDevParam->m_sProvSoe.m_shFront = (front + 1) % PROV_SOE_MAX; pProvDevParam->m_sProvSoe.m_shRear = (rear + 1) % PROV_SOE_MAX; bReturn = FALSE; } else { memcpy((void *)&pProvDevParam->m_sProvSoe.m_sSoeData[rear], (void *)pSoeMsg, sizeof(SOE_DEF)); pProvDevParam->m_sProvSoe.m_shRear = (rear + 1) % PROV_SOE_MAX; pProvDevParam->m_sProvSoe.m_shSoeNum++; bReturn = TRUE; } return bReturn; } //***************************************************************************/ //* 从缓冲区取并且删除SOE数据函数 */ //*参数: u_32 commid : 厂站端口号 */ //* u_32 selidx : 端口索引号 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //* PROV_SOE *pSoeMsg : SOE数据指针 */ //*返回值:BOOL retval : 获取SOE数据是否成功 */ //***************************************************************************/ BOOL ProvGetAndDelSoe(u_32 commid, DEVADDRPARAM *psDevAddrParam, SOE_DEF *pSoeMsg) { short front, rear; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if(FALSE == GetSpecialProvPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pProvDevParam)) { return FALSE; } front = pProvDevParam->m_sProvSoe.m_shFront; rear = pProvDevParam->m_sProvSoe.m_shRear; if(pProvDevParam->m_sProvSoe.m_shSoeNum <= 0) { pProvDevParam->m_sProvSoe.m_shSoeNum = 0; pProvDevParam->m_sProvSoe.m_shFront = 0; pProvDevParam->m_sProvSoe.m_shRear = 0; return FALSE; } memcpy((void *)pSoeMsg, (void *)&pProvDevParam->m_sProvSoe.m_sSoeData[front], sizeof(SOE_DEF)); pProvDevParam->m_sProvSoe.m_shFront = (front + 1) % PROV_SOE_MAX; pProvDevParam->m_sProvSoe.m_shSoeNum--; return TRUE; } BOOL ProvGetNoXSoe(u_32 commid, DEVADDRPARAM *psDevAddrParam, int iNo, SOE_DEF *pSoeMsg) { short rear; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if(FALSE == GetSpecialProvPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pProvDevParam)) { return FALSE; } if(pProvDevParam->m_sProvSoe.m_shSoeNum <= 0) { pProvDevParam->m_sProvSoe.m_shSoeNum = 0; pProvDevParam->m_sProvSoe.m_shFront = 0; pProvDevParam->m_sProvSoe.m_shRear = 0; return FALSE; } iNo = iNo % PROV_SOE_MAX; rear = pProvDevParam->m_sProvSoe.m_shRear - iNo - 1; if(rear < 0) { rear += PROV_SOE_MAX; } memcpy((void *)pSoeMsg, (void *)&pProvDevParam->m_sProvSoe.m_sSoeData[rear], sizeof(SOE_DEF)); return TRUE; } //***************************************************************************/ //* 转发一类数据是否存在函数 */ //*参数: u_32 commid : 厂站端口号 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ BOOL ProvHaveClassOne(u_32 commid, DEVADDRPARAM *psDevAddrParam, BOOL bCheckDiChange) { int i; BOOL bACD, bQueryAllDev; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; bACD = FALSE; if(ProvHaveSoeData(commid) > 0) { bACD = TRUE; } else { if(pLinkParam->m_uchLinkAddr != 0xFF) { bQueryAllDev = TRUE; } else { bQueryAllDev = FALSE; } // 是否转发遥信变位,一般将其屏蔽 if(TRUE == bCheckDiChange) { if(pPortParam->m_psBaoHu != NULL) { if(pPortParam->m_psBaoHu->DiChange == TRUE) { bACD = TRUE; } } } if(bACD == FALSE) { for(i=0; im_iDevNum; i++) { if(bQueryAllDev == TRUE) { psDevAddrParam->m_iDevIdx = i; } else { if(i >= 1) { break; } // 该项判断应该不需要存在 //if(psDevAddrParam->m_iDevIdx >= pLinkParam->m_iDevNum) //{ // break; //} } pProvDevParam = &pLinkParam->m_psProvDev[psDevAddrParam->m_iDevIdx]; // 如果在总查询过程中 //if((pProvDevParam->m_bProvQuery == TRUE) || (pProvDevParam->m_sProvGroupParam.m_bFinished == FALSE)) if(pProvDevParam->m_bProvQuery == TRUE) { bACD = TRUE; break; } if(SingleListHaveData(&pProvDevParam->m_sBaoHuData) > 0) { bACD = TRUE; break; } } } } return bACD; } //***************************************************************************/ //* 转发链路指令的生成函数 */ //*参数: u_32 commid : 厂站端口号 */ //* u_char addr : 间隔设备地址 */ //* u_char cmdidx : 指令生成索引号 */ //* BOOL bACD : 一类数据存在标识 */ //*返回值:无 */ //***************************************************************************/ void ProvMakeLinkCommand(u_32 commid, u_char addr, u_char cmdidx, BOOL bACD) { CLPDU_FIX bClpdu_fix; memset(&bClpdu_fix, 0, sizeof(CLPDU_FIX)); switch(cmdidx) { case M_CON_NA_3: // 确认帧 bClpdu_fix.nSTART = 0x10; if(bACD) bClpdu_fix.nCONTROL = cmdidx | 0x20; else bClpdu_fix.nCONTROL = cmdidx; bClpdu_fix.nADDR = addr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)&bClpdu_fix, 5); break; case M_BY_NA_3: // 忙帧(确认帧) case M_NV_NA_3: // 无所要求的数据帧回答 case M_LKR_NA_3_1: // 链路状态响应帧--链路工作正常 case M_LKR_NA_3_2: // 链路状态响应帧--链路服务未工作 case M_LKR_NA_3_3: // 链路状态响应帧--链路服务未实现 bClpdu_fix.nSTART = 0x10; if(bACD) bClpdu_fix.nCONTROL = cmdidx | 0x20; else bClpdu_fix.nCONTROL = cmdidx; bClpdu_fix.nADDR = addr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)&bClpdu_fix, 5); break; default: break; } } //***************************************************************************/ //* 转发链路指令的生成函数 */ //*参数: u_32 commid : 厂站端口号 */ //* u_char addr : 间隔设备地址 */ //* u_char cmdidx : 指令生成索引号 */ //* BOOL bACD : 一类数据存在标识 */ //* BOOL bClearRecvBuf : 是否清除接收缓冲区 */ //*返回值:无 */ //***************************************************************************/ void ProvMakeLinkCommandEx(u_32 commid, u_char addr, u_char cmdidx, BOOL bACD, BOOL bClearRecvBuf, u_32 cmdtype) { CLPDU_FIX bClpdu_fix; memset(&bClpdu_fix, 0, sizeof(CLPDU_FIX)); switch(cmdidx) { case M_CON_NA_3: // 确认帧 case M_BY_NA_3: // 忙帧(确认帧) case M_NV_NA_3: // 无所要求的数据帧回答 case M_LKR_NA_3_1: // 链路状态响应帧--链路工作正常 case M_LKR_NA_3_2: // 链路状态响应帧--链路服务未工作 case M_LKR_NA_3_3: // 链路状态响应帧--链路服务未实现 bClpdu_fix.nSTART = 0x10; if(bACD) bClpdu_fix.nCONTROL = cmdidx | 0x20; else bClpdu_fix.nCONTROL = cmdidx; bClpdu_fix.nADDR = addr; bClpdu_fix.nCS = CalBuban103Lpc(&bClpdu_fix.nCONTROL, 2); bClpdu_fix.nEnd = 0x16; PutPollCmdToBuf(commid, cmdtype, 0, (char*)&bClpdu_fix, 5); break; default: break; } } //***************************************************************************/ //* 转发链路指令的生成函数 */ //*参数: u_32 commid : 厂站端口号 */ //* u_char addr : 间隔设备地址 */ //* u_char cmdidx : 指令生成索引号 */ //* BOOL bACD : 一类数据存在标识 */ //* BYTE bCause : 传送原因 */ //* u_32 cmdtype : 指令缓冲区类型 */ //*返回值:无 */ //***************************************************************************/ void ProvMakeVarCommand(u_32 commid, u_char linkaddr, u_char addr, \ u_char cmdidx, BOOL bACD, BYTE bCause, u_32 cmdtype) { u_char tmp[MAX_POLL_CMD_BUF_LEN]; CLPDU_VARR *ptrClpdu_varr; i_32 len; memset(tmp, 0, sizeof(tmp)); ptrClpdu_varr = (CLPDU_VARR *)tmp; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; ptrClpdu_varr->nADDR = linkaddr; if(bACD) ptrClpdu_varr->nCONTROL = 0x28; else ptrClpdu_varr->nCONTROL = 0x08; len = 0; switch(cmdidx) { case M_TM_TA_3://带时标的报文 break; case M_TMR_TA_3://具有相对时间的带时标的报文 break; case M_MEI_NA_3://被测值I break; case M_TME_TA_3://具有相对时间的带时标的被测值 break; case M_IRC_NA_3://标识 len = sizeof(CLPDU_VARR); tmp[len++] = cmdidx; tmp[len++] = 0x81; tmp[len++] = bCause; tmp[len++] = addr; tmp[len++] = FUNC_GLOBAL; tmp[len++] = bCause-1; tmp[len++] = 2; memcpy(tmp+len, "SZ-SCADA", 8); len += 8; tmp[len++] = 0x01; len += 3; break; case M_SYN_TA_3://时间同步 break; case M_TGI_NA_3://总查询(总召唤)终止 len = sizeof(CLPDU_VARR); tmp[len++] = cmdidx; tmp[len++] = 0x81; tmp[len++] = bCause; tmp[len++] = addr; tmp[len++] = FUNC_GLOBAL; tmp[len++] = 0; tmp[len++] = 0; break; case M_MEII_NA_3://被测值II break; case M_GD_NTA_3://通用分类数据 break; case M_GI_NTA_3://通用分类标识 break; case M_LRD_TA_3://被记录的扰动表 break; case M_RTD_TA_3://扰动数据传输准备就绪 break; case M_RTC_NA_3://被记录的通道传输准备就绪 break; case M_RTT_NA_3://带标志的状态变位传输准备就绪 break; case M_TOT_TA_3://传送带标志的状态变位 break; case M_TOV_NA_3://传送扰动值 break; case M_EOT_TA_3://传送结束 break; case M_MEIII_TA_3://带时标的被测值Ⅲ break; case M_MEIV_TA_3://带时标的被测值Ⅳ break; case M_MEV_TA_3://带时标的被测值Ⅴ break; case M_MEVI_TA_3://带时标的被测值Ⅵ break; case M_MEVII_NA_3://被测值Ⅶ break; case M_IT_NA_3://电能脉冲计数值 break; case M_IT_TA_3://带时标的电能脉冲计数值 break; case M_ST_NA_3://步位置信息 break; case M_ST_TA_3://带时标的步位置信息 break; case M_SP_NA_3://单点状态信息 break; case M_SP_TA_3://带时标的单点状态信息 break; case M_DP_NA_3://双点状态信息 break; case M_DP_TA_3://带时标的双点状态信息 break; case M_SS_NA_3://单点状态和状态变位检出 break; case M_SS_TA_3://带时标的单点状态和状态变位检出 break; case M_DS_NA_3://双点状态和状态变位检出 break; case M_DS_TA_3://带时标的双点状态和状态变位检出 break; case M_WL_TA_3://水位 break; case M_DC_NA_3://控制断路器命令 break; case M_RC_NA_3://升降命令 break; case M_SE_NA_3://设定命令 break; case M_CC_NA_3://控制命令 break; } if(len > 0) { ptrClpdu_varr->nLEN1 = len - 4; ptrClpdu_varr->nLEN2 = len - 4; tmp[len++] = CalBuban103Lpc(tmp+4, ptrClpdu_varr->nLEN1); tmp[len++] = 0x16; PutPollCmdToBuf(commid, cmdtype, 0, (char*)tmp, len); } } //***************************************************************************/ //* 转发命令处理 */ //*参数: u_32 portidx : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //*返回值:无 */ //***************************************************************************/ void ProvRtuProtocolDataProcess(int commid, RTUMSG *rtumsg) { if(rtumsg->MsgLen == 0) return; // 数据校验错误(附加字节的第二个字节) if(rtumsg->MsgData[rtumsg->MsgLen+1] > 0) return; // wen 增加限制,以使得指令缓冲区不会生成多条指令 //if(CheckPollCmdBuf(commid)) return; switch(rtumsg->MsgData[0]) { case 0x10://shortframe process Provshortprocess(commid, rtumsg); break; case 0x68: Provlongprocess(commid, rtumsg); break; default: break; } } //***************************************************************************/ //* 保护命令数据处理函数 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvSendCmdToPort(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { u_32 destport; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if(FALSE == GetSpecialProvPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pProvDevParam)) { return; } if((C_GD_NA_3 != rtumsg->MsgData[6])\ && (C_GRC_NA_3 != rtumsg->MsgData[6])\ && (C_GC_NA_3 != rtumsg->MsgData[6])) { return; } // ??? 在这里将保护数据发送到指定的装置下发端口 if(pProvDevParam->m_iRealCommid > 0) { destport = pProvDevParam->m_iRealCommid-1; } else { return; } rtumsg->MsgData[12] = RII_PROV_ID; rtumsg->MsgType = MSGTYPE_BAOHU_103CMD; SendProtectCmdToDev(destport, rtumsg); } //***************************************************************************/ //* 数据转发短帧处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //*返回值:无 */ //***************************************************************************/ void Provshortprocess(u_32 commid, RTUMSG *rtumsg) { BOOL bFind; DEVADDRPARAM DevAddrParam; BUBAN103LINKDEF *pLinkParam=NULL; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif if((rtumsg->MsgData[1] & 0xc0) == 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d(CtrlByte=%02x)接收到的短帧数据不是主站命令!!!\n", commid, rtumsg->MsgData[2], rtumsg->MsgData[1]); DebugPrint(szbuf); #endif return; } if(!IsExtInfoPtr(commid)) { return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; DevAddrParam.m_uchLinkAddr = rtumsg->MsgData[2]; if(FindProtectDev(pPortParam, &DevAddrParam, TRUE) == FALSE) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d 不匹配!!!\n", commid, rtumsg->MsgData[2]); DebugPrint(szbuf); #endif bFind = FALSE; } else { bFind = TRUE; } //printf("commid=%d, iLinkIdx=%d, iDevIdx=%d\n", commid, DevAddrParam.m_iLinkIdx, DevAddrParam.m_iDevIdx); if(TRUE == bFind) { pLinkParam = &pPortParam->m_psLink[DevAddrParam.m_iLinkIdx]; } /* if((rtumsg->MsgData[1] & 0x0f) == C_RCU_NA_3) { //InitBuban103LinkCmdBuf(pLinkParam); //SetDevLinkOk(pLinkParam, DevAddrParam.m_iDevIdx, TRUE); ProvMakeLinkCommand(commid, rtumsg->MsgData[2], M_CON_NA_3, TRUE); //pLinkParam->m_psProvDev[DevAddrParam.m_iDevIdx].m_iProvAsdu5Cause = M_CAUSE_RESET_CU; } return; */ switch(rtumsg->MsgData[1] & 0x0f) { case C_RCU_NA_3://复位通信单元 if(TRUE == bFind) { InitBuban103LinkCmdBuf(pLinkParam); SetDevLinkOk(pLinkParam, DevAddrParam.m_iDevIdx, TRUE); ProvMakeLinkCommand(commid, rtumsg->MsgData[2], M_CON_NA_3, TRUE); pLinkParam->m_psProvDev[DevAddrParam.m_iDevIdx].m_iProvAsdu5Cause = M_CAUSE_RESET_CU; } else { ProvMakeLinkCommand(commid, rtumsg->MsgData[2], M_CON_NA_3, FALSE); } break; case C_RFB_NA_3://复位帧计数位 if(TRUE == bFind) { pLinkParam->m_pu8CtlByte[DevAddrParam.m_iDevIdx] = 0; pLinkParam->m_psProvDev[DevAddrParam.m_iDevIdx].m_iProvAsdu5Cause = M_CAUSE_RESET_FCB; ProvMakeLinkCommand(commid, rtumsg->MsgData[2], M_CON_NA_3, TRUE); } else { ProvMakeLinkCommand(commid, rtumsg->MsgData[2], M_CON_NA_3, FALSE); } break; case C_RLK_NA_3://链路状态请求 if(TRUE == bFind) { ProvMakeLinkCommand(commid, rtumsg->MsgData[2], M_LKR_NA_3_1, FALSE); } else { ProvMakeLinkCommand(commid, rtumsg->MsgData[2], M_LKR_NA_3_2, FALSE); } break; case C_PL1_NA_3://召唤一级数据 if(FALSE == bFind) { break; } if(TRUE == IsDevLinkOk(pLinkParam, DevAddrParam.m_iDevIdx)) { // 查找链路中所有的装置 //if(pLinkParam->m_uchLinkAddr != 0xFF) //{ // DevAddrParam.m_iDevIdx = -1; //} ProvPL1process(commid, &DevAddrParam); } break; case C_PL2_NA_3://召唤二级数据 if(FALSE == bFind) { break; } if(TRUE == IsDevLinkOk(pLinkParam, DevAddrParam.m_iDevIdx)) { // 查找链路中所有的装置 //if(pLinkParam->m_uchLinkAddr != 0xFF) //{ // DevAddrParam.m_iDevIdx = -1; //} ProvPL2process(commid, &DevAddrParam); } break; default: break; } } //***************************************************************************/ //* 转发一类数据处理 */ //*参数: u_32 commid : 厂站端口号 */ //* u_char addr : 间隔设备地址 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvPL1process(u_32 commid, DEVADDRPARAM *psDevAddrParam) { BOOL bACD; WORD wValue; DAY_TIME sCurTime; SOE_DEF sSoeData; DI_DEF pntmsg; PROV_DI_PNT *diprovptr; DBINFO sDbInfo; i_32 i, len; char szDebugbuf[256]; RTUMSG rtumsg, msg; DBORIENTATION *pDBUnit; CLPDU_VARR *ptrClpdu_varr; DEVADDRPARAM sDevAddrParam; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; memset(szDebugbuf, 0, sizeof(szDebugbuf)); memset((void *)&rtumsg, 0, sizeof(rtumsg)); pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; pProvDevParam = &pLinkParam->m_psProvDev[psDevAddrParam->m_iDevIdx]; if(pProvDevParam->m_iProvAsdu5Cause > 0) { ProvMakeVarCommand(commid, pLinkParam->m_uchLinkAddr,\ (BYTE)pProvDevParam->m_iProvAddr, M_IRC_NA_3, FALSE,\ (BYTE)pProvDevParam->m_iProvAsdu5Cause, FAST_POLL_CMD); pProvDevParam->m_iProvAsdu5Cause = 0; return; } // 首先发送突发事件(由于所有装置的信息都在一个缓冲区,所以只能有一个公共链路) while(ProvHaveSoeData(commid) > 0) { ProvAndDelGetSoeData(commid, &sSoeData); //if(ProvAndDelGetSoeData(commid, &sSoeData) > 0) //{ // bACD = TRUE; //} //else //{ // bACD = ProvHaveClassOne(commid, psDevAddrParam, FALSE); //} if(FALSE == FindProtectDevFromPntNo(pPortParam, &sDevAddrParam, &sDbInfo, sSoeData.iPntNo, DI_PNT_TYPE)) { continue; } ptrClpdu_varr = (CLPDU_VARR *)rtumsg.MsgData; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; // 重新赋值链路的转发地址 ptrClpdu_varr->nADDR = sDevAddrParam.m_uchLinkAddr; // 如果在总查询过程中 /* if(pLinkParam->m_psProvDev[psDevAddrParam->m_iDevIdx].m_bProvQuery) { ptrClpdu_varr->nCONTROL |= 0x20; } else { // 是否还有一类数据 if(TRUE == bACD) { ptrClpdu_varr->nCONTROL |= 0x20; } else { ptrClpdu_varr->nCONTROL &= 0xDF; } }*/ // 是否还有一类数据 //if(TRUE == bACD) //{ // ptrClpdu_varr->nCONTROL |= 0x20; //} //else //{ // ptrClpdu_varr->nCONTROL &= 0xDF; //} ptrClpdu_varr->nCONTROL &= 0xDF; wValue = sSoeData.SoeTime.mSec + sSoeData.SoeTime.Sec * 1000; if(sSoeData.u8Type == 1) { rtumsg.MsgData[sizeof(CLPDU_VARR)] = 0x01; len = 14; // 四个八位二进制组 rtumsg.MsgData[sizeof(CLPDU_VARR)+7] = LOBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+8] = HIBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+9] = sSoeData.SoeTime.Min & 0x3F; rtumsg.MsgData[sizeof(CLPDU_VARR)+10] = sSoeData.SoeTime.Hour & 0x1F; // SIN rtumsg.MsgData[sizeof(CLPDU_VARR)+11] = 0; } else { rtumsg.MsgData[sizeof(CLPDU_VARR)] = 0x02; len = 18; // 四个八位二进制组 rtumsg.MsgData[sizeof(CLPDU_VARR)+7] = LOBYTE(sSoeData.wRelativeTime); rtumsg.MsgData[sizeof(CLPDU_VARR)+8] = HIBYTE(sSoeData.wRelativeTime); rtumsg.MsgData[sizeof(CLPDU_VARR)+9] = LOBYTE(sSoeData.wFaultNo); rtumsg.MsgData[sizeof(CLPDU_VARR)+10] = HIBYTE(sSoeData.wFaultNo); rtumsg.MsgData[sizeof(CLPDU_VARR)+11] = LOBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+12] = HIBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+13] = sSoeData.SoeTime.Min & 0x3F; rtumsg.MsgData[sizeof(CLPDU_VARR)+14] = sSoeData.SoeTime.Hour & 0x1F; // SIN rtumsg.MsgData[sizeof(CLPDU_VARR)+15] = 0; } ptrClpdu_varr->nLEN1 = (BYTE)len; ptrClpdu_varr->nLEN2 = (BYTE)len; rtumsg.MsgData[sizeof(CLPDU_VARR)+1] = 0x81; //COT rtumsg.MsgData[sizeof(CLPDU_VARR)+2] = M_CAUSE_AUTOSEND; // 重新赋值 ASDU 公共地址 rtumsg.MsgData[sizeof(CLPDU_VARR)+3] = sDevAddrParam.m_uchCommAddr; // FUN //rtumsg.MsgData[sizeof(CLPDU_VARR)+4] = sSoeData.u8ProvFun; // INF //rtumsg.MsgData[sizeof(CLPDU_VARR)+5] = sSoeData.u8ProvInf; // FUN rtumsg.MsgData[sizeof(CLPDU_VARR)+4] = sDbInfo.m_u8ProvFun; // INF rtumsg.MsgData[sizeof(CLPDU_VARR)+5] = sDbInfo.m_u8ProvInf; // DPI rtumsg.MsgData[sizeof(CLPDU_VARR)+6] = sSoeData.bStatus+1; len = ptrClpdu_varr->nLEN1 + 4; // 发送时会重新计算 //rtumsg.MsgData[len++] = CalBuban103Lpc(rtumsg.MsgData+4, ptrClpdu_varr->nLEN1); rtumsg.MsgData[len++] = 0; rtumsg.MsgData[len++] = 0x16; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)rtumsg.MsgData, len); return; } bACD = ProvHaveClassOne(commid, psDevAddrParam, pPortParam->m_bSendChangeDi); if(bACD == TRUE) { // ??? 需要修改为实际信息 //bACD = FALSE; pProvDevParam = &pLinkParam->m_psProvDev[psDevAddrParam->m_iDevIdx]; if(SingleListHaveData(&pProvDevParam->m_sBaoHuData) > 0) { msg.MsgLen = SingleListGetAndDelData(&pProvDevParam->m_sBaoHuData, msg.MsgData, sizeof(msg.MsgData)); if(pLinkParam->m_uchLinkAddr != 0xFF) { msg.MsgData[5] = pLinkParam->m_uchLinkAddr; } else { msg.MsgData[5] = (BYTE)pProvDevParam->m_iProvAddr; } msg.MsgData[9] = (BYTE)pProvDevParam->m_iProvAddr; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)msg.MsgData, msg.MsgLen); return; } // 是否转发遥信变位,一般将其屏蔽 if(pPortParam->m_bSendChangeDi == TRUE) { if(pPortParam->m_psBaoHu->DiChange == TRUE) { if(TRUE == ProvSendChangedDi(commid, psDevAddrParam)) { return; } } } // 如果在总查询过程中 if(pProvDevParam->m_bProvQuery == TRUE) { pDBUnit = &pProvDevParam->m_sYxInfo; for(i=pProvDevParam->m_iQueryPntNo; im_iPntNum; i++) { // 如果是总召唤数据 if(pDBUnit->m_psDataInfo[i].m_u8LoopData) { break; } } if(i >= pDBUnit->m_iPntNum) { pProvDevParam->m_bProvQuery = FALSE; pProvDevParam->m_iProvQueryStepWithASDU = 0; ProvMakeVarCommand(commid, pLinkParam->m_uchLinkAddr,\ (BYTE)pProvDevParam->m_iProvAddr, M_TGI_NA_3, FALSE,\ (BYTE)M_CAUSE_STOPQUERY, FAST_POLL_CMD); pProvDevParam->m_iQueryPntNo = 0; } else { pProvDevParam->m_iQueryPntNo++; diprovptr = (PROV_DI_PNT *)pPortParam->m_psBaoHu->DiPtr; ptrClpdu_varr = (CLPDU_VARR *)rtumsg.MsgData; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; // 重新赋值链路的转发地址 ptrClpdu_varr->nADDR = pLinkParam->m_uchLinkAddr; // 如果在总查询过程中 ptrClpdu_varr->nCONTROL |= 0x20; rtumsg.MsgData[sizeof(CLPDU_VARR)] = 0x01; len = 14; rtumsg.MsgData[sizeof(CLPDU_VARR)+1] = 0x81; //COT //rtumsg.MsgData[sizeof(CLPDU_VARR)+2] = M_CAUSE_AUTOSEND; rtumsg.MsgData[sizeof(CLPDU_VARR)+2] = M_CAUSE_QUERY; // 重新赋值 ASDU 公共地址 rtumsg.MsgData[sizeof(CLPDU_VARR)+3] = (BYTE)pProvDevParam->m_iProvAddr; // FUN rtumsg.MsgData[sizeof(CLPDU_VARR)+4] = pDBUnit->m_psDataInfo[i].m_u8ProvFun; // INF rtumsg.MsgData[sizeof(CLPDU_VARR)+5] = pDBUnit->m_psDataInfo[i].m_u8ProvInf; GetPntMsg(diprovptr[pDBUnit->m_iStartPntNo+i].PortNo,\ diprovptr[pDBUnit->m_iStartPntNo+i].PntNo,\ (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); // DPI rtumsg.MsgData[sizeof(CLPDU_VARR)+6] = pntmsg.Status+1; GetLocalTimeEx(&sCurTime); wValue = sCurTime.Sec*1000+sCurTime.mSec; // 四个八位二进制组 rtumsg.MsgData[sizeof(CLPDU_VARR)+7] = LOBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+8] = HIBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+9] = sCurTime.Min & 0x3F; rtumsg.MsgData[sizeof(CLPDU_VARR)+10] = sCurTime.Hour & 0x1F; // SIN rtumsg.MsgData[sizeof(CLPDU_VARR)+11] = 0; ptrClpdu_varr->nLEN1 = (BYTE)len; ptrClpdu_varr->nLEN2 = (BYTE)len; len = ptrClpdu_varr->nLEN1 + 4; // 发送时会重新计算 //rtumsg.MsgData[len++] = CalBuban103Lpc(rtumsg.MsgData+4, ptrClpdu_varr->nLEN1); rtumsg.MsgData[len++] = 0; rtumsg.MsgData[len++] = 0x16; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)rtumsg.MsgData, len); } return; } } /* if(pLinkParam->m_uchLinkAddr != 0xFF) { ProvMakeLinkCommand(commid, pLinkParam->m_uchLinkAddr, M_NV_NA_3, FALSE); } else { ProvMakeLinkCommand(commid, psDevAddrParam->m_uchLinkAddr, M_NV_NA_3, FALSE); } */ //ProvMakeLinkCommand(commid, psDevAddrParam->m_uchLinkAddr, M_NV_NA_3, bACD); ProvMakeLinkCommand(commid, psDevAddrParam->m_uchLinkAddr, M_NV_NA_3, FALSE); } //***************************************************************************/ //* 转发二类数据处理 */ //*参数: u_32 commid : 厂站端口号 */ //* u_char addr : 间隔设备地址 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvPL2process(u_32 commid, DEVADDRPARAM *psDevAddrParam) { //BOOL bACD; //PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; //pProvDevParam = &pLinkParam->m_psProvDev[pLinkParam->m_iDevIdx]; //psDevAddrParam->m_iDevIdx = pLinkParam->m_iDevIdx; /* // 首先发送突发事件 if(ProvHaveSoeData(commid) > 0) { bACD = TRUE; } else if(pProvDevParam->m_bProvQuery == TRUE) { bACD = TRUE; } else { bACD = FALSE; } */ //bACD = ProvHaveClassOne(commid, psDevAddrParam, FALSE); //ProvMakeLinkCommand(commid, pLinkParam->m_uchLinkAddr, M_NV_NA_3, bACD); ProvMakeLinkCommand(commid, pLinkParam->m_uchLinkAddr, M_NV_NA_3, FALSE); } //***************************************************************************/ //* 数据转发长帧处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //*返回值:无 */ //***************************************************************************/ void Provlongprocess(u_32 commid, RTUMSG *rtumsg) { BOOL bFind; DEVADDRPARAM DevAddrParam; BUBAN103LINKDEF *pLinkParam=NULL; BUBAN103PORTPARAM *pPortParam=NULL; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif if((rtumsg->MsgData[4] & 0xc0) == 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d(CtrlByte=%02x)接收到的短帧数据不是主站命令!!!\n", commid, rtumsg->MsgData[5], rtumsg->MsgData[4]); DebugPrint(szbuf); #endif return; } if(!IsExtInfoPtr(commid)) { return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; DevAddrParam.m_uchLinkAddr = rtumsg->MsgData[5]; DevAddrParam.m_uchCommAddr = rtumsg->MsgData[9]; if(0xFF != DevAddrParam.m_uchLinkAddr) { if(FindProtectDev(pPortParam, &DevAddrParam, FALSE) == FALSE) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 不匹配!!!\n", commid, rtumsg->MsgData[5], rtumsg->MsgData[9]); DebugPrint(szbuf); #endif bFind = FALSE; } else { bFind = TRUE; } if(TRUE == bFind) { pLinkParam = &pPortParam->m_psLink[DevAddrParam.m_iLinkIdx]; } if(IsDevLinkOk(pLinkParam, DevAddrParam.m_iDevIdx) == FALSE) { return; } } else { if(C_SYN_TA_3 != rtumsg->MsgData[6]) { return; } } // 长帧数据的功能类型 switch(rtumsg->MsgData[6]) { case C_SYN_TA_3: //时间同步 ProvSYNprocess(commid, rtumsg); break; case C_TGI_NA_3: //总查询(总召唤) ProvTGIprocess(commid, rtumsg, &DevAddrParam); break; case C_GD_NA_3: //通用分类数据 ProvGDprocess(commid, rtumsg, &DevAddrParam); //ProvSendCmdToPort(commid, rtumsg, &DevAddrParam); break; case C_GRC_NA_3: //一般命令 ProvGRCprocess(commid, rtumsg, &DevAddrParam); break; case C_GC_NA_3: //通用分类命令 ProvGCprocess(commid, rtumsg, &DevAddrParam); //ProvSendCmdToPort(commid, rtumsg, &DevAddrParam); break; case C_ODT_NA_3: //扰动数据传输的命令 ProvODTprocess(commid, rtumsg, &DevAddrParam); break; case C_ADT_NA_3: //扰动数据传输的认可 ProvADTprocess(commid, rtumsg, &DevAddrParam); break; case C_DC_NA_3: //控制断路器命令 ProvDCprocess(commid, rtumsg, &DevAddrParam); break; case C_RC_NA_3: //升降命令 ProvRCprocess(commid, rtumsg, &DevAddrParam); break; case C_SE_NA_3: //设定命令 ProvSEprocess(commid, rtumsg, &DevAddrParam); break; case C_CC_NA_3: //控制命令 ProvCCprocess(commid, rtumsg, &DevAddrParam); break; case C_CI_NA_3: //电能脉冲计数召唤命令 ProvCIprocess(commid, rtumsg, &DevAddrParam); break; default: break; } switch(rtumsg->MsgData[4] & 0x0f) { case C_SD1_NA_3://传送数据(发送/确认帧) // 非总查询命令 /* if(C_TGI_NA_3 == rtumsg->MsgData[6]) { ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_CON_NA_3, TRUE); } else if(C_SYN_TA_3 == rtumsg->MsgData[6]) { if(rtumsg->MsgData[5] != 0xFF) { ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_CON_NA_3, TRUE); } } else { ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_CON_NA_3, FALSE); } */ //if(TRUE == ProvHaveClassOne(commid, &DevAddrParam, FALSE)) //{ // ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_CON_NA_3, TRUE); //} //else //{ // ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_CON_NA_3, FALSE); //} ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_CON_NA_3, FALSE); break; case C_SD2_NA_3://传送数据(发送/无回答帧) break; } } //***************************************************************************/ //* 转发时间同步处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //*返回值:无 */ //***************************************************************************/ void ProvSYNprocess(u_32 commid, RTUMSG *rtumsg) { i_32 len; DAY_TIME sTime; //char szDbg[128]; u_char tmp[MAX_POLL_CMD_BUF_LEN]; CLPDU_VARR bClpdu_varr; BUBAN103PORTPARAM *pPortParam; if(!IsExtInfoPtr(commid)) { return; } pPortParam = (pBUBAN103PORTPARAM)SioParam[commid].ExtInfo; sTime.mSec = rtumsg->MsgData[12] + (rtumsg->MsgData[13] << 8); sTime.Sec = sTime.mSec / 1000; sTime.mSec = 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; //sprintf(szDbg, "time:%04d-%02d-%02d_%02d:%02d:%02d.%03d\n", // sTime.Year, sTime.Month, sTime.Day, sTime.Hour, // sTime.Min, sTime.Sec, sTime.mSec); //DebugPrint(szDbg); // 如果时间同步原因,则进行对时 if((pPortParam->m_psBaoHu->CheckTime == 1) && (rtumsg->MsgData[8] == M_CAUSE_CHECKTIME)) { SetLocalTimeEx(&sTime); } // 广播地址 if(rtumsg->MsgData[5] == 0xff) { return; } memset(&bClpdu_varr, 0 , sizeof(CLPDU_VARR)); memset(tmp , 0 , sizeof(tmp)); bClpdu_varr.nSTART1 = 0x68; bClpdu_varr.nSTART2 = 0x68; bClpdu_varr.nLEN1 = 15; bClpdu_varr.nLEN2 = 15; bClpdu_varr.nCONTROL = M_DATA_NA_3; bClpdu_varr.nADDR = rtumsg->MsgData[5]; len = sizeof(bClpdu_varr); memcpy(tmp, (char*)&bClpdu_varr, len); tmp[len++] = M_SYN_TA_3; tmp[len++] = 0x81; tmp[len++] = M_CAUSE_CHECKTIME; tmp[len++] = rtumsg->MsgData[9]; tmp[len++] = FUNC_GLOBAL; tmp[len++] = 0; memcpy(tmp+len, rtumsg->MsgData+12, 7); //if(!SetLocalTime(&t)) // tmp[len+2] |= 0x80; len += 7; //tmp[len++] = CalBuban103Lpc(tmp+4, bClpdu_varr.nLEN1); tmp[len++] = 0; tmp[len++] = 0x16; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)tmp, len); } //***************************************************************************/ //* 转发总查询(总召唤)处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvTGIprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if(GetPortParamPtr(commid, &pPortParam) == FALSE) { return; } pPortParam->m_iLinkIdx = psDevAddrParam->m_iLinkIdx; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; pLinkParam->m_iDevIdx = psDevAddrParam->m_iDevIdx; pProvDevParam = &pLinkParam->m_psProvDev[psDevAddrParam->m_iDevIdx]; // 总查询开始 pProvDevParam->m_bProvQuery = TRUE; pProvDevParam->m_iProvQueryStepWithASDU = M_MEVII_NA_3; // 存在一类数据,请查询 //ProvMakeLinkCommand(commid, rtumsg->MsgData[9], M_CON_NA_3, TRUE); //ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_CON_NA_3, TRUE); } //***************************************************************************/ //* 转发通用分类数据处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvGDprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { //PROVDEVDEF *pProvDevParam; //BUBAN103LINKDEF *pLinkParam; //BUBAN103PORTPARAM *pPortParam; if(rtumsg->MsgData[12] != RII_PROV_ID) { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); return; } //if(FALSE == GetSpecialProvPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pProvDevParam)) //{ // return; //} } //***************************************************************************/ //* 转发一般命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvGRCprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { if(rtumsg->MsgData[12] != RII_PROV_ID) { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); return; } } //***************************************************************************/ //* 转发通用分类命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvGCprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { int iGrpNum; GROUPDEF *pBaoHuDB; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; /*wen 2005.06.01 实际情况需要安这样来处理数据,直接转发到装置去 if(rtumsg->MsgData[12] != RII_PROV_ID) { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); return; } */ if(FALSE == GetSpecialProvPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pProvDevParam)) { return; } if(rtumsg->MsgData[12] != RII_PROV_ID) { pProvDevParam->m_sProvGroupParam.m_u8Group = rtumsg->MsgData[9]; pProvDevParam->m_sProvGroupParam.m_u8ItemAttr = rtumsg->MsgData[11]; pProvDevParam->m_sProvGroupParam.m_u8ItemNo = rtumsg->MsgData[10]; pProvDevParam->m_sProvGroupParam.m_u8RII = rtumsg->MsgData[12]; pBaoHuDB = NULL; iGrpNum = GetBaohuDB(pProvDevParam->m_iRealCommid-1, pProvDevParam->m_iProvAddr, &pBaoHuDB); // 传送原因(通用分类读数据) if(rtumsg->MsgData[8] == C_CAUSE_READWITHVALIDDATA) { // INF switch(rtumsg->MsgData[11]) { case C_INF_READGROUPTITLE: // 读组标题 if((pBaoHuDB != NULL) && (iGrpNum > 0)) { ProvMakeTitleOfGroups(commid, rtumsg, pProvDevParam, pBaoHuDB, iGrpNum); } else { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); } break; case C_INF_READGROUPALLITEMS: // 读一个组的全部条目的值或属性 if((pBaoHuDB != NULL) && (iGrpNum > 0)) { ProvMakeAttrOfAllItemInGroup(commid, rtumsg, pProvDevParam, pBaoHuDB, iGrpNum); } else { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); } break; case C_INF_READDIROFSINGLEITEM: // 读单个条目的目录 if((pBaoHuDB != NULL) && (iGrpNum > 0)) { ProvMakeDirOfItem(commid, rtumsg, pProvDevParam, pBaoHuDB, iGrpNum); } else { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); } break; case C_INF_READATTROFISNGLEITEM:// 读单个条目的值或属性 if((pBaoHuDB != NULL) && (iGrpNum > 0)) { ProvMakeAttrOfItem(commid, rtumsg, pProvDevParam, pBaoHuDB, iGrpNum); } else { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); } break; case C_INF_QUERYGENERAL: // 对通用分类数据总查询 ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_NV_NA_3, FALSE); break; default: ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); break; } } else { ProvSendCmdToPort(commid, rtumsg, psDevAddrParam); } return; } // wen test 可以添加保护数据返回做测试用 if(RII_PROV_ID == rtumsg->MsgData[12]) { // test RTUMSG msg; BYTE buffix[] = {0x68, 0x46, 0x46, 0x68, 0x08, 0x01, 0x0A, 0x81, 0x2A, 0x01, 0xFE, 0xF1, 0xFF, 0x06, 0x50, 0x01, 0x01, 0x07, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02, 0x01, 0x07, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x03, 0x01, 0x07, 0x04, 0x01, 0x22, 0xDB, 0x79, 0x3F, 0x50, 0x04, 0x01, 0x07, 0x04, 0x01, 0x3D, 0x6A, 0x53, 0x43, 0x50, 0x05, 0x01, 0x07, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x50, 0x06, 0x01, 0x07, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00, 0x08, 0x16 }; BYTE bufsoe[] = {0x68, 0x0E, 0x0E, 0x68, 0x28, 0x01, 0x01, 0x81, 0x01, 0x01, 0x64, 0x42, 0x01, 0x70, 0x94, 0x05, 0x0D, 0x00, 0x6A, 0x16}; msg.MsgLen = sizeof(buffix); memcpy(msg.MsgData, buffix, msg.MsgLen); msg.PortIdx = (BYTE)commid; if(pLinkParam->m_uchLinkAddr != 0xFF) { msg.MsgData[5] = pLinkParam->m_uchLinkAddr; } else { msg.MsgData[5] = (BYTE)pProvDevParam->m_iProvAddr; } msg.MsgData[9] = (BYTE)pProvDevParam->m_iProvAddr; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); return; } } //***************************************************************************/ //* 转发扰动数据传输的命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvODTprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { } //***************************************************************************/ //* 转发扰动数据传输的认可处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvADTprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { } //***************************************************************************/ //* 转发控制断路器命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvDCprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { } //***************************************************************************/ //* 转发升降命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvRCprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { } //***************************************************************************/ //* 转发设定命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvSEprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { } //***************************************************************************/ //* 转发控制命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvCCprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { } //***************************************************************************/ //* 转发电能脉冲计数召唤命令处理 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ void ProvCIprocess(u_32 commid, RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam) { i_32 iPiNum; i_32 i; u_char tmp[MAX_POLL_CMD_BUF_LEN]; CLPDU_VARR *ptrClpdu_varr; i_32 len; PI_DEF pntmsg; PROV_PI_PNT *piprovptr; PROVDEVDEF *pProvDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; if(GetSpecialProvPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pProvDevParam) == FALSE) { return; } memset(tmp, 0, sizeof(tmp)); ptrClpdu_varr = (CLPDU_VARR *)tmp; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; ptrClpdu_varr->nADDR = rtumsg->MsgData[5]; //if(ProvHaveClassOne(commid, psDevAddrParam, TRUE)) //{ // ptrClpdu_varr->nCONTROL = 0x28; //} //else //{ // ptrClpdu_varr->nCONTROL = 0x08; //} ptrClpdu_varr->nCONTROL = 0x08; len = sizeof(CLPDU_VARR); tmp[len++] = M_IT_NA_3; tmp[len++] = 0x00; tmp[len++] = M_CAUSE_CYCLE; tmp[len++] = rtumsg->MsgData[9]; tmp[len++] = 1; iPiNum = pProvDevParam->m_sYmInfo.m_iPntNum; if(iPiNum > INF_PI_NUM) { iPiNum = INF_PI_NUM; } piprovptr = (PROV_PI_PNT *)pPortParam->m_psBaoHu->PiPtr; if((pProvDevParam->m_sYmInfo.m_iStartPntNo+iPiNum)\ > pPortParam->m_psBaoHu->PiNum) { if((pProvDevParam->m_bProvQuery == TRUE)\ || (CheckPollCmdBufEmpty(commid) == 0)) { //ProvMakeLinkCommand(commid, pLinkParam->m_uchLinkAddr, M_NV_NA_3, TRUE); ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_NV_NA_3, TRUE); } else { //ProvMakeLinkCommand(commid, pLinkParam->m_uchLinkAddr, M_NV_NA_3, FALSE); ProvMakeLinkCommand(commid, rtumsg->MsgData[5], M_NV_NA_3, FALSE); } return; } tmp[len++] = INF_PI_START; for(i=0; im_sYmInfo.m_iStartPntNo+i].PortNo,\ piprovptr[pProvDevParam->m_sYmInfo.m_iStartPntNo+i].PntNo,\ &pntmsg, PI_PNT_TYPE, PNT_RAWVALUE); tmp[len++] = (BYTE)(pntmsg.RawValue & 0xFF); tmp[len++] = (BYTE)((pntmsg.RawValue & 0xFF00) >> 8); tmp[len++] = (BYTE)((pntmsg.RawValue & 0xFF0000) >> 16); tmp[len++] = (BYTE)((pntmsg.RawValue & 0xFF000000) >> 24); // IV/CA/CY/顺序号 len++; } tmp[sizeof(CLPDU_VARR)+1] = (BYTE)(iPiNum); // 返回码RII tmp[len++] = rtumsg->MsgData[13]; ptrClpdu_varr->nLEN1 = len - 4; ptrClpdu_varr->nLEN2 = len - 4; //tmp[len++] = CalBuban103Lpc(tmp+4, ptrClpdu_varr->nLEN1); tmp[len++] = 0; tmp[len++] = 0x16; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)tmp, len); } //***************************************************************************/ //* 转发全部组标题 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ BOOL ProvMakeTitleOfGroups(u_32 commid, RTUMSG *rtumsg, PROVDEVDEF *pProvDevParam, GROUPDEF *pBaoHuDB, int iNum) { i_32 i, len; RTUMSG msg; CLPDU_VARR *ptrClpdu_varr; memset((void *)&msg, 0, sizeof(RTUMSG)); ptrClpdu_varr = (CLPDU_VARR *)msg.MsgData; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; ptrClpdu_varr->nADDR = rtumsg->MsgData[5]; len = sizeof(CLPDU_VARR); msg.MsgData[len++] = M_GD_NTA_3; msg.MsgData[len++] = 0x81; msg.MsgData[len++] = M_CAUSE_READWITHVALIDDATA; msg.MsgData[len++] = rtumsg->MsgData[9]; msg.MsgData[len++] = FUNC_GENERALSORT; msg.MsgData[len++] = M_INF_READGROUPTITLE; msg.MsgData[len++] = rtumsg->MsgData[12];//RII msg.MsgData[len++] = (BYTE)iNum; for(i=0; inLEN1 = len - 4; ptrClpdu_varr->nLEN2 = len - 4; //msg.MsgData[len++] = CalBuban103Lpc(msg.MsgData+4, ptrClpdu_varr->nLEN1); msg.MsgData[len++] = 0; msg.MsgData[len++] = 0x16; msg.MsgLen = (WORD)len; msg.PortIdx = (BYTE)commid; return SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); } //***************************************************************************/ //* 转发一个组的全部条目的值或属性 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //* BOOL bContinue : 未传送的保护数据继续 */ //*返回值:无 */ //*备 注:所有组数据只能转发一帧 */ //***************************************************************************/ BOOL ProvMakeAttrOfAllItemInGroup(u_32 commid, RTUMSG *rtumsg,\ PROVDEVDEF *pProvDevParam,\ GROUPDEF *pBaoHuDB, int iNum) { BOOL bRetVal; i_32 i, ifixlen; RTUMSG msg; u_char *ptrPntNum; CLPDU_VARR *ptrClpdu_varr; i_32 iGroupNo, iPntNum, iNameLen; float *pfValue, fValue; memset((void *)&msg, 0, sizeof(RTUMSG)); ptrClpdu_varr = (CLPDU_VARR *)msg.MsgData; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; ptrClpdu_varr->nADDR = rtumsg->MsgData[5]; ifixlen = sizeof(CLPDU_VARR); // 组号 for(iGroupNo=0; iGroupNoMsgData[14]) { break; } } if(iGroupNo >= iNum) { return FALSE; } msg.MsgData[ifixlen++] = M_GD_NTA_3; msg.MsgData[ifixlen++] = 0x81; msg.MsgData[ifixlen++] = M_CAUSE_READWITHVALIDDATA; msg.MsgData[ifixlen++] = rtumsg->MsgData[9]; msg.MsgData[ifixlen++] = FUNC_GENERALSORT; msg.MsgData[ifixlen++] = M_INF_READGROUPALLITEMS; msg.MsgData[ifixlen++] = rtumsg->MsgData[12];//RII iPntNum = pBaoHuDB[iGroupNo].m_iPntNum; ptrPntNum = &msg.MsgData[ifixlen++]; msg.MsgLen = (WORD)ifixlen; bRetVal = TRUE; switch(rtumsg->MsgData[16]) { case KOD_ACTUALVALUE: // 实际值 for(i=0; iMsgData[14];// 组 号 msg.MsgData[msg.MsgLen++] = i+1; // 条目号 msg.MsgData[msg.MsgLen++] = KOD_ACTUALVALUE; // 实际值 msg.MsgData[msg.MsgLen++] = DATAID_FLOAT; // 浮点数 msg.MsgData[msg.MsgLen++] = sizeof(float); msg.MsgData[msg.MsgLen++] = 1; pfValue = (float*)(&msg.MsgData[msg.MsgLen]); fValue = pBaoHuDB[iGroupNo].m_psDataInfo[i].m_fValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; msg.MsgLen += sizeof(float); *ptrPntNum++; if(msg.MsgLen >= 240) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); msg.MsgLen = (WORD)ifixlen; *ptrPntNum = 0; } } if(msg.MsgLen > ifixlen) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); } break; case KOD_RANGE: // 量程(最大值、最小值、步长) for(i=0; iMsgData[14];// 组 号 msg.MsgData[msg.MsgLen++] = i+1; // 条目号 msg.MsgData[msg.MsgLen++] = KOD_RANGE; // 量程(最大值、最小值、步长) msg.MsgData[msg.MsgLen++] = DATAID_FLOAT; // 浮点数 msg.MsgData[msg.MsgLen++] = sizeof(float); msg.MsgData[msg.MsgLen++] = 3; pfValue = (float*)(&msg.MsgData[msg.MsgLen]); fValue = pBaoHuDB[iGroupNo].m_psDataInfo[i].m_fMaxValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; pfValue++; fValue = pBaoHuDB[iGroupNo].m_psDataInfo[i].m_fMinValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; pfValue++; fValue = pBaoHuDB[iGroupNo].m_psDataInfo[i].m_fStepValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; msg.MsgLen += 3*sizeof(float); *ptrPntNum++; if(msg.MsgLen >= 240) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); msg.MsgLen = (WORD)ifixlen; *ptrPntNum = 0; } } if(msg.MsgLen > ifixlen) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); } break; case KOD_DIMENSION: // 量 纲 for(i=0; iMsgData[14];// 组 号 msg.MsgData[msg.MsgLen++] = i+1; // 条目号 msg.MsgData[msg.MsgLen++] = KOD_DIMENSION; // 量 纲 msg.MsgData[msg.MsgLen++] = DATAID_OS8ASCII; iNameLen = strlen(pBaoHuDB[iGroupNo].m_psDataInfo[i].m_szUnit); msg.MsgData[msg.MsgLen++] = (BYTE)iNameLen; msg.MsgData[msg.MsgLen++] = 1; memcpy(&msg.MsgData[msg.MsgLen], pBaoHuDB[iGroupNo].m_psDataInfo[i].m_szUnit, iNameLen); msg.MsgLen += (WORD)iNameLen; *ptrPntNum++; if(msg.MsgLen >= 240) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); msg.MsgLen = (WORD)ifixlen; *ptrPntNum = 0; } } if(msg.MsgLen > ifixlen) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); } break; case KOD_DESCRIPTION: // 描 述 for(i=0; iMsgData[14];// 组 号 msg.MsgData[msg.MsgLen++] = i+1; // 条目号 msg.MsgData[msg.MsgLen++] = KOD_DIMENSION; // 量 纲 msg.MsgData[msg.MsgLen++] = DATAID_OS8ASCII; iNameLen = strlen(pBaoHuDB[iGroupNo].m_psDataInfo[i].m_szName); msg.MsgData[msg.MsgLen++] = (BYTE)iNameLen; msg.MsgData[msg.MsgLen++] = 1; memcpy(&msg.MsgData[msg.MsgLen], pBaoHuDB[iGroupNo].m_psDataInfo[i].m_szName, iNameLen); msg.MsgLen += (WORD)iNameLen; *ptrPntNum++; if(msg.MsgLen >= 220) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); msg.MsgLen = (WORD)ifixlen; *ptrPntNum = 0; } } if(msg.MsgLen > ifixlen) { ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;// lpc msg.MsgData[msg.MsgLen++] = 0x16; SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); } break; default: bRetVal = FALSE; break; } return bRetVal; } //***************************************************************************/ //* 转发一个条目的目录 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ BOOL ProvMakeDirOfItem(u_32 commid, RTUMSG *rtumsg, PROVDEVDEF *pProvDevParam, GROUPDEF *pBaoHuDB, int iNum) { RTUMSG msg; CLPDU_VARR *ptrClpdu_varr; i_32 iNameLen, iGroupNo, iItemNo; float *pfValue, fValue; // 条目号 iItemNo = rtumsg->MsgData[15]; for(iGroupNo=0; iGroupNoMsgData[14]) { break; } } if(iGroupNo >= iNum) { return FALSE; } if(iItemNo <= 0) { return FALSE; } if(iItemNo >= pBaoHuDB[iGroupNo].m_iPntNum) { return FALSE; } memset((void *)&msg, 0, sizeof(RTUMSG)); ptrClpdu_varr = (CLPDU_VARR *)msg.MsgData; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; ptrClpdu_varr->nADDR = rtumsg->MsgData[5]; msg.MsgLen = sizeof(CLPDU_VARR); msg.MsgData[msg.MsgLen++] = M_GD_NTA_3; msg.MsgData[msg.MsgLen++] = 0x81; msg.MsgData[msg.MsgLen++] = M_CAUSE_READWITHVALIDDATA; msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[9]; msg.MsgData[msg.MsgLen++] = FUNC_GENERALSORT; msg.MsgData[msg.MsgLen++] = M_INF_READDIROFSINGLEITEM; msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[12];//RII msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[14]; msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[15]; msg.MsgData[msg.MsgLen++] = 4; msg.MsgData[msg.MsgLen++] = KOD_ACTUALVALUE; // 实际值 msg.MsgData[msg.MsgLen++] = DATAID_FLOAT; // 浮点数 msg.MsgData[msg.MsgLen++] = sizeof(float); msg.MsgData[msg.MsgLen++] = 1; pfValue = (float*)(&msg.MsgData[msg.MsgLen]); fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; msg.MsgLen += sizeof(float); msg.MsgData[msg.MsgLen++] = KOD_RANGE; // 量程(最大值、最小值、步长) msg.MsgData[msg.MsgLen++] = DATAID_FLOAT; // 浮点数 msg.MsgData[msg.MsgLen++] = sizeof(float); msg.MsgData[msg.MsgLen++] = 3; pfValue = (float*)(&msg.MsgData[msg.MsgLen]); fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fMaxValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; pfValue++; fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fMinValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; pfValue++; fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fStepValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; msg.MsgLen += 3*sizeof(float); msg.MsgData[msg.MsgLen++] = KOD_DIMENSION; // 量 纲 msg.MsgData[msg.MsgLen++] = DATAID_OS8ASCII; iNameLen = strlen(pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szUnit); msg.MsgData[msg.MsgLen++] = (BYTE)iNameLen; msg.MsgData[msg.MsgLen++] = 1; memcpy(&msg.MsgData[msg.MsgLen], pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szUnit, iNameLen); msg.MsgLen += (WORD)iNameLen; msg.MsgData[msg.MsgLen++] = KOD_DESCRIPTION; // 描 述 msg.MsgData[msg.MsgLen++] = DATAID_OS8ASCII; iNameLen = strlen(pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szName); msg.MsgData[msg.MsgLen++] = (BYTE)iNameLen; msg.MsgData[msg.MsgLen++] = 1; memcpy(&msg.MsgData[msg.MsgLen], pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szName, iNameLen); msg.MsgLen += (WORD)iNameLen; ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;//lpc msg.MsgData[msg.MsgLen++] = 0x16; return SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); } //***************************************************************************/ //* 转发一个条目的值或属性 */ //*参数: u_32 commid : 厂站端口号 */ //* RTUMSG *rtumsg : 接收到的数据信息 */ //* i_32 iBuIdx : 保护装置(间隔)索引 */ //*返回值:无 */ //***************************************************************************/ BOOL ProvMakeAttrOfItem(u_32 commid, RTUMSG *rtumsg, PROVDEVDEF *pProvDevParam, GROUPDEF *pBaoHuDB, int iNum) { RTUMSG msg; CLPDU_VARR *ptrClpdu_varr; i_32 iNameLen, iGroupNo, iItemNo; float *pfValue, fValue; // 条目号 iItemNo = rtumsg->MsgData[15]; for(iGroupNo=0; iGroupNoMsgData[14]) { break; } } if(iGroupNo >= iNum) { return FALSE; } if(iItemNo <= 0) { return FALSE; } if(iItemNo >= pBaoHuDB[iGroupNo].m_iPntNum) { return FALSE; } memset((void *)&msg, 0, sizeof(RTUMSG)); ptrClpdu_varr = (CLPDU_VARR *)msg.MsgData; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; ptrClpdu_varr->nADDR = rtumsg->MsgData[5]; msg.MsgLen = sizeof(CLPDU_VARR); msg.MsgData[msg.MsgLen++] = M_GD_NTA_3; msg.MsgData[msg.MsgLen++] = 0x81; msg.MsgData[msg.MsgLen++] = M_CAUSE_READWITHVALIDDATA; msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[9]; msg.MsgData[msg.MsgLen++] = FUNC_GENERALSORT; msg.MsgData[msg.MsgLen++] = M_INF_READDIROFSINGLEITEM; msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[12];//RII msg.MsgData[msg.MsgLen++] = 1; msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[14]; msg.MsgData[msg.MsgLen++] = rtumsg->MsgData[15]; switch(rtumsg->MsgData[16]) { case KOD_ACTUALVALUE: // 实际值 msg.MsgData[msg.MsgLen++] = KOD_ACTUALVALUE; // 实际值 msg.MsgData[msg.MsgLen++] = DATAID_FLOAT; // 浮点数 msg.MsgData[msg.MsgLen++] = sizeof(float); msg.MsgData[msg.MsgLen++] = 1; pfValue = (float*)(&msg.MsgData[msg.MsgLen]); fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; msg.MsgLen += sizeof(float); break; case KOD_RANGE: // 量程(最大值、最小值、步长) msg.MsgData[msg.MsgLen++] = KOD_RANGE; // 量程(最大值、最小值、步长) msg.MsgData[msg.MsgLen++] = DATAID_FLOAT; // 浮点数 msg.MsgData[msg.MsgLen++] = sizeof(float); msg.MsgData[msg.MsgLen++] = 3; pfValue = (float*)(&msg.MsgData[msg.MsgLen]); fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fMaxValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; pfValue++; fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fMinValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; pfValue++; fValue = pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo-1].m_fStepValue; SequenceHostToRtu((char *)&fValue, sizeof(float)); *pfValue = fValue; msg.MsgLen += 3*sizeof(float); break; case KOD_DIMENSION: // 量 纲 msg.MsgData[msg.MsgLen++] = KOD_DIMENSION; // 量 纲 msg.MsgData[msg.MsgLen++] = DATAID_OS8ASCII; iNameLen = strlen(pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szUnit); msg.MsgData[msg.MsgLen++] = (BYTE)iNameLen; msg.MsgData[msg.MsgLen++] = 1; memcpy(&msg.MsgData[msg.MsgLen], pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szUnit, iNameLen); msg.MsgLen += (WORD)iNameLen; break; case KOD_DESCRIPTION: // 描 述 msg.MsgData[msg.MsgLen++] = KOD_DIMENSION; // 量 纲 msg.MsgData[msg.MsgLen++] = DATAID_OS8ASCII; iNameLen = strlen(pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szName); msg.MsgData[msg.MsgLen++] = (BYTE)iNameLen; msg.MsgData[msg.MsgLen++] = 1; memcpy(&msg.MsgData[msg.MsgLen], pBaoHuDB[iGroupNo].m_psDataInfo[iItemNo].m_szName, iNameLen); msg.MsgLen += (WORD)iNameLen; break; } ptrClpdu_varr->nLEN1 = msg.MsgLen - 4; ptrClpdu_varr->nLEN2 = msg.MsgLen - 4; msg.MsgLen++;//lpc msg.MsgData[msg.MsgLen++] = 0x16; return SingleListAddData(&pProvDevParam->m_sBaoHuData, msg.MsgData, msg.MsgLen); } BOOL ProvSendChangedDi(u_32 commid, DEVADDRPARAM *psDevAddrParam) { int i, j, iStart, len; WORD wValue; BOOL bQueryAllDev, bFind; DAY_TIME sCurTime; RTUMSG rtumsg; DI_DEF pntmsg; PROV_DI_PNT *diprovptr = NULL; CLPDU_VARR *ptrClpdu_varr = NULL; PROVDEVDEF *pProvDevParam = NULL; BUBAN103LINKDEF *pLinkParam = NULL; BUBAN103PORTPARAM *pPortParam = NULL; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; pLinkParam = &pPortParam->m_psLink[psDevAddrParam->m_iLinkIdx]; diprovptr = (PROV_DI_PNT*)pPortParam->m_psBaoHu->DiPtr; bFind = FALSE; if(pLinkParam->m_uchLinkAddr != 0xFF) { bQueryAllDev = TRUE; } else { bQueryAllDev = FALSE; } for(i=0; im_iDevNum; i++) { if(bQueryAllDev == TRUE) { psDevAddrParam->m_iDevIdx = i; } else { if(i >= 1) { break; } } pProvDevParam = &pLinkParam->m_psProvDev[psDevAddrParam->m_iDevIdx]; iStart = pProvDevParam->m_sYxInfo.m_iStartPntNo; for(j=0; jm_sYxInfo.m_iPntNum; j++) { if(TRUE == diprovptr[iStart+j].ChangeFlag) { bFind = TRUE; diprovptr[iStart+j].ChangeFlag = FALSE; GetPntMsg(diprovptr[iStart+j].PortNo, diprovptr[iStart+j].PntNo, (void *)&pntmsg, DI_PNT_TYPE, PNT_STATUS); break; } } if(TRUE == bFind) { break; } } if(bFind == TRUE) { GetLocalTimeEx(&sCurTime); ptrClpdu_varr = (CLPDU_VARR *)rtumsg.MsgData; ptrClpdu_varr->nSTART1 = 0x68; ptrClpdu_varr->nSTART2 = 0x68; // 重新赋值链路的转发地址 ptrClpdu_varr->nADDR = psDevAddrParam->m_uchLinkAddr; ptrClpdu_varr->nCONTROL &= 0xDF; // wen 2005.06.10 遥信变位只精确到秒 //wValue = sCurTime.Sec*1000 + sCurTime.mSec; wValue = sCurTime.Sec*1000; rtumsg.MsgData[sizeof(CLPDU_VARR)] = 0x01; // 四个八位二进制组 rtumsg.MsgData[sizeof(CLPDU_VARR)+7] = LOBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+8] = HIBYTE(wValue); rtumsg.MsgData[sizeof(CLPDU_VARR)+9] = sCurTime.Min & 0x3F; rtumsg.MsgData[sizeof(CLPDU_VARR)+10] = sCurTime.Hour & 0x1F; // SIN rtumsg.MsgData[sizeof(CLPDU_VARR)+11] = 0; len = 14; ptrClpdu_varr->nLEN1 = len; ptrClpdu_varr->nLEN2 = len; rtumsg.MsgData[sizeof(CLPDU_VARR)+1] = 0x81; //COT rtumsg.MsgData[sizeof(CLPDU_VARR)+2] = M_CAUSE_AUTOSEND; // 重新赋值 ASDU 公共地址 rtumsg.MsgData[sizeof(CLPDU_VARR)+3] = (BYTE)pProvDevParam->m_iProvAddr; // FUN rtumsg.MsgData[sizeof(CLPDU_VARR)+4] = pProvDevParam->m_sYxInfo.m_psDataInfo[j].m_u8ProvFun; // INF rtumsg.MsgData[sizeof(CLPDU_VARR)+5] = pProvDevParam->m_sYxInfo.m_psDataInfo[j].m_u8ProvInf; // DPI rtumsg.MsgData[sizeof(CLPDU_VARR)+6] = pntmsg.Status+1; len = ptrClpdu_varr->nLEN1 + 4; // 发送时会重新计算 //rtumsg.MsgData[len++] = CalBuban103Lpc(rtumsg.MsgData+4, ptrClpdu_varr->nLEN1); rtumsg.MsgData[len++] = 0; rtumsg.MsgData[len++] = 0x16; PutPollCmdToBuf(commid, FAST_POLL_CMD, 0, (char*)rtumsg.MsgData, len); } else { pPortParam->m_psBaoHu->DiChange = FALSE; } return bFind; } i_32 PackOneValueIntoPackage(BYTE *pbDestBuf, u_32 uMaxBufLen, BYTE bDataFormat, u_32 uDataType, u_32 uDataLen, BYTE *pbSourData) { i_32 iCount, k; float *ptrfValue, fValue; double *ptrdbValue; short *ptri16Value; i_32 *ptriValue; iCount = 0; // 数据类型 switch(bDataFormat) { case 0:// 模拟量 // pbSourData[0] // 数据源长度 fValue = *(float*)(pbSourData+1); // 数据长度 pbDestBuf[iCount++] = (BYTE)uDataLen; pbDestBuf[iCount++] = 1; // 数据长度(103中无用) //rtumsg->MsgData[uOffset++]; //ptrfValueSour = (float *)&rtumsg->MsgData[uOffset]; if(uDataType == DATAID_UI)// 无符号整数 { if(uDataLen == 1) { pbDestBuf[iCount] = (BYTE)((u_32)fabs(fValue)); } else if(uDataLen == 2) { ptri16Value = (short *)&pbDestBuf[iCount]; *ptri16Value = (short)fabs(fValue); SequenceHostToRtu((char *)ptri16Value, sizeof(short)); } else if(uDataLen == 4) { ptriValue = (i_32 *)&pbDestBuf[iCount]; *ptriValue = (i_32)fabs(fValue); SequenceHostToRtu((char *)ptriValue, sizeof(i_32)); } } // wen 2005.04.05 北京四方扩展数据类型 //else if(uDataType == DATAID_INT) else if((DATAID_INT == uDataType) || ( DATAID_EXDATA_0X24 == uDataType)) { if(uDataLen == 1) { pbDestBuf[iCount] = (BYTE)((i_32)fabs(fValue)); } else if(uDataLen == 2) { ptri16Value = (short *)&pbDestBuf[iCount]; *ptri16Value = (short)fabs(fValue); SequenceHostToRtu((char *)ptri16Value, sizeof(short)); } else if(uDataLen == 4) { ptriValue = (i_32 *)&pbDestBuf[iCount]; *ptriValue = (i_32)fabs(fValue); SequenceHostToRtu((char *)ptriValue, sizeof(i_32)); } } else if(uDataType == DATAID_UFLOAT)// 无符号浮点数 { ptrfValue = (float *)&pbDestBuf[iCount]; *ptrfValue = (float)fabs(fValue); SequenceHostToRtu((char *)ptrfValue, sizeof(float)); } else if(uDataType == DATAID_FLOAT)// 浮点数 { ptrfValue = (float *)&pbDestBuf[iCount]; *ptrfValue = fValue; SequenceHostToRtu((char *)ptrfValue, sizeof(float)); } else if(uDataType == DATAID_754SHORT)// R32.23 IEEE 标准754短实数 { ptrfValue = (float *)&pbDestBuf[iCount]; *ptrfValue = fValue; SequenceHostToRtu((char *)ptrfValue, sizeof(float)); } else if(uDataType == DATAID_754REAL)// R64.53 IEEE 标准754实数 { ptrdbValue = (double *)&pbDestBuf[iCount]; *ptrdbValue = fValue; SequenceHostToRtu((char *)ptrdbValue, sizeof(double)); } else if(uDataType == DATAID_13BITS) // 带品质描述的被测值(13BITS) { ptri16Value = (short *)&pbDestBuf[iCount]; *ptri16Value = ((short)(fValue)) & 0x1fff; SequenceHostToRtu((char *)ptri16Value, sizeof(short)); } // wen 2004.07.26 修改该类型数据的处理 else if(uDataType == DATAID_BSTRING) // 8位2进制码 { uDataLen = (uDataLen + 7) / 8; for(k=0; k<(int)uDataLen; k++); { pbDestBuf[iCount+k] = (BYTE)(((int)(fValue)) / 256); fValue /= 256; } } iCount += uDataLen; break; case 1:// 开关量 // pbSourData[0] // 数据源长度 fValue = *(float*)(pbSourData+1); // 数据长度 pbDestBuf[iCount++] = (BYTE)uDataLen; pbDestBuf[iCount++] = 1; if(uDataType == DATAID_UI)// 无符号整数 { if(uDataLen == 1) { pbDestBuf[iCount] = (BYTE)((u_32)fabs(fValue)); } else if(uDataLen == 2) { ptri16Value = (short *)&pbDestBuf[iCount]; *ptri16Value = (short)fabs(fValue); SequenceHostToRtu((char *)ptri16Value, sizeof(short)); } else if(uDataLen == 4) { ptriValue = (i_32 *)&pbDestBuf[iCount]; *ptriValue = (i_32)fabs(fValue); SequenceHostToRtu((char *)ptriValue, sizeof(i_32)); } } else if( uDataType == DATAID_INT) { if(uDataLen == 1) { pbDestBuf[iCount] = (BYTE)((i_32)fabs(fValue)); } else if(uDataLen == 2) { ptri16Value = (short *)&pbDestBuf[iCount]; *ptri16Value = (short)fabs(fValue); SequenceHostToRtu((char *)ptri16Value, sizeof(short)); } else if(uDataLen == 4) { ptriValue = (i_32 *)&pbDestBuf[iCount]; *ptriValue = (i_32)fabs(fValue); SequenceHostToRtu((char *)ptriValue, sizeof(i_32)); } } else if(uDataType == DATAID_UFLOAT)// 无符号浮点数 { ptrfValue = (float *)&pbDestBuf[iCount]; *ptrfValue = (float)fabs(fValue); SequenceHostToRtu((char *)ptrfValue, sizeof(float)); } else if(uDataType == DATAID_FLOAT)// 浮点数 { ptrfValue = (float *)&pbDestBuf[iCount]; *ptrfValue = fValue; SequenceHostToRtu((char *)ptrfValue, sizeof(float)); } else if(uDataType == DATAID_754SHORT)// R32.23 IEEE 标准754短实数 { ptrfValue = (float *)&pbDestBuf[iCount]; *ptrfValue = fValue; SequenceHostToRtu((char *)ptrfValue, sizeof(float)); } else if(uDataType == DATAID_754REAL)// R64.53 IEEE 标准754实数 { ptrdbValue = (double *)&pbDestBuf[iCount]; *ptrdbValue = fValue; SequenceHostToRtu((char *)ptrdbValue, sizeof(double)); } else if(uDataType == DATAID_13BITS) // 带品质描述的被测值(13BITS) { ptri16Value = (short *)&pbDestBuf[iCount]; *ptri16Value = ((short)(fValue)) &0x1fff; SequenceHostToRtu((char *)ptri16Value, sizeof(short)); } // wen 2004.07.26 修改该类型数据的处理 else if(uDataType == DATAID_BSTRING) // 8位2进制码 { uDataLen = (uDataLen + 7) / 8; for(k=0; k<(int)uDataLen; k++); { pbDestBuf[iCount+k] = (BYTE)(((int)(fValue)) / 256); fValue /= 256; } } else if(uDataType == DATAID_DOUBLE)// 双点信息 { pbDestBuf[iCount] = (BYTE)((u_32)(fabs(fValue)+1)); } else if(uDataType == DATAID_SINGLE)// 单点信息 { pbDestBuf[iCount] = (BYTE)((u_32)fabs(fValue)); } iCount += uDataLen; break; case 3:// 字符串 pbDestBuf[iCount++] = pbSourData[0]; pbDestBuf[iCount++] = 1; if(uDataType == DATAID_OS8ASCII)// 8位ASCII { memcpy((void *)(pbDestBuf+iCount), (void *)(pbSourData+1), pbSourData[0]); iCount += pbSourData[0]; } break; } return iCount; } // 部颁103和斯凯达内部规约间的格式转换 void Buban103ScadaCmdchange(int commid, RTUMSG *rtumsg) { u_32 uInterAction, uOffset, uDataLen, uDataType; u_char bFaultNo; i_32 i, j, k, iGroupNo, iStartNo, iCPUNo, offset; BOOL bIsValidCmd; GEN_DATAGROUP sGenDataGroup; PROTECTCONTENTHEAD *ptrProHead; BYTE bSourData[4096]; i_32 iFixDataNGD; CMDPARAM sCmdParam; PROTECTMSG PrtMsg; int iProvAddr, iYkNo; DEVDEF *pDevParam; DEVADDRPARAM sAddrParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; char szbuf[256]; memcpy((void *)&PrtMsg, rtumsg->MsgData, rtumsg->MsgLen); ptrProHead = (PROTECTCONTENTHEAD *)PrtMsg.MsgData; if(FALSE == GetPortParamPtr(commid, &pPortParam)) { return; } iProvAddr = ptrProHead->uAddr; sprintf(szbuf, "地址=%d ", ptrProHead->uAddr); DebugPrint(szbuf); if(FALSE == FindProtectDevFromProvAddr(pPortParam, &sAddrParam, iProvAddr)) { sprintf(szbuf, "地址错误 "); DebugPrint(szbuf); return; } // wen 2005.06.06 增加数据返回时的上下文存储 pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_iBaoHuCommid = rtumsg->PortIdx; memcpy((void *)&pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_sRealAddrParam, (void *)&sAddrParam, sizeof(DEVADDRPARAM)); GetLocalTimeEx(&pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_sBaoHuCmdStartTime); pPortParam->m_psLink[sAddrParam.m_iLinkIdx].m_sBaoHuCmdParam.m_iBaoHuMsgType = MSGTYPE_BAOHU_SCADACMD; bIsValidCmd = TRUE; uOffset = sizeof(PROTECTCONTENTHEAD); pLinkParam = &pPortParam->m_psLink[sAddrParam.m_iLinkIdx]; pDevParam = &pLinkParam->m_psDev[sAddrParam.m_iDevIdx]; // CPU号与分组号一一对应 if((ptrProHead->cCPUNo != (char)0xFF) && (ptrProHead->cCPUNo != 0)) { pDevParam->m_sDevParam.m_u8CPUNo = ptrProHead->cCPUNo; } if((ptrProHead->cFixNo != (char)0xFF) && (ptrProHead->cFixNo != 0)) { pDevParam->m_sDevParam.m_u8FixNo = ptrProHead->cFixNo; } iCPUNo = 1; // 保护指令记忆 if(ptrProHead->uAddr != 0xff) { pDevParam->m_sDevParam.m_u32FuncCode = ptrProHead->uFuncCode; } memcpy((void *)&sCmdParam.m_sDevAddr, (void *)&sAddrParam, sizeof(DEVADDRPARAM)); switch(ptrProHead->uFuncCode) { case hREADFIX:// 读取定值(只存在一个保护定值组的情况) uInterAction = hREADINGDATA; for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(PROTECT_FIX_PNT_TYPE == pDevParam->m_sDevParam.m_saGroupDef[i].m_iDataType) { sprintf(szbuf, "第%d组CPU号= %d!!!\n", i+1, pDevParam->m_sDevParam.m_u8CPUNo); DebugPrint(szbuf); if(pDevParam->m_sDevParam.m_u8CPUNo == iCPUNo) { break; } else { iCPUNo++; } } } if(i == pDevParam->m_sDevParam.m_iCfgGroupNum) { bIsValidCmd = FALSE; sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d不存在保护定值!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr); DebugPrint(szbuf); break; } pDevParam->m_sDevParam.m_saGroupDef[i].m_u32CurPntNo = 1; sCmdParam.m_uchInf = C_INF_READGROUPALLITEMS; sGenDataGroup.m_u8Grp = (BYTE)pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo; sGenDataGroup.m_u8Itm = 0; sGenDataGroup.m_u8KOD = PrtMsg.MsgData[uOffset]; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentCommand_CAsdu21(commid, &sCmdParam, &sGenDataGroup, 1); break; case hREADFIXNO:// 读取定值区号 uInterAction = hREADINGDATA; bIsValidCmd = FALSE; break; case hREADPAI:// 读取保护模拟量 uInterAction = hREADINGDATA; for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(PROTECT_AI_PNT_TYPE == pDevParam->m_sDevParam.m_saGroupDef[i].m_iDataType) { break; } } if(i == pDevParam->m_sDevParam.m_iCfgGroupNum) { bIsValidCmd = FALSE; #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d不存在保护模拟量!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif break; } pDevParam->m_sDevParam.m_saGroupDef[i].m_u32CurPntNo = 1; sCmdParam.m_uchInf = C_INF_READGROUPALLITEMS; sGenDataGroup.m_u8Grp = (BYTE)pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo; sGenDataGroup.m_u8Itm = 0; sGenDataGroup.m_u8KOD = PrtMsg.MsgData[uOffset]; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentCommand_CAsdu21(commid, &sCmdParam, &sGenDataGroup, 1); break; case hREADPDI:// 读取保护开关量 uInterAction = hREADINGDATA; for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(PROTECT_DI_PNT_TYPE == pDevParam->m_sDevParam.m_saGroupDef[i].m_iDataType) { break; } } if(i == pDevParam->m_sDevParam.m_iCfgGroupNum) { bIsValidCmd = FALSE; #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d不存在保护开关量!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif break; } pDevParam->m_sDevParam.m_saGroupDef[i].m_u32CurPntNo = 1; sCmdParam.m_uchInf = C_INF_READGROUPALLITEMS; sGenDataGroup.m_u8Grp = (BYTE)pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo; sGenDataGroup.m_u8Itm = 0; sGenDataGroup.m_u8KOD = PrtMsg.MsgData[uOffset]; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentCommand_CAsdu21(commid, &sCmdParam, &sGenDataGroup, 1); break; case hREADPWAVE:// 读取保护波形数据 case hQUERYFAULT:// 读取指定故障报告 bFaultNo = rtumsg->MsgData[sizeof(PROTECTCONTENTHEAD)]; uInterAction = hREADINGDATA; bIsValidCmd = FALSE; break; case hQUERYSELFCHECK:// 读取指定的自检报告 bFaultNo = rtumsg->MsgData[sizeof(PROTECTCONTENTHEAD)]; uInterAction = hREADINGDATA; bIsValidCmd = FALSE; break; case hWRITEALLFIX:// 修改保护定值 uInterAction = hREADINGDATA; //uOffset += 12; pDevParam->m_u32CallCnt = pLinkParam->m_u32TimeOutConst; for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(PROTECT_FIX_PNT_TYPE == pDevParam->m_sDevParam.m_saGroupDef[i].m_iDataType) { if(pDevParam->m_sDevParam.m_u8CPUNo == iCPUNo) { break; } else { iCPUNo++; } } } if(i == pDevParam->m_sDevParam.m_iCfgGroupNum) { bIsValidCmd = FALSE; #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d不存在保护定值!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif break; } iGroupNo = pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo; iStartNo = *((int *)&PrtMsg.MsgData[uOffset]); sprintf(szbuf, "修改定值组帧开始 组号=%d, 起始点号=%d, uoffset=%d 接收数据:\n",iGroupNo, iStartNo, uOffset); DebugPrint(szbuf); for(k=0; kMsgLen; k+=6) { sprintf(szbuf, "%2X %2X %2X %2X %2X %2X",rtumsg->MsgData[k],rtumsg->MsgData[k+1],rtumsg->MsgData[k+2],rtumsg->MsgData[k+3],rtumsg->MsgData[k+4],rtumsg->MsgData[k+5]); DebugPrint(szbuf); } // wen 2004.02.02 当前数据处理时的起始点号 pDevParam->m_sDevParam.m_saGroupDef[i].m_u32CurPntNo = 1; if(pDevParam->m_sDevParam.m_saGroupDef[i].m_bInit == FALSE) { bIsValidCmd = FALSE; #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 组号%d 未先读取定值!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr, iGroupNo); DebugPrint(szbuf); #endif break; } uOffset += 4; offset = 0; for(j=0, iFixDataNGD=0; (uOffsetMsgLen) && (jm_sDevParam.m_saGroupDef[i].m_iPntNum); j++, iFixDataNGD++) { // wen 2004.02.02 如果一帧数据无法全部完成写定值工作,则分成多帧来完成 if(offset >= 200) { sCmdParam.m_uchInf = C_INF_WRITEITEMWITHACK; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentData_CAsdu10(commid, &sCmdParam, bSourData, (BYTE)iFixDataNGD); offset = 0; iFixDataNGD = 0; } // wen 2004.01.07 每一个数据都有索引 bSourData[offset++] = (BYTE)iGroupNo; // wen 2004.02.02 用存储的条目号 //bSourData[offset++] = (BYTE)(iStartNo-1+j); bSourData[offset++] = pDevParam->m_sDevParam.m_saGroupDef[i].m_pu8GIN[iStartNo-1+j]; bSourData[offset++] = 1; uDataType = pDevParam->m_sDevParam.m_saGroupDef[i].m_pu8DataType[iStartNo-1+j]; uDataLen = pDevParam->m_sDevParam.m_saGroupDef[i].m_pu8DataLen[iStartNo-1+j]; bSourData[offset++] = (BYTE)uDataType; // 不能处理字符串 offset += PackOneValueIntoPackage(bSourData+offset, sizeof(bSourData)-offset, PrtMsg.MsgData[uOffset], uDataType, uDataLen, &PrtMsg.MsgData[uOffset+1]); sprintf(szbuf, "第%d点定值的组号=%d,条目号=%d,数据类型=%d,数据宽度=%d,值=%d; %02X %02X %02X %02X",iStartNo-1+j,\ iGroupNo,pDevParam->m_sDevParam.m_saGroupDef[i].m_pu8GIN[iStartNo-1+j],\ uDataType, uDataLen, *(float*)(&PrtMsg.MsgData[uOffset+1+1]), PrtMsg.MsgData[uOffset+2], PrtMsg.MsgData[uOffset+3], PrtMsg.MsgData[uOffset+4], PrtMsg.MsgData[uOffset+5]); DebugPrint(szbuf); uOffset += sizeof(float)+2; } if(iFixDataNGD > 0) { sCmdParam.m_uchInf = C_INF_WRITEITEMWITHACK; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentData_CAsdu10(commid, &sCmdParam, bSourData, (BYTE)iFixDataNGD); } break; case hWRITEFIXNO:// 修改保护定值区 uInterAction = hREADINGDATA; pDevParam->m_u32CallCnt = pLinkParam->m_u32TimeOutConst; bIsValidCmd = FALSE; break; case hRESETPROTECT:// 保护信号复归 //Param.bCmdIdx = APPLY_REVERT; uInterAction = hREADDATAEND; if(pDevParam->m_sDevParam.m_sYkDBOrientation.m_iPntNum <= 0) { bIsValidCmd = FALSE; break; } else { bIsValidCmd = TRUE; } iYkNo = pDevParam->m_sDevParam.m_sYkDBOrientation.m_iStartPntNo; bSourData[0] = (BYTE)(commid & 0xFF); bSourData[1] = (BYTE)((commid & 0xFF00) << 8); bSourData[2] = (BYTE)((commid & 0xFF0000) << 16); bSourData[3] = (BYTE)((commid & 0xFF000000) << 24); bSourData[4] = (BYTE)(iYkNo & 0xFF); bSourData[5] = (BYTE)((iYkNo & 0xFF00) << 8); bSourData[6] = (BYTE)((iYkNo & 0xFF0000) << 16); bSourData[7] = (BYTE)((iYkNo & 0xFF000000) << 24); bSourData[8] = STEP_YKYT_EXEC; bSourData[9] = 1; Buban103YkYtProcess(commid, bSourData, 10); break; case hCHECKTIME:// 单个装置对时 //Param.bCmdIdx = CHECK_TIME; uInterAction = hREADINGDATA; MakeTimeSyn_CAsdu6(commid, &sCmdParam); break; case hBROADCASTCHECKTIME:// 保护装置广播对时 uInterAction = hREADDATAEND; sCmdParam.m_sDevAddr.m_uchLinkAddr = 0xFF; MakeTimeSyn_CAsdu6(commid, &sCmdParam); break; case hWRITEFIXACK: // 修改保护定值确认 sCmdParam.m_uchInf = C_INF_WRITEITEMWITHEXEC; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentData_CAsdu10(commid, &sCmdParam, NULL, 0); uInterAction = hREADDATAEND; break; case hWRITEFIXNAK: // 修改保护定值不确认 sCmdParam.m_uchInf = C_INF_STOPWRITEITEM; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentData_CAsdu10(commid, &sCmdParam, NULL, 0); uInterAction = hREADDATAEND; break; // wen 2004.09.29 case hWRITESPECIALFIX:// 修改指定的保护定值 uInterAction = hREADINGDATA; pDevParam->m_u32CallCnt = pLinkParam->m_u32TimeOutConst; for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(PROTECT_FIX_PNT_TYPE == pDevParam->m_sDevParam.m_saGroupDef[i].m_iDataType) { if(pDevParam->m_sDevParam.m_u8CPUNo == iCPUNo) { break; } else { iCPUNo++; } } } if(i == pDevParam->m_sDevParam.m_iCfgGroupNum) { bIsValidCmd = FALSE; #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d不存在保护定值!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif break; } iGroupNo = pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo; iStartNo = *((int *)&PrtMsg.MsgData[uOffset]); pDevParam->m_sDevParam.m_saGroupDef[i].m_u32CurPntNo = iStartNo; if(pDevParam->m_sDevParam.m_saGroupDef[i].m_bInit == FALSE) { bIsValidCmd = FALSE; #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 组号%d 未先读取定值!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr, iGroupNo); DebugPrint(szbuf); #endif break; } uOffset += 4; offset = 0; // wen 2004.01.07 每一个数据都有索引 bSourData[offset++] = (BYTE)iGroupNo; // wen 2004.02.02 用存储的条目号 bSourData[offset++] = pDevParam->m_sDevParam.m_saGroupDef[i].m_pu8GIN[iStartNo-1]; bSourData[offset++] = 1; uDataType = pDevParam->m_sDevParam.m_saGroupDef[i].m_pu8DataType[iStartNo-1]; uDataLen = pDevParam->m_sDevParam.m_saGroupDef[i].m_pu8DataLen[iStartNo-1]; bSourData[offset++] = (BYTE)uDataType; // 不能处理字符串 offset += PackOneValueIntoPackage(bSourData+offset, sizeof(bSourData)-offset, PrtMsg.MsgData[uOffset], uDataType, uDataLen, &PrtMsg.MsgData[uOffset+1]); uOffset += sizeof(float)+2; sCmdParam.m_uchInf = C_INF_WRITEITEMWITHACK; sCmdParam.m_uchRII = RII_PROV_ID; MakeGenIdentData_CAsdu10(commid, &sCmdParam, bSourData, 1); break; default: bIsValidCmd = FALSE; break; } // 保护地址不合法或者指令不合法时或者查询指令错误, 直接退出 if( !bIsValidCmd ) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d指令不可识别!!!\n", commid, sAddrParam.m_uchLinkAddr, sAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif MakeInteractionCmd(pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid, commid, hREADDATAEND, ptrProHead, FALSE); } else { MakeInteractionCmd(pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid, commid, uInterAction, ptrProHead, FALSE); } } void Buban103GDprocessWithPAIToScada(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid, iItemNum; BYTE u8KOD, u8INF, u8DataType; BYTE u8DataNum, u8DataLen, u8ItemNo; u_32 *puStartNo; int iOffset, offset; double fValue; float *pfValue; BOOL bFirst, bNumChanged; PROTECTCONTENTHEAD *ptrProHead; RTUMSG sendmsg; PROTECTMSG msg; VALUEDEF sValue; GROUPDEF *pGroupParam; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } bNumChanged = FALSE; bFirst = TRUE; iOffset = 14; pGroupParam = &pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx]; if(pGroupParam->m_iPntNum <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据空间为零!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } if((iOffset+3) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } u8INF = rtumsg->MsgData[11]; u8KOD = rtumsg->MsgData[16]; pGroupParam->m_u8NGD = rtumsg->MsgData[13]; memset((void *)&msg, 0, sizeof(PROTECTMSG)); msg.MsgType = fPFV_PROTECT_BYPASS_ACK; msg.PortNumber = commid; // 操作用户 ptrProHead = (pPROTECTCONTENTHEAD)msg.MsgData; ptrProHead->ummid = 0xFFFFFFFF; ptrProHead->uAddr = pDevParam->m_sDevParam.m_iProvAddr; // 定值区号(不需要时,填写0xFF) ptrProHead->cFixNo = (char)pDevParam->m_sDevParam.m_u8FixNo; // C P U 号(不需要时,填写0xFF) ptrProHead->cCPUNo = (char)pDevParam->m_sDevParam.m_u8CPUNo; // 操作类型 ptrProHead->uFuncCode = hPAIDATA; // 扩展保留 offset = sizeof(PROTECTCONTENTHEAD); // 实际条目类型 msg.MsgData[offset++] = u8KOD; // 起始序号 puStartNo = (u_32*)&msg.MsgData[offset]; offset += sizeof(u_32); iItemNum = pGroupParam->m_u8NGD & 0x3F; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 组 号 // 条目号 u8ItemNo = rtumsg->MsgData[iOffset+1]; iOffset += 2; if(TRUE == bFirst) { if(u8ItemNo == 0) { pGroupParam->m_u32CurPntNo = 1; } else if(u8ItemNo <= pGroupParam->m_iStartItemNo) { pGroupParam->m_u32CurPntNo = 1; } if((M_INF_WRITEITEMWITHACK == u8INF) && (pGroupParam->m_bInit == FALSE)) { for(j=0; jm_iPntNum; j++) { if(pGroupParam->m_pu8GIN[j] == u8ItemNo) { break; } } if(j >= pGroupParam->m_iPntNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,不匹配的GIN=%d!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8ItemNo, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } pGroupParam->m_u32CurPntNo = j+1; } *puStartNo = pGroupParam->m_u32CurPntNo; bFirst = FALSE; } if(u8KOD != rtumsg->MsgData[iOffset]) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,数据KOD=%d与要求的KOD=%d不符!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo, rtumsg->MsgData[iOffset], u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 4; continue; } else { iOffset++; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; j<(int)u8DataNum; j++) { // wen 2004.02.01 如果条目号为0,则该条目为该组条目数量,不上送 if((u8ItemNo == 0) && (j == 0)) { iOffset += u8DataLen; continue; } if((int)pGroupParam->m_u32CurPntNo > pGroupParam->m_iPntNum) { break; } if(pGroupParam->m_bInit == FALSE) { //pGroupParam->m_pu8DataLen[pGroupParam->m_u32CurPntNo-1] = u8DataLen; //pGroupParam->m_pu8DataType[pGroupParam->m_u32CurPntNo-1] = u8DataType; pGroupParam->m_pu8GIN[pGroupParam->m_u32CurPntNo-1] = u8ItemNo+j; } if(GetOneValueOfASDU10(&rtumsg->MsgData[iOffset], &sValue, u8DataType, u8DataLen) == FALSE) { iOffset += u8DataLen; continue; } iOffset += u8DataLen; switch(sValue.m_iDataType) { case DT_UINT:// 无符号整型数 fValue = sValue.m_unValue.m_uValue; break; case DT_INT: fValue = sValue.m_unValue.m_iValue; break; case DT_FLOAT: fValue = sValue.m_unValue.m_fValue; break; case DT_CONTROL: fValue = sValue.m_unValue.m_dwValue; break; case DT_STRING: fValue = -1; break; case DT_BINARY: fValue = sValue.m_unValue.m_dwValue; break; case DT_NO:// 无数据 default: fValue = -1; break; } if(pGroupParam->m_bInit == FALSE) { if((u8ItemNo == 0) && (j == 0)) { if((fValue > 0) && (KOD_ACTUALVALUE == u8KOD)) { if((int)fValue > pGroupParam->m_iPntNum) { //pGroupParam->m_iPntNum = (int)sValue.m_unValue.m_uValue; bNumChanged = TRUE; } else { pGroupParam->m_iPntNum = (int)fValue; } } } } if(TRUE == bNumChanged) { //freeallfixmemory } if(DT_STRING != sValue.m_iDataType) { pfValue = (float *)&msg.MsgData[offset]; *pfValue = (float)fValue; offset += sizeof(float); } if(pGroupParam->m_bInit == FALSE) { pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].m_u32DataID = u8DataType; } pGroupParam->m_u32CurPntNo++; } } if(pGroupParam->m_iPntNum > 0) { if((int)pGroupParam->m_u32CurPntNo >= pGroupParam->m_iPntNum) { pGroupParam->m_bInit = TRUE; pGroupParam->m_u32CurPntNo = 1; } } msg.MsgLen = offset; sendmsg.MsgLen = (WORD)(msg.MsgLen+sizeof(PROTECTMSGHEAD)); sendmsg.MsgType = MSGTYPE_BAOHU_SCADADATA; sendmsg.PortIdx = pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid; memcpy(sendmsg.MsgData, (BYTE *)&msg, sendmsg.MsgLen); PutBaohuDataToPort(&sendmsg); if(pDevParam->m_sDevParam.m_u32FuncCode == hREADPAI) { if(TRUE == pGroupParam->m_bInit) { MakeInteractionCmd(pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid, commid, hREADDATAEND, ptrProHead, FALSE); pDevParam->m_sDevParam.m_u32FuncCode = 0; } } } void Buban103GDprocessWithPDIToScada(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid, iItemNum; BYTE u8KOD, u8INF, u8DataType; BYTE u8DataNum, u8DataLen, u8ItemNo; u_32 *puStartNo; int iOffset, offset; double fValue; BOOL bFirst, bNumChanged; PROTECTCONTENTHEAD *ptrProHead; RTUMSG sendmsg; PROTECTMSG msg; VALUEDEF sValue; GROUPDEF *pGroupParam; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } bNumChanged = FALSE; bFirst = TRUE; iOffset = 14; pGroupParam = &pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx]; if(pGroupParam->m_iPntNum <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据空间为零!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } if((iOffset+3) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } u8INF = rtumsg->MsgData[11]; u8KOD = rtumsg->MsgData[16]; pGroupParam->m_u8NGD = rtumsg->MsgData[13]; memset((void *)&msg, 0, sizeof(PROTECTMSG)); msg.MsgType = fPFV_PROTECT_BYPASS_ACK; msg.PortNumber = commid; // 操作用户 ptrProHead = (pPROTECTCONTENTHEAD)msg.MsgData; ptrProHead->ummid = 0xFFFFFFFF; ptrProHead->uAddr = pDevParam->m_sDevParam.m_iProvAddr; // 定值区号(不需要时,填写0xFF) ptrProHead->cFixNo = (char)pDevParam->m_sDevParam.m_u8FixNo; // C P U 号(不需要时,填写0xFF) ptrProHead->cCPUNo = (char)pDevParam->m_sDevParam.m_u8CPUNo; // 操作类型 ptrProHead->uFuncCode = hPDIDATA; // 扩展保留 offset = sizeof(PROTECTCONTENTHEAD); // 实际条目类型 msg.MsgData[offset++] = u8KOD; // 起始序号 puStartNo = (u_32*)&msg.MsgData[offset]; offset += sizeof(u_32); iItemNum = pGroupParam->m_u8NGD & 0x3F; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 组 号 // 条目号 u8ItemNo = rtumsg->MsgData[iOffset+1]; iOffset += 2; if(TRUE == bFirst) { if(u8ItemNo == 0) { pGroupParam->m_u32CurPntNo = 1; } else if(u8ItemNo <= pGroupParam->m_iStartItemNo) { pGroupParam->m_u32CurPntNo = 1; } if((M_INF_WRITEITEMWITHACK == u8INF) && (pGroupParam->m_bInit == FALSE)) { for(j=0; jm_iPntNum; j++) { if(pGroupParam->m_pu8GIN[j] == u8ItemNo) { break; } } if(j >= pGroupParam->m_iPntNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,不匹配的GIN=%d!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8ItemNo, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } pGroupParam->m_u32CurPntNo = j+1; } *puStartNo = pGroupParam->m_u32CurPntNo; bFirst = FALSE; } if(u8KOD != rtumsg->MsgData[iOffset]) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,数据KOD=%d与要求的KOD=%d不符!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo, rtumsg->MsgData[iOffset], u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 4; continue; } else { iOffset++; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; j<(int)u8DataNum; j++) { // wen 2004.02.01 如果条目号为0,则该条目为该组条目数量,不上送 if((u8ItemNo == 0) && (j == 0)) { iOffset += u8DataLen; continue; } if((int)pGroupParam->m_u32CurPntNo > pGroupParam->m_iPntNum) { break; } if(pGroupParam->m_bInit == FALSE) { //pGroupParam->m_pu8DataLen[pGroupParam->m_u32CurPntNo-1] = u8DataLen; //pGroupParam->m_pu8DataType[pGroupParam->m_u32CurPntNo-1] = u8DataType; pGroupParam->m_pu8GIN[pGroupParam->m_u32CurPntNo-1] = u8ItemNo+j; } if(GetOneValueOfASDU10(&rtumsg->MsgData[iOffset], &sValue, u8DataType, u8DataLen) == FALSE) { iOffset += u8DataLen; continue; } iOffset += u8DataLen; switch(sValue.m_iDataType) { case DT_UINT:// 无符号整型数 fValue = sValue.m_unValue.m_uValue; break; case DT_INT: fValue = sValue.m_unValue.m_iValue; break; case DT_FLOAT: fValue = sValue.m_unValue.m_fValue; break; case DT_CONTROL: fValue = sValue.m_unValue.m_dwValue; break; case DT_STRING: fValue = -1; break; case DT_BINARY: fValue = sValue.m_unValue.m_dwValue; break; case DT_NO:// 无数据 default: fValue = -1; break; } /* if(pGroupParam->m_bInit == FALSE) { if((u8ItemNo == 0) && (j == 0)) { if((fValue > 0) && (KOD_ACTUALVALUE == u8KOD)) { if((int)fValue > pGroupParam->m_iPntNum) { //pGroupParam->m_iPntNum = (int)sValue.m_unValue.m_uValue; bNumChanged = TRUE; } else { pGroupParam->m_iPntNum = (int)fValue; } } } } if(TRUE == bNumChanged) { //freeallfixmemory } */ if(DT_BINARY == sValue.m_iDataType) { if(2 == sValue.m_iDataNum) { if((fValue < 1) || (fValue > 2)) { fValue = 0; } else { fValue -= 1; } } } if(fValue > 0) { msg.MsgData[offset++] = TRUE; } else { msg.MsgData[offset++] = FALSE; } if(pGroupParam->m_bInit == FALSE) { pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].m_u32DataID = u8DataType; } pGroupParam->m_u32CurPntNo++; } } if(pGroupParam->m_iPntNum > 0) { if((int)pGroupParam->m_u32CurPntNo >= pGroupParam->m_iPntNum) { pGroupParam->m_bInit = TRUE; pGroupParam->m_u32CurPntNo = 1; } } msg.MsgLen = offset; sendmsg.MsgLen = (WORD)(msg.MsgLen+sizeof(PROTECTMSGHEAD)); sendmsg.MsgType = MSGTYPE_BAOHU_SCADADATA; sendmsg.PortIdx = pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid; memcpy(sendmsg.MsgData, (BYTE *)&msg, sendmsg.MsgLen); PutBaohuDataToPort(&sendmsg); if(pDevParam->m_sDevParam.m_u32FuncCode == hREADPDI) { if(TRUE == pGroupParam->m_bInit) { MakeInteractionCmd(pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid, commid, hREADDATAEND, ptrProHead, FALSE); pDevParam->m_sDevParam.m_u32FuncCode = 0; } } } void Buban103GDprocessWithPFIXToScada(RTUMSG *rtumsg, DEVADDRPARAM *psDevAddrParam, i_32 iGroupIdx) { int i, j, commid, iItemNum; BYTE u8KOD, u8INF, u8DataType; BYTE u8DataNum, u8DataLen, u8ItemNo; u_32 *puStartNo; int iOffset, offset; double fValue; float *pfValue; BOOL bFirst, bNumChanged; PROTECTCONTENTHEAD *ptrProHead; RTUMSG sendmsg; PROTECTMSG msg; VALUEDEF sValue; GROUPDEF *pGroupParam; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; //#ifdef _DEBUG_MSG_ char szbuf[256]; //#endif sprintf(szbuf, "Buban103GDprocessWithPFIXToScada"); DebugPrint(szbuf); commid = rtumsg->PortIdx; if(FALSE == GetSpecialPtr(commid, psDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } bNumChanged = FALSE; bFirst = TRUE; iOffset = 14; pGroupParam = &pDevParam->m_sDevParam.m_saGroupDef[iGroupIdx]; if(pGroupParam->m_iPntNum <= 0) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据空间为零!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } if((iOffset+3) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时, 数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } u8INF = rtumsg->MsgData[11]; u8KOD = rtumsg->MsgData[16]; pGroupParam->m_u8NGD = rtumsg->MsgData[13]; if((0xf9 == u8INF) && (rtumsg->MsgData[8] == 0x29)) { sprintf(szbuf, "Buban103GDprocessWithPFIXToScada写定值确认失败"); DebugPrint(szbuf); } if((0xf9 == u8INF) && (rtumsg->MsgData[8] == 0x2c)) { sprintf(szbuf, "Buban103GDprocessWithPFIXToScada写定值确认成功"); DebugPrint(szbuf); } if((0xfa == u8INF) && (rtumsg->MsgData[8] == 0x28)) { sprintf(szbuf, "Buban103GDprocessWithPFIXToScada写定值执行成功"); DebugPrint(szbuf); } if((0xfa == u8INF) && (rtumsg->MsgData[8] == 0x29)) { sprintf(szbuf, "Buban103GDprocessWithPFIXToScada写定值执行失败"); DebugPrint(szbuf); } if((0xfb == u8INF) && (rtumsg->MsgData[8] == 0x28)) { sprintf(szbuf, "Buban103GDprocessWithPFIXToScada写定值终止执行成功"); DebugPrint(szbuf); } memset((void *)&msg, 0, sizeof(PROTECTMSG)); msg.MsgType = fPFV_PROTECT_BYPASS_ACK; msg.PortNumber = commid; // 操作用户 ptrProHead = (pPROTECTCONTENTHEAD)msg.MsgData; ptrProHead->ummid = 0xFFFFFFFF; ptrProHead->uAddr = pDevParam->m_sDevParam.m_iProvAddr; // 定值区号(不需要时,填写0xFF) ptrProHead->cFixNo = (char)pDevParam->m_sDevParam.m_u8FixNo; // C P U 号(不需要时,填写0xFF) ptrProHead->cCPUNo = (char)pDevParam->m_sDevParam.m_u8CPUNo; // 操作类型 ptrProHead->uFuncCode = hFIXDATA; // 扩展保留 offset = sizeof(PROTECTCONTENTHEAD); // 实际条目类型 msg.MsgData[offset++] = u8KOD; // 起始序号 puStartNo = (u_32*)&msg.MsgData[offset]; offset += sizeof(u_32); iItemNum = pGroupParam->m_u8NGD & 0x3F; for(i=0; i= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 数据长度(单个数据长*数量) u8DataNum = rtumsg->MsgData[iOffset+5]; u8DataLen = rtumsg->MsgData[iOffset+4]; if((iOffset+6+u8DataLen*u8DataNum) >= rtumsg->MsgLen) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)处理时,数据帧长度不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif break; } // 组 号 // 条目号 u8ItemNo = rtumsg->MsgData[iOffset+1]; iOffset += 2; if(TRUE == bFirst) { if(u8ItemNo == 0) { pGroupParam->m_u32CurPntNo = 1; } else if(u8ItemNo <= pGroupParam->m_iStartItemNo) { pGroupParam->m_u32CurPntNo = 1; } if((M_INF_WRITEITEMWITHACK == u8INF) && (pGroupParam->m_bInit == FALSE)) { for(j=0; jm_iPntNum; j++) { if(pGroupParam->m_pu8GIN[j] == u8ItemNo) { break; } } if(j >= pGroupParam->m_iPntNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,不匹配的GIN=%d!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, u8ItemNo, pGroupParam->m_iGroupNo); DebugPrint(szbuf); #endif return; } pGroupParam->m_u32CurPntNo = j+1; } *puStartNo = pGroupParam->m_u32CurPntNo; bFirst = FALSE; } if(u8KOD != rtumsg->MsgData[iOffset]) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10(Group=%d)写确认处理时,数据KOD=%d与要求的KOD=%d不符!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pGroupParam->m_iGroupNo, rtumsg->MsgData[iOffset], u8KOD); DebugPrint(szbuf); #endif iOffset += u8DataLen*u8DataNum + 4; continue; } else { iOffset++; } u8DataType = rtumsg->MsgData[iOffset++]; iOffset += 2; for(j=0; j<(int)u8DataNum; j++) { // wen 2004.02.01 如果条目号为0,则该条目为该组条目数量,不上送 if((u8ItemNo == 0) && (j == 0)) { iOffset += u8DataLen; continue; } if((int)pGroupParam->m_u32CurPntNo > pGroupParam->m_iPntNum) { break; } if(pGroupParam->m_bInit == FALSE) { pGroupParam->m_pu8DataLen[pGroupParam->m_u32CurPntNo-1] = u8DataLen; pGroupParam->m_pu8DataType[pGroupParam->m_u32CurPntNo-1] = u8DataType; pGroupParam->m_pu8GIN[pGroupParam->m_u32CurPntNo-1] = u8ItemNo+j; } if(GetOneValueOfASDU10(&rtumsg->MsgData[iOffset], &sValue, u8DataType, u8DataLen) == FALSE) { iOffset += u8DataLen; continue; } iOffset += u8DataLen; switch(sValue.m_iDataType) { case DT_UINT:// 无符号整型数 fValue = sValue.m_unValue.m_uValue; break; case DT_INT: fValue = sValue.m_unValue.m_iValue; break; case DT_FLOAT: fValue = sValue.m_unValue.m_fValue; break; case DT_CONTROL: fValue = sValue.m_unValue.m_dwValue; break; case DT_STRING: fValue = -1; break; case DT_BINARY: fValue = sValue.m_unValue.m_dwValue; break; case DT_NO:// 无数据 default: fValue = -1; break; } if(DT_STRING == sValue.m_iDataType) { msg.MsgData[offset++] = DATATYPE_STRING; msg.MsgData[offset++] = (BYTE)sValue.m_iDataNum; memcpy((void *)&msg.MsgData[offset], sValue.m_szValue, sValue.m_iDataNum); offset += sValue.m_iDataNum; } else if(DT_BINARY == sValue.m_iDataType) { if(2 == sValue.m_iDataNum) { if((fValue < 1) || (fValue > 2)) { fValue = 0; } else { fValue -= 1; } } msg.MsgData[offset++] = DATATYPE_DI; //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ //遥信量也是以float的形式上送的 //if(fValue > 0) //{ // msg.MsgData[offset++] = TRUE; //} //else //{ // msg.MsgData[offset++] = FALSE; //} //=============================================================== if(fValue > 0) { fValue = TRUE; } else { fValue = FALSE; } pfValue = (float *)&msg.MsgData[offset]; *pfValue = (float)fValue; offset += sizeof(float); //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ } else { // 南瑞装置的开关量以无符号整数送上来 //msg.MsgData[offset++] = DATATYPE_AI; if(pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].iFixDataType == 2) msg.MsgData[offset++] = DATATYPE_DI; else msg.MsgData[offset++] = DATATYPE_AI; pfValue = (float *)&msg.MsgData[offset]; *pfValue = (float)fValue; offset += sizeof(float); } if(pGroupParam->m_bInit == FALSE) { pGroupParam->m_psDataInfo[pGroupParam->m_u32CurPntNo-1].m_u32DataID = u8DataType; } pGroupParam->m_u32CurPntNo++; } } if(pGroupParam->m_iPntNum > 0) { if((int)pGroupParam->m_u32CurPntNo > pGroupParam->m_iPntNum) { sprintf(szbuf, "当前处理点号m_u32CurPntNo=%d, 定值总数m_iPntNum= %d", pGroupParam->m_u32CurPntNo, pGroupParam->m_iPntNum); DebugPrint(szbuf); pGroupParam->m_bInit = TRUE; pGroupParam->m_u32CurPntNo = 1; } } msg.MsgLen = offset; sendmsg.MsgLen = (WORD)(msg.MsgLen+sizeof(PROTECTMSGHEAD)); sendmsg.MsgType = MSGTYPE_BAOHU_SCADADATA; sendmsg.PortIdx = pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid; memcpy(sendmsg.MsgData, (BYTE *)&msg, sendmsg.MsgLen); PutBaohuDataToPort(&sendmsg); if(pDevParam->m_sDevParam.m_u32FuncCode == hREADFIX) { if(TRUE == pGroupParam->m_bInit) { MakeInteractionCmd(pLinkParam->m_sBaoHuCmdParam.m_iBaoHuCommid, commid, hREADDATAEND, ptrProHead, FALSE); pDevParam->m_sDevParam.m_u32FuncCode = 0; } } ptrProHead = (pPROTECTCONTENTHEAD)&sendmsg.MsgData[sizeof(PROTECTMSGHEAD)]; // wen 2004.01.06 写定值确认 if((M_CAUSE_WRITEACK == rtumsg->MsgData[8]) || ( M_CAUSE_WRITECONFIRM == rtumsg->MsgData[8])) { ptrProHead->uFuncCode = hWRITEFIXACK; Buban103ScadaCmdchange(commid, &sendmsg); } else if(M_CAUSE_WRITENAK == rtumsg->MsgData[8]) { ptrProHead->uFuncCode = hWRITEFIXNAK; Buban103ScadaCmdchange(commid, &sendmsg); } } void Buban103ScadaDatachange(int commid, RTUMSG *rtumsg) { // 类型标识(TYP):10 //rtumsg->MsgData[6]; // 可变结构限定词(VSQ):0x81 //rtumsg->MsgData[7]; // 传送原因(COT) //rtumsg->MsgData[8]; // 应用服务数据单元公共地址 //rtumsg->MsgData[9]; // 功能类型(FUN): 254(0xfe) //rtumsg->MsgData[10]; // 信息序号(INF): // 读组标题 : 240 // 读一个组的全部条目的值或属性 : 241 // 读单个条目的目录 : 243 // 读单个条目的值或属性 : 244 // 对通用分类数据总查询中止 : 245 //rtumsg->MsgData[11]; // 返回信息标识符(RII) //rtumsg->MsgData[12]; // 通用分类数据集数目 //rtumsg->MsgData[13]; // 以下为多个通用分类数据 // 通用分类标识序号(GIN):条目号和组号 //rtumsg->MsgData[14]; // 描述类别(KOD) // 无所指定的描述类别 : KOD_NOSPECIFIED(0) // 实际值 : KOD_ACTUALVALUE(1) // 缺省值 : KOD_DEFAULTVALUE(2) // 量程(最大值、最小值、步长) : KOD_RANGE(3) // 备用 : KOD_BACKUP1(4) // 精度(n,m) : KOD_PRECISION(5) // 因子 : KOD_FACTOR(6) // 参比 : KOD_REFERENCE(7) // 列表 : KOD_ENUMERATION(8) // 量纲 : KOD_DIMENSION(9) // 描述 : KOD_DESCRIPTION(10) // 备用 : KOD_BACKUP2(11) // 口令条目 : KOD_PASSWORD(12) // 只读 : KOD_READONLY(13) // 只写 : KOD_WRITEONLY(14) // 备用 : KOD_BACKUP3(15) // 备用 : KOD_BACKUP4(16) // 备用 : KOD_BACKUP5(17) // 备用 : KOD_BACKUP6(18) // 相应的功能类型和信息序号 : KOD_CORFUNCANDINF(19) // 相应的事件 : KOD_COREVENT(20) // 列表的文本阵列 : KOD_ENUMTEXTARRAY(21) // 列表的值阵列 : KOD_ENUMVALUEARRAY(22) // 相关联的条目 : KOD_RELATEDENTRIES(23) //rtumsg->MsgData[16]; // 数据类型描述 //rtumsg->MsgData[17]; //DATAID_NO : 无数据 //DATAID_OS8ASCII : 8位ASCII //DATAID_BSTRING : 8位2进制数 //DATAID_UIX : 无符号整数 //DATAID_INT : 整数 //DATAID_UFLOAT : 无符号浮点数 //DATAID_FLOAT : 浮点数 //DATAID_754SHORT : R32.23 IEEE 标准754短实数 //DATAID_754REAL : R64.53 IEEE 标准754实数 //DATAID_DOUBLE : 双点信息 //DATAID_SINGLE : 单点信息 //DATAID_13BITS : 带品质描述的被测值(13BITS) //DATAID_SORTIDNO : 通用分类标识序号 //DATAID_WITHTIME : 带时标的报文 //DATAID_WITHTIMESPACE : 带相对时标的报文 //DATAID_STRUCT : 数据结构 // 数据尺寸 //rtumsg->MsgData[18] // 数量 //rtumsg->MsgData[19] // 数据值(长度根据以上描述) // 2 ... n 个通用分类数据 int i, iGroupNo, iCfgGroupIdx; DEVDEF *pDevParam; BUBAN103LINKDEF *pLinkParam; BUBAN103PORTPARAM *pPortParam; DEVADDRPARAM sDevAddrParam; #ifdef _DEBUG_MSG_ char szbuf[256]; #endif sDevAddrParam.m_uchLinkAddr = rtumsg->MsgData[5]; sDevAddrParam.m_uchCommAddr = rtumsg->MsgData[9]; pPortParam = (BUBAN103PORTPARAM *)SioParam[commid].ExtInfo; if(FindProtectDev(pPortParam, &sDevAddrParam, FALSE) == FALSE) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d 不在端口配置保护范围内!!!", commid, sDevAddrParam.m_uchLinkAddr, sDevAddrParam.m_uchCommAddr); DebugPrint(szbuf); #endif return; } if(FALSE == GetSpecialPtr(commid, &sDevAddrParam, &pPortParam, &pLinkParam, &pDevParam)) { return; } //组 号 iGroupNo = rtumsg->MsgData[14]; for(i=0; im_sDevParam.m_iCfgGroupNum; i++) { if(pDevParam->m_sDevParam.m_saGroupDef[i].m_iGroupNo == iGroupNo) { iCfgGroupIdx = i; break; } } if(i >= pDevParam->m_sDevParam.m_iCfgGroupNum) { #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10 通用分类数据处理时,Group=%d不在处理范围内!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, iGroupNo); DebugPrint(szbuf); #endif return; } switch(pDevParam->m_sDevParam.m_saGroupDef[iCfgGroupIdx].m_iDataType) { // 处理保护模拟量 case PROTECT_AI_PNT_TYPE: Buban103GDprocessWithPAIToScada(rtumsg, &sDevAddrParam, iCfgGroupIdx); break; // 处理保护开关量 case PROTECT_DI_PNT_TYPE: Buban103GDprocessWithPDIToScada(rtumsg, &sDevAddrParam, iCfgGroupIdx); break; // 处理保护定值 case PROTECT_FIX_PNT_TYPE: Buban103GDprocessWithPFIXToScada(rtumsg, &sDevAddrParam, iCfgGroupIdx); break; default: #ifdef _DEBUG_MSG_ sprintf(szbuf, "端口%d linkaddr=%d devaddr=%d ASDU10处理时, Group=%d数据类型(=%d)不匹配!!!\n", commid, pLinkParam->m_uchLinkAddr, pDevParam->m_sDevParam.m_u8DevAddr, pDevParam->m_sDevParam.m_saGroupDef[iCfgGroupIdx].m_iGroupNo, pDevParam->m_sDevParam.m_saGroupDef[iCfgGroupIdx].m_iDataType); DebugPrint(szbuf); #endif break; } } void Buban103ScadaProtocolExchange(int commid, RTUMSG *rtumsg) { if(MSGTYPE_BAOHU_SCADACMD == rtumsg->MsgType) { // 下行命令 Buban103ScadaCmdchange(commid, rtumsg); } if(MSGTYPE_BAOHU_SCADADATA == rtumsg->MsgType) { // 上行数据 Buban103ScadaDatachange(commid, rtumsg); } } void Buban103DispConfig(int commid, BUBAN103PORTPARAM *psPortParam) { int i, j; char szDbg[256]; sprintf(szDbg, ">>>Disp Commid_%02d Config(PortType=%d):", commid, psPortParam->m_psBaoHu->PortType); DebugPrint(szDbg); sprintf(szDbg, ">>>LinkNum=%d", psPortParam->m_iLinkNum); DebugPrint(szDbg); for(i=0; im_iLinkNum; i++) { sprintf(szDbg, ">>>LinkIdx=%d DevNum=%d", i, psPortParam->m_psLink[i].m_iDevNum); DebugPrint(szDbg); if(PROTOCOL_MASTER == psPortParam->m_psBaoHu->PortType) { for(j=0; jm_psLink[i].m_iDevNum; j++) { sprintf(szDbg, "###DevNo %d", j); DebugPrint(szDbg); sprintf(szDbg, ">>>ProvAddr=%d CfgGroupNum=%d, DevAddr=%d", psPortParam->m_psLink[i].m_psDev[j].m_sDevParam.m_iProvAddr, psPortParam->m_psLink[i].m_psDev[j].m_sDevParam.m_iCfgGroupNum, psPortParam->m_psLink[i].m_psDev[j].m_sDevParam.m_u8DevAddr); DebugPrint(szDbg); DebugPrint((char*)"\n"); } } else { for(j=0; jm_psLink[i].m_iDevNum; j++) { sprintf(szDbg, "###DevNo %d", j); sprintf(szDbg, ">>>ProvAddr=%d Asdu10Num=%d, RealCommid=%d", psPortParam->m_psLink[i].m_psProvDev[j].m_iProvAddr, psPortParam->m_psLink[i].m_psProvDev[j].m_iAsdu10Num, psPortParam->m_psLink[i].m_psProvDev[j].m_iRealCommid); DebugPrint(szDbg); DebugPrint((char*)"\n"); } } } } void Buban103DispMalloc(int commid, int iSize) { char szbuf[128]; return; sprintf(szbuf, "disp: commid=%d, malloc(%d)", commid, iSize); DebugPrint(szbuf); } //===========================转发数据处理结束========================= //===========================数据处理函数结束=========================