/************************************************************************************ * * Copyright (C) 2002-2003 SCADA Control Technology Co., Ltd. All rights reserved. * * $Source: /opt/CVS_ROOT_PGC_EX2000/commserver/windows/widgets/tcphost.cpp,v $ * * $Author: zhuzhenhua $ * * $Date: 2006/08/07 03:16:49 $ * * $Revision: 1.3 $ * * $State: Exp $ * * $Name: $ * * $Locker: $ * * $Log: tcphost.cpp,v $ * Revision 1.3 2006/08/07 03:16:49 zhuzhenhua * no message * * Revision 1.2 2006/07/31 07:18:24 huyizhong * no message * * Revision 1.1.1.1 2006/07/05 07:31:44 jehu * no message * * Revision 1.12 2006/06/16 06:17:41 administrator * 修改变位遥信点号为word类型而不是dword类型的bug * * Revision 1.11 2006/05/26 10:38:03 administrator * 增加32位模拟量传送 * * Revision 1.10 2006/04/30 07:25:51 administrator * 不连接服务器,也可以做主备运转 * * Revision 1.9 2006/04/28 06:28:59 administrator * no message * * Revision 1.8 2006/04/26 05:59:27 administrator * 如果为并列运行方式下,所以装置都是下发机 * * Revision 1.7 2006/04/22 07:48:22 administrator * 可以屏蔽网络连接的错误信息,支持端口通讯时不切换主备机及网络连接成功的算法 * * Revision 1.6 2006/01/19 09:53:57 Administrator * bug修正 * * Revision 1.5 2006/01/17 06:14:44 Administrator * 增加对时、装置并列运行以及端口号偏移 * * Revision 1.4 2005/11/30 09:49:29 Administrator * 厦门出差时的修改 * * Revision 1.3 2005/11/18 03:49:23 Administrator * 增加施耐德modbus规约 * * Revision 1.2 2005/10/20 06:55:46 Administrator * 新增前置机功能 * * Revision 1.1 2005/10/12 06:03:45 Administrator * 增加前置机功能 * * **************************************************************************************/ //*************************************************************** //* tcphost.cpp * //* Liangchu Lee 1999.12.20 * //*************************************************************** #include "commport.h" #include "tcphost.h" #include "basetype.h" extern HOST_IP_ADDR HostIpAddr; extern char IniFilePath[256]; BYTE SyncHead[6] = {0xeb, 0x90, 0xeb, 0x90, 0xeb, 0x90}; int SystemTimeFlag; int SystemTimeMode; // 暂时不进行配置,在需要模拟盘接入时,在打开该接口 int gMapOutputPort=0; // 模拟盘输出端口 int gMapSaveDataPort=0; // 模拟盘请求数据缓冲端口 //int SystemLoginFalg; TCP_LINK_DEF HostLink[MAX_HOST]; TCP_RCV_DATA_BUF HostRevBuf[MAX_HOST]; TCP_SEND_DATA_BUF HostSendBuf[MAX_HOST]; FEND_DEF FendMsg; int Host_Socket_Port; int HostWSAStartupErr = FALSE; HOSTMSG gRtuChangeMsg[RTUCHANGMSGNUM]; BOOL GetConfigName(char *szFileName, int iFileNameLen, int IsPortConfig) { #ifdef OS_LINUX if(IsPortConfig) { strcpy(szFileName, "portconfig.ini"); } else { strcpy(szFileName, "config.ini"); } #else //GetCurrentDirectory(sizeof(szDir), szDir); if(IsPortConfig) { sprintf(szFileName, "%s/portconfig.ini", IniFilePath); } else { sprintf(szFileName, "%s/config.ini", IniFilePath); } #endif return TRUE; } BOOL IsWouldBlock() { BOOL bRetVal; bRetVal = FALSE; #ifdef OS_LINUX if(EINPROGRESS == errno) { bRetVal = TRUE; } #else if(WSAEWOULDBLOCK == WSAGetLastError()) { bRetVal = TRUE; } #endif return bRetVal; } BOOL IsWouldBlockEx(int neterrno) { BOOL bRetVal; bRetVal = FALSE; #ifdef OS_LINUX if(EINPROGRESS == neterrno) { bRetVal = TRUE; } #else if(WSAEWOULDBLOCK == neterrno) { bRetVal = TRUE; } #endif return bRetVal; } int GetNetErrorNo() { #ifdef OS_LINUX return errno; #else return WSAGetLastError(); #endif } void CloseNetSocket(SOCKET sock) { #ifdef OS_LINUX close(sock); #else closesocket(sock); #endif } void ULongToIPString(char *ipstr, u_long ipulong) { struct sockaddr_in server; ipstr[0] = 0; if(ipulong == 0) { return; } #ifdef OS_LINUX server.sin_addr.s_addr = ipulong; #else SwapByteSequence((char *)&ipulong, sizeof(u_long)); server.sin_addr.s_addr = ipulong; #endif strcpy(ipstr, inet_ntoa(server.sin_addr)); DebugPrint(ipstr); } void MakeNetNameplateMsgToHost(HOSTMSG *rtumsg) { rtumsg->MsgType = iNETNAMEPLATE; rtumsg->PortNumber = 0; rtumsg->MsgLen = 3; rtumsg->MsgData[0] = FEND_TYPE; *(short*)&rtumsg->MsgData[1] = (short)FendMsg.FendIdx; } void SendNetNameplateMsgToHost(int flag) { static int timecnt = 0; HOSTMSG rtumsg; int i; timecnt++; if((timecnt == (3000/TIMER_CNT)) || flag) { timecnt = 0; MakeNetNameplateMsgToHost(&rtumsg); for(i = 0; i < MAX_HOST; i++) { SendDataToHostSendBuf(i, (u_char*)&rtumsg, rtumsg.MsgLen+sizeof(HOSTMSGHEAD), flag); } } } void SendNetActiveMsgToHost(void) { static int timecnt = 0; HOSTMSG rtumsg; int i; timecnt++; if(timecnt >= (1000/TIMER_CNT)) { timecnt = 0; rtumsg.MsgType = iNETTESTMSG; rtumsg.PortNumber = 0; rtumsg.MsgLen = 0; for(i = 0; i < MAX_HOST; i++) { SendDataToHostSendBuf(i, (u_char*)&rtumsg, rtumsg.MsgLen+sizeof(HOSTMSGHEAD), FALSE); } } SendNetNameplateMsgToHost(FALSE); } void InitSetTcpIpAddr(void) { int i; char ipaddr[4][32], ipaddrmask[4][32]; char szbuf[256], InitFileName[256]; GetConfigName(InitFileName, sizeof(InitFileName), 0); GetPrivateProString("前置机", "前置机A地址1", "", ipaddr[0], 30, InitFileName); GetPrivateProString("前置机", "前置机A地址2", "", ipaddr[1], 30, InitFileName); GetPrivateProString("前置机", "前置机B地址1", "", ipaddr[2], 30, InitFileName); GetPrivateProString("前置机", "前置机B地址2", "", ipaddr[3], 30, InitFileName); GetPrivateProString("前置机", "前置机A地址1掩码", "", ipaddrmask[0], 30, InitFileName); GetPrivateProString("前置机", "前置机A地址2掩码", "", ipaddrmask[1], 30, InitFileName); GetPrivateProString("前置机", "前置机B地址1掩码", "", ipaddrmask[2], 30, InitFileName); GetPrivateProString("前置机", "前置机B地址2掩码", "", ipaddrmask[3], 30, InitFileName); //DebugPrint("InitSetTcpIpAddr Begin..."); for(i = 0; i < 4; i++) { FendMsg.SetTcpIpAddr[i][0] = 0x00; if(strlen((char*)ipaddr[i]) == 0) { continue; } if(CheckTcpIpAddr((char*)ipaddr[i]) == FALSE) { sprintf(szbuf, "前置机%C地址%d = %s 错误!!!", (i < 2) ? 'A' : 'B', (i % 2) + 1, ipaddr[i]); DebugPrint(szbuf); } else { strcpy((char*)FendMsg.SetTcpIpAddr[i], (char*)ipaddr[i]); } //DebugPrint(FendMsg.SetTcpIpAddr[i]); } //DebugPrint("InitSetTcpIpAddr End."); //SystemTimeFlag = GetPrivateProInt("对时", "对时", 1, InitFileName); SystemTimeMode = GetPrivateProInt("对时", "对时方式", 1, InitFileName); if(SystemTimeMode == 0) { SystemTimeFlag = 0; } else { SystemTimeFlag = 1; } } int FindFendIdx(void) { int i, retval; retval = -1; for(i = 0; i < MAX_ADDR; i++) { if(strlen(FendMsg.TcpIpAddr[i]) == 0) { continue; } if(CmpString2(FendMsg.TcpIpAddr[i], FendMsg.SetTcpIpAddr[0]) || CmpString2(FendMsg.TcpIpAddr[i], FendMsg.SetTcpIpAddr[1])) { retval = 0; break; } if(CmpString2(FendMsg.TcpIpAddr[i], FendMsg.SetTcpIpAddr[2]) || CmpString2(FendMsg.TcpIpAddr[i], FendMsg.SetTcpIpAddr[3])) { retval = 1; break; } } return retval; } void FindCurrentFend(void) { FendMsg.FendIdx = FindFendIdx(); if(FendMsg.FendIdx < 0) { if(CmpString2(FendMsg.Name, "HOSTA") || CmpString2(FendMsg.Name, "FENDA")) { FendMsg.FendIdx = 0; } else if(CmpString2(FendMsg.Name, "HOSTB") || CmpString2(FendMsg.Name, "FENDB")) { FendMsg.FendIdx = 1; } else { FendMsg.FendIdx = (FendMsg.Name[strlen(FendMsg.Name)-1] - 'A') ? 1 : 0; // 0 -- a, 1 -- b } } } BOOL InitFendMsgEx(void) { int i, j; struct hostent *test; char InitFileName[256]; GetConfigName(InitFileName, sizeof(InitFileName), 0); for(j = 0; j < MAX_FEND; j++) { FendMsg.FendExistFlag[j] = FALSE; FendMsg.FendExistCnt[j] = 0; FendMsg.LinkStatus[j] = FALSE; FendMsg.LinkCnt[j] = 0; FendMsg.SendTxdDataFlag[j] = FALSE; } for(j = 0; j < MAX_ADDR; j++) { FendMsg.AllIpAddr[j] = 0; FendMsg.HostIpAddr[j] = 0; FendMsg.BroadCastAddr[j] = 0; } InitSetTcpIpAddr(); FendMsg.EnableLink = GetPrivateProInt("前置机", "允许前置机连接", 1, InitFileName); FendMsg.EnableLink = FendMsg.EnableLink ? 1 : 0; FendMsg.LinkFlag = GetPrivateProInt("前置机", "前置机连接", 2, InitFileName) % 3; FendMsg.LinkFlag = 2; // wen 2006.01.14 增加装置的起始厂站号的偏移 FendMsg.iPortOffset = GetPrivateProInt("前置机", "起始厂站号", 0, InitFileName); if(FendMsg.iPortOffset < 0) { FendMsg.iPortOffset = 0; } // wen 2006.01.14 增加并列运行方式 FendMsg.iRunMode = GetPrivateProInt("前置机", "运行方式", 0, InitFileName) % 2; if(FendMsg.iRunMode < 0) { FendMsg.iRunMode = RUN_MODE_STANDBY; } // wen 2006.04.22 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽) FendMsg.iPortMask = GetPrivateProInt("前置机", "主备切换端口屏蔽字", 0, InitFileName); // wen 2006.05.20 32bit传送模拟量数据 FendMsg.iSendAiof32Bit = GetPrivateProInt("前置机", "遥测数据32位传送", 0, InitFileName); if(FendMsg.iSendAiof32Bit > 0) { FendMsg.iSendAiof32Bit = 1; } else { FendMsg.iSendAiof32Bit = 0; } gethostname(FendMsg.Name, 100); test = gethostbyname(FendMsg.Name); for(i=0, j=0; (ih_addr_list[i]; if(addr == NULL) { break; } inaddr = *((struct in_addr *)test->h_addr_list[i]); // 判断是否前置机IP地址(针对于ds-3116的3地址的情况) if(false == CheckIsFendIpAddr(ntohl(inaddr.s_addr))) { continue; } strcpy(FendMsg.TcpIpAddr[i], inet_ntoa(*addr)); FendMsg.AllIpAddr[i] = ntohl(inaddr.s_addr); if(IN_CLASSA(FendMsg.AllIpAddr[i])) //A类地址 { FendMsg.HostIpAddr[i] = FendMsg.AllIpAddr[i] & IN_CLASSA_NET; FendMsg.BroadCastAddr[i] = FendMsg.HostIpAddr[i] | IN_CLASSA_HOST; } else if(IN_CLASSB(FendMsg.AllIpAddr[i])) //B类地址 { FendMsg.HostIpAddr[i] = FendMsg.AllIpAddr[i] & IN_CLASSB_NET; FendMsg.BroadCastAddr[i] = FendMsg.HostIpAddr[i] | IN_CLASSB_HOST; } else if(IN_CLASSC(FendMsg.AllIpAddr[i])) //C类地址 { FendMsg.HostIpAddr[i] = FendMsg.AllIpAddr[i] & IN_CLASSC_NET; FendMsg.BroadCastAddr[i] = FendMsg.HostIpAddr[i] | IN_CLASSC_HOST; } } for(i = 0; i < (int)strlen(FendMsg.Name); i++) { FendMsg.Name[i] = toupper(FendMsg.Name[i]); } return TRUE; } BOOL InitHostWSAStartup(void) { int i, j; #ifdef OS_WINDOWS WSADATA WSAData; #endif char szbuf[256]; static BOOL bInitFinished = FALSE; char InitFileName[256]; GetConfigName(InitFileName, sizeof(InitFileName), 0); // wen 2002.08.01 初始化时,应该关闭网络在初始化 if(bInitFinished) { CloseHost(); } else { bInitFinished = TRUE; } #ifdef OS_WINDOWS if(WSAStartup(MAKEWORD(2, 1), (LPWSADATA)&WSAData) != 0) { WSAGetLastError(); HostWSAStartupErr = TRUE; return FALSE; } #endif; //InitFendMsg(); InitFendMsgEx(); for(i = 0; i < MAX_HOST; i++) { HostRevBuf[i].MsgCnt = 0; HostRevBuf[i].Front = 0; HostRevBuf[i].Rear = 0; HostSendBuf[i].MsgLen = 0; HostLink[i].InitOk = FALSE; HostLink[i].InitFlag = FALSE; HostLink[i].ExistFlag = FALSE; HostLink[i].CommFlag = FALSE; HostLink[i].Status = 2; HostLink[i].StatusCnt = 0; HostLink[i].VersionFalgByte = 0; HostLink[i].RevHostStatusMsg = 0; HostLink[i].NetNameplateFalg = FALSE; HostLink[i].SocketId = INVALID_SOCKET; } Host_Socket_Port = GetPrivateProInt("网络设置", "主机网络端口", 7119, InitFileName); GetPrivateProString("主机地址", "主机A地址1", "", (char*)HostLink[0].TcpIpAddr[0], 30, InitFileName); GetPrivateProString("主机地址", "主机A地址2", "", (char*)HostLink[0].TcpIpAddr[1], 30, InitFileName); GetPrivateProString("主机地址", "主机B地址1", "", (char*)HostLink[1].TcpIpAddr[0], 30, InitFileName); GetPrivateProString("主机地址", "主机B地址2", "", (char*)HostLink[1].TcpIpAddr[1], 30, InitFileName); for(i=0, j=0; i < 4; i++) { if(strlen((char*)HostLink[i/2].TcpIpAddr[i%2]) == 0) { continue; } if(CheckTcpIpAddr((char*)HostLink[i/2].TcpIpAddr[i%2]) == FALSE) { sprintf(szbuf, "主机%c地址%d = %s 错误!!!", ((i < 2) ? 'A' : 'B'), ((i % 2) + 1), HostLink[i/2].TcpIpAddr[i%2]); DebugPrint(szbuf); //sprintf(szbuf, "i=%d, j=%d", i, j); //DebugPrint(szbuf); continue; } j++; } FendMsg.EnableLink = (j) ? FendMsg.EnableLink : 0; FindCurrentFend(); HostWSAStartupErr = FALSE; return TRUE; } void LinkOneHost(int hostid) { struct sockaddr_in sa; int retval, len, tmp_len; char tmp_buf[256]; u_long largp = 1L; //非阻塞模式 /* if((!SystemLoginFalg) && RESTRICTED_USER) { return; } */ // wen 2002.01.24 //if(HostLink[hostid].Status == 2) return; if(HostLink[hostid].InitOk == TRUE) { return; } if(HostLink[hostid].InitFlag == TRUE) { return; } if(CheckTcpIpAddr((char*)HostLink[hostid].TcpIpAddr[HostLink[hostid].CurLinkIdx]) == FALSE) { HostLink[hostid].TcpIpAddr[HostLink[hostid].CurLinkIdx][0] = 0x00; if(CheckTcpIpAddr((char*)HostLink[hostid].TcpIpAddr[HostLink[hostid].CurLinkIdx ? 0 : 1])) HostLink[hostid].CurLinkIdx = HostLink[hostid].CurLinkIdx ? 0 : 1; return; } HostLink[hostid].InitLinkCnt++; HostLink[hostid].InitLinkCnt = 0; HostLink[hostid].InitFlag = TRUE; if((HostLink[hostid].SocketId = socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET) { #ifdef OS_LINUX retval = errno; #else retval = WSAGetLastError(); #endif HostLink[hostid].InitFlag = FALSE; HostLink[hostid].InitOk = FALSE; return; } #ifdef OS_LINUX // wen 2005.07.08 将socket设置为非阻塞模式 retval = fcntl(HostLink[hostid].SocketId, F_GETFL, 0); fcntl(HostLink[hostid].SocketId, F_SETFL, retval|O_NONBLOCK); #else retval = ioctlsocket(HostLink[hostid].SocketId, FIONBIO, (u_long FAR *)&largp); if(SOCKET_ERROR == retval) { retval = WSAGetLastError(); sprintf(tmp_buf, "wen: ioctlsocket设置非阻塞模式错误, SocketError=%d, SocketId = %d", retval, HostLink[hostid].SocketId); DebugPrint(tmp_buf); return; } #endif if(ShmGetDispHostLinkFlag()) { sprintf(tmp_buf, "【socket=%d】前置机连接主机%c(%s:%d)!!!", HostLink[hostid].SocketId, hostid+'A', (char *)HostLink[hostid].TcpIpAddr[HostLink[hostid].CurLinkIdx], Host_Socket_Port); DebugPrint((char*)tmp_buf); } retval = MAX_NET_BUF; len = sizeof(retval); setsockopt(HostLink[hostid].SocketId, SOL_SOCKET, SO_RCVBUF, (char*)&retval, len); setsockopt(HostLink[hostid].SocketId, SOL_SOCKET, SO_SNDBUF, (char*)&retval, len); len = 4; tmp_buf[0] = 1; retval = setsockopt(HostLink[hostid].SocketId, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, len); retval = getsockopt(HostLink[hostid].SocketId, SOL_SOCKET, SO_KEEPALIVE, tmp_buf, &len); tmp_len = 1; retval = setsockopt(HostLink[hostid].SocketId, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp_len, len); memset((char *)&sa, 0, sizeof(struct sockaddr_in)); sa.sin_port = htons((WORD)Host_Socket_Port); sa.sin_family = PF_INET; sa.sin_addr.s_addr = inet_addr((char*)HostLink[hostid].TcpIpAddr[HostLink[hostid].CurLinkIdx]); retval = connect((SOCKET)HostLink[hostid].SocketId, (struct sockaddr *)&sa, sizeof(sa)); if(retval != 0) { // wen 2005.10.21 修改网络错误判断 retval = GetNetErrorNo(); if(IsWouldBlockEx(retval) == FALSE) //if(IsWouldBlock() == FALSE) { HostLink[hostid].InitFlag = FALSE; HostLink[hostid].InitOk = FALSE; CloseHostSocket(HostLink[hostid].SocketId, 0); // wen 2002.04.05 if(ShmGetDispHostLinkFlag()) { sprintf(tmp_buf, "与主机%c(%s:%d)网络连接错误,错误号 = %d !!!", hostid + 'A', (char *)HostLink[hostid].TcpIpAddr[HostLink[hostid].CurLinkIdx], Host_Socket_Port, retval); DebugPrint((char*)tmp_buf); } } } //else //{ // HostConnect(HostLink[hostid].SocketId, 0); //} } void HostConnect(SOCKET socket, WORD error) { int id; char szbuf[256]; for(id = 0; id < MAX_HOST; id++) { if(socket == HostLink[id].SocketId) { HostLink[id].InitFlag = FALSE; HostLink[id].iNoWriteNum = 0; if(error) { if(ShmGetDispHostLinkFlag()) { sprintf(szbuf, "与主机%c(%s:%d)网络连接失败,错误号 = %d !!!", id+'A', (char *)HostLink[id].TcpIpAddr[HostLink[id].CurLinkIdx], Host_Socket_Port, error); DebugPrint((char*)szbuf); } HostLink[id].InitOk = FALSE; CloseHostSocket(HostLink[id].SocketId, 0); break; } HostLink[id].InitOk = TRUE; if(ShmGetDispHostLinkFlag()) { sprintf(szbuf, "与主机%c(%s:%d)网络连接成功 !!!", id+'A', (char *)HostLink[id].TcpIpAddr[HostLink[id].CurLinkIdx], Host_Socket_Port); DebugPrint((char*)szbuf); } //HostSendBuf[id].MsgLen = 0; // wen 2002.07.10 确保首先发送以下帧 ClearSendBuffer(id); ClearRecvBuffer(id); SendNetNameplateMsgToHost(TRUE); SendNetNameplateMsgToHost(TRUE); SendHostSendBufToHost(); } } } void LinkToHost(void) { int i; static int cnt = 0; //char szbuf[256]; if(HostWSAStartupErr) { return; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // wen 2006.04.30 将该段代码提前,如果不连接服务器,也可以做主备运转 for(i = 0; i < MAX_FEND; i++) { FendMsg.LinkCnt[i]++; FendMsg.FendExistCnt[i]++; if(FendMsg.LinkCnt[i] > 10000 / TIMER_CNT) { FendMsg.LinkCnt[i]--; FendMsg.LinkStatus[i] = FALSE; } if(FendMsg.FendExistCnt[i] > 10000 / TIMER_CNT) { FendMsg.FendExistCnt[i]--; FendMsg.FendExistFlag[i] = FALSE; } } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ if(FendMsg.EnableLink == 0) { return; } for(i = 0; i < MAX_HOST; i++) { if(HostLink[i].InitOk == TRUE) { HostLink[i].StatusCnt++; // wen 2002.01.24 //if(HostLink[i].StatusCnt > (5000/TIMER_CNT)) if(HostLink[i].StatusCnt > (10000/TIMER_CNT)) { // wen 2005.07.21 修改冗余代码 //sprintf(szbuf, "【socket=%d】接收主机%c数据超时关闭!!!", // HostLink[i].SocketId, i + 'A'); //DebugPrint((char*)szbuf); //HostLink[i].StatusCnt = 0; CloseHostSocket(HostLink[i].SocketId, OVER_TIME_CLOSE_NET); } } } SendNetActiveMsgToHost(); switch(FendMsg.LinkFlag) { case 0: case 1: LinkOneHost(FendMsg.LinkFlag); break; case 2: for(i = 0; i < MAX_HOST; i++) { LinkOneHost(i); } break; default: break; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // wen 2006.04.30 将该段代码提前,如果不连接服务器,也可以做主备运转 /* for(i = 0; i < MAX_FEND; i++) { FendMsg.LinkCnt[i]++; FendMsg.FendExistCnt[i]++; if(FendMsg.LinkCnt[i] > 10000 / TIMER_CNT) { FendMsg.LinkCnt[i]--; FendMsg.LinkStatus[i] = FALSE; } if(FendMsg.FendExistCnt[i] > 10000 / TIMER_CNT) { FendMsg.FendExistCnt[i]--; FendMsg.FendExistFlag[i] = FALSE; } } */ //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ cnt++; if((cnt * TIMER_CNT) < 3000) { return; } cnt = 0; switch(FendMsg.LinkStatus[1]*2 + FendMsg.LinkStatus[0]) { case 3: // 两前置机都处于连机状态 for(i = 0; i < MAX_HOST; i++) { if(HostLink[i].Status == 0) { //SendSwitch(i); } } break; case 1: // 仅前置机 A 处于连机状态 //SendSwitch(0); break; case 2: // 仅前置机 B 处于连机状态 //SendSwitch(1); break; default: break; } } void CloseHostSocket(SOCKET socket, int flag) { int i; char szbuf[256]; for(i = 0; i < MAX_HOST; i++) { if((HostLink[i].SocketId == socket) && (HostLink[i].SocketId != INVALID_SOCKET)) { CloseNetSocket(HostLink[i].SocketId); HostSendBuf[i].MsgLen = 0; HostLink[i].InitOk = FALSE; HostLink[i].InitFlag = FALSE; HostLink[i].ExistFlag = FALSE; HostLink[i].CommFlag = FALSE; HostLink[i].Status = 2; HostLink[i].StatusCnt = 0; HostLink[i].VersionFalgByte = 0; HostLink[i].RevHostStatusMsg = 0; if(CheckTcpIpAddr((char*)HostLink[i].TcpIpAddr[HostLink[i].CurLinkIdx ? 0 : 1])) { HostLink[i].CurLinkIdx = HostLink[i].CurLinkIdx ? 0 : 1; } if(ShmGetDispHostLinkFlag()) { switch(flag) { case HOST_CLOSE_NET: sprintf(szbuf, "【socket=%d】主机主动关闭与主机 %c 的网络连接!!!", HostLink[i].SocketId, i + 'A'); DebugPrint((char*)szbuf); break; case OVER_TIME_CLOSE_NET: sprintf(szbuf, "【socket=%d】网络定时超时关闭与主机 %c 的网络连接!!!", HostLink[i].SocketId, i + 'A'); DebugPrint((char*)szbuf); break; case FEND_CLOSE_NET: sprintf(szbuf, "【socket=%d】前置机关闭与主机 %c 的网络连接!!!", HostLink[i].SocketId, i + 'A'); DebugPrint((char*)szbuf); break; case ERROR_CLOSE_NET: sprintf(szbuf, "【socket=%d】网络错误后关闭与主机 %c 的网络连接!!!", HostLink[i].SocketId, i + 'A'); DebugPrint((char*)szbuf); break; default: sprintf(szbuf, "【socket=%d】其他情况关闭与主机 %c 的网络连接!!!", HostLink[i].SocketId, i + 'A'); DebugPrint((char*)szbuf); break; } } HostLink[i].SocketId = INVALID_SOCKET; } } } void CloseHost(void) { int i; for(i = 0; i < MAX_HOST; i++) { CloseHostSocket(HostLink[i].SocketId, FEND_CLOSE_NET); } } void PutDataToHostRevBuf(int hostid, char *buf, int len) { int j; char *ptr, szbuf[256]; if(HostRevBuf[hostid].MsgCnt == 0) { HostRevBuf[hostid].Front = 0; HostRevBuf[hostid].Rear = 0; } ptr = buf; if((MAX_NET_BUF - HostRevBuf[hostid].MsgCnt) > len) { j = MAX_NET_BUF - HostRevBuf[hostid].Rear; if(j >= len) { memmove((char*)&HostRevBuf[hostid].MsgData[HostRevBuf[hostid].Rear], ptr, len); HostRevBuf[hostid].Rear += len; HostRevBuf[hostid].Rear %= MAX_NET_BUF; } else { sprintf(szbuf, "主机%c接收暂存缓冲区分半存储!!!", 'A'+hostid); DebugPrint((char*)szbuf); memmove((char*)&HostRevBuf[hostid].MsgData[HostRevBuf[hostid].Rear], ptr, j); HostRevBuf[hostid].Rear += j; HostRevBuf[hostid].Rear %= MAX_NET_BUF; memmove((char*)HostRevBuf[hostid].MsgData, ptr, len - j); HostRevBuf[hostid].Rear += (len-j); HostRevBuf[hostid].Rear %= MAX_NET_BUF; } HostRevBuf[hostid].MsgCnt += len; } else { sprintf(szbuf, "主机%c接收暂存缓冲区溢出!!!", 'A'+hostid); DebugPrint((char*)szbuf); } } BOOL ReadHost(int hostid) { int retval, errorcode; char msgbuf[MAX_NET_BUF]; BOOL bRetVal; bRetVal = FALSE; if(HostLink[hostid].InitOk) { retval = recv(HostLink[hostid].SocketId, msgbuf, MAX_NET_BUF, 0); if(retval > 0) { PutDataToHostRevBuf(hostid, (char*)msgbuf, retval); HostLink[hostid].StatusCnt = 0; bRetVal = TRUE; } else { #ifdef OS_LINUX if(retval == 0) { errorcode = 0; } else { errorcode = errno; } #else errorcode = WSAGetLastError(); #endif if(ShmGetDispHostLinkFlag()) { sprintf(msgbuf, "recv(HostLink[%d].SocketId=%d) = %d(errno=%d)", hostid, HostLink[hostid].SocketId, retval, errorcode); DebugPrint(msgbuf); } } } return bRetVal; } int GetHostMsgFormHostRevBuf(HOSTMSG *hmsg, int hostid) { int status; int msglen, msgidx; int front, cnt; BYTE buf[32]; char szbuf[256]; ORTUMSG * msg; front = HostRevBuf[hostid].Front; cnt = HostRevBuf[hostid].MsgCnt; status = 0; while (cnt) { switch(status) { case 0: case 1: case 2: case 3: case 4: case 5: if(HostRevBuf[hostid].MsgData[front] == SyncHead[status]) { status++; } else { status = 0; } front = (front + 1) % MAX_NET_BUF; cnt--; if(status == 0) { HostRevBuf[hostid].Front = front; HostRevBuf[hostid].MsgCnt = cnt; } break; case 6: case 7: case 8: case 9: buf[status-6] = HostRevBuf[hostid].MsgData[front]; status++; front = (front + 1) % MAX_NET_BUF; cnt--; if(status == 10) { msg = (ORTUMSG*)&buf; hmsg->MsgType = msg->MsgType; hmsg->PortNumber = msg->PortNumber; hmsg->MsgLen = SequenceHostToRtuWord((WORD)msg->MsgLen); hmsg->EMsgLen = 0; msglen = hmsg->MsgLen; if(msglen == 0) { HostRevBuf[hostid].Front = front; HostRevBuf[hostid].MsgCnt = cnt; return TRUE; } if(msglen > (MAX_RTU_MSG_SIZE - 12)) { sprintf(szbuf, "接收主机%c信息包超长 Len = %d!", 'A'+hostid, msglen); DebugPrint((char*)szbuf); status = 0; HostRevBuf[hostid].Front = front; HostRevBuf[hostid].MsgCnt = cnt; } } msgidx = 0; break; case 10: hmsg->MsgData[msgidx++] = HostRevBuf[hostid].MsgData[front]; front = (front + 1) % MAX_NET_BUF; cnt--; msglen--; if(msglen == 0) { HostRevBuf[hostid].Front = front; HostRevBuf[hostid].MsgCnt = cnt; return TRUE; } if(msgidx < 6) { break; } if(memcmp((char*)&hmsg->MsgData[msgidx-6], (char*)SyncHead, 6) == 0) { sprintf(szbuf, "接收主机%c 信息包失步! ", 'A'+ hostid); DebugPrint((char*)szbuf); status = 0; HostRevBuf[hostid].Front = front; HostRevBuf[hostid].MsgCnt = cnt; } break; default: status = 0; break; } } return FALSE; } BOOL ReadDataFormHost(SOCKET socket) { BOOL bRetVal; int i, hostid; WORD sum; char szbuf[256]; HOSTMSG hostmsg; DAY_TIME DateTime; SYSTEMTIME *pTime; bRetVal = TRUE; for(hostid = 0; hostid < MAX_HOST; hostid++) { if(HostLink[hostid].SocketId == socket) { bRetVal = ReadHost(hostid); break; } } if(bRetVal == FALSE) { return bRetVal; } if(hostid >= MAX_HOST) { return FALSE; } while(GetHostMsgFormHostRevBuf(&hostmsg, hostid)) { if(FALSE == AllDataRtuToHostByteSequence(&hostmsg)) { sprintf(szbuf, "接收主机%c数据格式错误!!!", 'A'+ hostid); DebugPrint((char*)szbuf); continue; } if(HostLink[hostid].VersionFalgByte & CHECK_VERSION_FLAG) { sum = hostmsg.MsgData[hostmsg.MsgLen - 2] + hostmsg.MsgData[hostmsg.MsgLen - 1] * 256; sum = SequenceRtuToHostWord(sum); if(sum != CalCheckout((u_char*)hostmsg.MsgData, hostmsg.MsgLen - 2)) { sprintf(szbuf, "接收主机%c信息校验码错误!!!", 'A'+ hostid); DebugPrint((char*)szbuf); continue; } hostmsg.MsgLen -= 2; } switch(hostmsg.MsgType) { case hHOSTSTATUS: for(i = 0; i < MAX_HOST; i++) { HostLink[i].Status = (*(int*)&hostmsg.MsgData[i*sizeof(int)]) % 3; } // wen 2002.01.24 HostLink[hostid].RevHostStatusMsg = TRUE; break; case hNETTESTMSG: break; case hTIMEINFORM: if((HostLink[0].Status == 0) && (HostLink[1].Status == 0)) { continue; } if(HostLink[hostid].Status) { continue; } if(SystemTimeFlag && (SystemTimeMode == 1)) { //SetLocalTime((SYSTEMTIME*)hostmsg.MsgData); pTime = (SYSTEMTIME*)hostmsg.MsgData; if(pTime->wSecond > 5) { break; } DateTime.Year = pTime->wYear; DateTime.Month = (BYTE)pTime->wMonth; DateTime.Day = (BYTE)pTime->wDay; DateTime.Hour = (BYTE)pTime->wHour; DateTime.Min = (BYTE)pTime->wMinute; DateTime.Sec = (BYTE)pTime->wSecond; DateTime.mSec = pTime->wMilliseconds; SetLocalTimeEx(&DateTime); } break; // wen 2003.10.24 增加动态数据库修改的同步(郑州农科) //case hRELOADDBSTN:// 重新装入数据库站信息 // 启动线程拷贝站信息数据并替换该站的数据类型的句柄(如:模拟量,开关量,电度量和离线量) // break; // wen 2003.10.24 增加动态数据库修改的同步(郑州农科) //case hRELOADDBPOINT:// 重新装入数据库点信息 // 直接设置点信息 // break; default: // hMAPANDATA,hMAPDIDATA,hBYPASSCMD,hYKYTCMD etc. if((HostLink[0].Status == 0) && (HostLink[1].Status == 0)) { continue; } // wen 2002.04.05 // 主备服务器数据都发送(针对可能无应答的服务器) //if(HostLink[hostid].Status) // continue; HostDataProce(&hostmsg); break; } } return bRetVal; } int SendHost(int hostid); int SendDataToHostSendBuf(int hostid, u_char *buf, int len, BOOL bInsert) { int imsgLen; HOSTMSG *revmsg; ORTUMSG msg; char szbuf[256]; if(HostLink[hostid].InitOk == FALSE) { return 0; } if(!bInsert) { if(HostLink[hostid].RevHostStatusMsg != TRUE) { return 0; } if(HostLink[hostid].NetNameplateFalg == FALSE) { MakeNetNameplateMsgToHost((HOSTMSG *)buf); HostLink[hostid].NetNameplateFalg = TRUE; } } revmsg = (HOSTMSG*)buf; // wen 2002.08.01 数据帧格式错误,长度大于总长度 if(revmsg->MsgLen > len) { sprintf(szbuf, "发送到主机%c缓冲区数据帧格式错误:帧长度:%d 字节", 'A'+hostid, revmsg->MsgLen); DebugPrint((char*)szbuf); return 0; } // wen 2002.07.11 给判断多留一些空间 //imsgLen = msg.MsgLen + sizeof(ORTUMSGHEAD); imsgLen = revmsg->MsgLen + sizeof(ORTUMSGHEAD); // 6bytes同步头+2bytes校验+12bytes空闲字节 //if((MAX_NET_BUF - HostSendBuf[hostid].MsgLen) < (msg.MsgLen+6)) if((MAX_NET_BUF - HostSendBuf[hostid].MsgLen) < (imsgLen+20)) { if(SendHost(hostid) == FALSE) { return 0; } // wen 2002.08.01 数据发送以后,缓冲区长度任然不足 if((MAX_NET_BUF - HostSendBuf[hostid].MsgLen) < (imsgLen+20)) { sprintf(szbuf, "主机%c发送缓冲区溢出!!!", 'A'+hostid); DebugPrint((char*)szbuf); return 0; } } /* msg.MsgType = (BYTE)revmsg->MsgType; msg.MsgLen = revmsg->MsgLen; msg.PortNumber = (BYTE)revmsg->PortNumber; memmove((char*)msg.MsgData, (char*)revmsg->MsgData, revmsg->MsgLen); */ if(FALSE == AllDataHostToRtuByteSequence(revmsg, &msg)) { sprintf(szbuf, "向主机%c发送数据格式错误!!!", 'A'+ hostid); DebugPrint((char*)szbuf); return 0; } if(HostLink[hostid].VersionFalgByte & CHECK_VERSION_FLAG) { *(WORD*)&msg.MsgData[imsgLen] = SequenceHostToRtuWord(CalCheckout(msg.MsgData, imsgLen)); imsgLen += 2; msg.MsgLen = SequenceHostToRtuWord((WORD)imsgLen); } memmove((char*)&HostSendBuf[hostid].MsgData[HostSendBuf[hostid].MsgLen], (char*)SyncHead, 6); HostSendBuf[hostid].MsgLen += 6; memmove((char*)&HostSendBuf[hostid].MsgData[HostSendBuf[hostid].MsgLen], (char*)&msg, imsgLen); HostSendBuf[hostid].MsgLen += imsgLen; // wen 2002.08.01 数据缓冲区长度过长(永远也不会到达) if(HostSendBuf[hostid].MsgLen > MAX_NET_BUF) { sprintf(szbuf, "主机%c缓冲区长度越限:长度:%d 字节", 'A'+hostid, HostSendBuf[hostid].MsgLen); DebugPrint((char*)szbuf); HostSendBuf[hostid].MsgLen = 0; return 0; } return len; } void SendDataToAllHostSendBuf(u_char *buf, int len) { int i; for(i = 0; i < MAX_HOST; i++) { SendDataToHostSendBuf(i, buf, len, FALSE); } } int SendHost(int hostid) { int retval, neterror; char szbuf[256]; struct timeval timeout; fd_set fdset_wr; if(HostLink[hostid].InitOk == FALSE) { HostSendBuf[hostid].MsgLen = 0; return TRUE; } if(HostLink[hostid].SocketId == INVALID_SOCKET) { HostSendBuf[hostid].MsgLen = 0; return TRUE; } if(HostSendBuf[hostid].MsgLen == 0) { return TRUE; } FD_ZERO(&fdset_wr); FD_SET(HostLink[hostid].SocketId, &fdset_wr); memset((char*)&timeout, 0, sizeof(struct timeval)); // wen 2005.07.08 设置超时等待时间(这样会丢失数据吗?) //timeout.tv_usec = 200; retval = select(HostLink[hostid].SocketId+1, (fd_set*)0, &fdset_wr, (fd_set*)0, &timeout); if(retval == 0) { // wen 2005.10.21 累计值超限关闭socket HostLink[hostid].iNoWriteNum++; if(HostLink[hostid].iNoWriteNum > MAX_NO_WRITE_NUM) { sprintf(szbuf, "主机%c SOCKET不可写标记累计超过限值", 'A'+hostid); DebugPrint((char*)szbuf); CloseHostSocket(HostLink[hostid].SocketId, OVER_TIME_CLOSE_NET); HostLink[hostid].iNoWriteNum = 0; } return TRUE; } if(retval != -1) { // 首先判断socket写标识正常否 if(FD_ISSET(HostLink[hostid].SocketId, &fdset_wr)) { HostLink[hostid].iNoWriteNum = 0; retval = send(HostLink[hostid].SocketId, (char*)HostSendBuf[hostid].MsgData, HostSendBuf[hostid].MsgLen, 0); if(SOCKET_ERROR == retval) { neterror = GetNetErrorNo(); if(IsWouldBlockEx(neterror) == TRUE) { if(ShmGetDispHostLinkFlag()) { sprintf(szbuf, "【socket=%d】发送主机%c网络可能阻塞", HostLink[hostid].SocketId, 'A'+hostid); DebugPrint((char*)szbuf); } } else { if(ShmGetDispHostLinkFlag()) { sprintf(szbuf, "发送主机%c缓冲区网络出错:%d,请求:%d 字节", 'A'+hostid, neterror, HostSendBuf[hostid].MsgLen); DebugPrint((char*)szbuf); } CloseHostSocket(HostLink[hostid].SocketId, ERROR_CLOSE_NET); return FALSE; } } else { HostSendBuf[hostid].MsgLen -= retval; if(HostSendBuf[hostid].MsgLen > 0) { if(ShmGetDispHostLinkFlag()) { sprintf(szbuf, "【socket=%d】发送主机%c缓冲区出错! 剩余:%d 字节,发送:%d 字节", HostLink[hostid].SocketId, 'A'+hostid, HostSendBuf[hostid].MsgLen, retval); DebugPrint((char*)szbuf); } memmove(HostSendBuf[hostid].MsgData, HostSendBuf[hostid].MsgData+retval, HostSendBuf[hostid].MsgLen); } else { //sprintf(szbuf, "【socket=%d】发送主机%c缓冲区! 发送:%d 字节", // HostLink[hostid].SocketId, 'A'+hostid, retval); //DebugPrint((char*)szbuf); HostSendBuf[hostid].MsgLen = 0; } } } else { CloseHostSocket(HostLink[hostid].SocketId, ERROR_CLOSE_NET); return FALSE; } } else { CloseHostSocket(HostLink[hostid].SocketId, ERROR_CLOSE_NET); return FALSE; } return TRUE; } void SendHostSendBufToHost(void) { int i; // wen 2003.06.11 增加变化数据的发送 SendRtuChangeDataToHost(); for(i = 0; i < MAX_HOST; i++) { SendHost(i); } } void ClearSendBuffer(int hostid) { HostSendBuf[hostid].MsgLen = 0; } void ClearRecvBuffer(int hostid) { HostRevBuf[hostid].MsgCnt = 0; HostRevBuf[hostid].Front = 0; HostRevBuf[hostid].Rear = 0; } void HostDataProceWithSignalYkYt(HOSTMSG *hmsg) { BOOL bFailed; char buf[64]; int port, ykytpnt; SIO_PARAM_DEF *pSioParam; pSioParam = GetSioParamPtr(); // wen 2006.01.14 增加端口偏移 //port = hmsg->PortNumber; port = hmsg->PortNumber - FendMsg.iPortOffset; if(port < 0 ) { return; } bFailed = TRUE; if((hmsg->MsgLen != 5) && (hmsg->MsgLen != 7)) { bFailed = FALSE; } else if((hmsg->MsgData[3] < 1) || (hmsg->MsgData[3] > 8)) { bFailed = FALSE; } else if((hmsg->MsgData[4] < 1) || (hmsg->MsgData[4] > 2)) { bFailed = FALSE; } ykytpnt = *((short *)&hmsg->MsgData[1]); if((bFailed == FALSE) || (pSioParam[port].m_psBaoHu == NULL)) { buf[0] = (BYTE)ykytpnt; buf[1] = 0; buf[2] = 0; SetYkYtAckData(port, buf); return; } memset(buf, 0, sizeof(buf)); buf[0] = port; buf[4] = (BYTE)ykytpnt; buf[8] = hmsg->MsgData[3]; buf[9] = (hmsg->MsgData[4] == 1) ? 1 : 2; SendYkYtCommand(port, buf, 10); } //*************************************************************** //* 主机数据处理 * //*************************************************************** void HostDataProce(HOSTMSG *hostmsg) { int port, iReLoadDefCnt=0; HOSTMSG msg; switch(hostmsg->MsgType) { case hYKYTCMD: if(((hostmsg->MsgLen % 5) != 0) && ((hostmsg->MsgLen % 7) != 0)) { break; } if(hostmsg->MsgLen >= 10) // 多条遥调遥控命令 { //ProLen = 0; //memmove((char*)&MultiYkYtMsg, (char*)hostmsg, hostmsg->MsgLen+sizeof(HOSTMSGHEAD)); //MultiYkYtFlag = TRUE; //MultiYkYtSelectProce(); //MultiYkYtFlag = FALSE; } else // 单条遥调遥控命令 { HostDataProceWithSignalYkYt(hostmsg); } break; case hBYPASSCMD: switch(hostmsg->MsgData[1]) { case 0x0d: case 0x0e: case 0x11: //SendDataToPort(hostmsg->PortNumber, (char*)hostmsg->MsgData, hostmsg->MsgLen, CLEAR_INPUT_BUF); break; case 0x1a: //SendDataToPort(hostmsg->PortNumber, (char*)hostmsg->MsgData, hostmsg->MsgLen, CLEAR_INPUT_BUF); break; default: //SendDataToPort(hostmsg->PortNumber, (char*)hostmsg->MsgData, hostmsg->MsgLen, CLEAR_INPUT_BUF); break; } break; case hMAPANDATA: case hMAPDIDATA: //FormHostMapDataProce(hostmsg); break; case hDATA_OUTPUT_CTRL: //hostmsg->PortNumber = hostmsg->MsgData[1]; //MakeRsLinks22DataCtrlCommand(hostmsg); hostmsg->PortNumber = hostmsg->MsgData[1]; port = hostmsg->PortNumber; //selidx = PortParam[port].CurrentPortSel; //switch(PortParam[port].CommPort[selidx].RtuType) //{ // case RSLINKS22DDE: // MakeRsLinks22DataCtrlCommand(hostmsg); // break; // case DISA2000: // Disa2000AoCommand(hostmsg); // break; //} break; case hRELOADDATABASE: msg.MsgType = hRELOADDATABASE; msg.PortNumber = 0; msg.MsgLen = 1; msg.EMsgLen = 0; msg.MsgData[0] = FALSE; if(iReLoadDefCnt * TIMER_CNT / 1000 > 60) { iReLoadDefCnt = 0; //ReLoadPortDefine(); msg.MsgData[0] = TRUE; } SendDataToAllHostSendBuf((u_char*)&msg, msg.MsgLen+sizeof(HOSTMSGHEAD)); break; case hMAPALLOP: //HostMapOpProc(hostmsg); break; // 数据库信息修改 case NET_PROFILE_UPDATE: //ModifyDBProc(hostmsg); break; } } //*************************************************************** //* 发送变化数据到主机 * //*************************************************************** void SendRtuChangeDataToHost(void) { int i; #ifdef FEND_STANDBY_NOSEND // wen 2003.01.07 前置机为备用机时,不发送变化数据给服务器 if(!IsSendDatatoPort(-1)) return; #endif for(i = 0; i < RTUCHANGMSGNUM; i++) { gRtuChangeMsg[i].EMsgLen = 0; if(gRtuChangeMsg[i].MsgLen) { SendDataToAllHostSendBuf((u_char*)&gRtuChangeMsg[i], gRtuChangeMsg[i].MsgLen + sizeof(HOSTMSGHEAD)); gRtuChangeMsg[i].MsgLen = 0; } } } //*************************************************************** //* 发送端口统计到主机数据 * //*************************************************************** void SendPortStatisticsToHost(void) { /* int i, portnum; HOSTMSG MsgBuf; portnum = DEFAULT_MAX_PORT_NUM; MsgBuf.MsgType = WUXI_ZHUANFA_AI_TO_HOST; MsgBuf.PortNumber = MaxPortNum-1; MsgBuf.MsgLen = portnum *20 + 2; MsgBuf.EMsgLen = 0; *(short*)&MsgBuf.MsgData[0] = 0; for(i = 0; i < portnum; i++) { *(float*)&MsgBuf.MsgData[20*i+2] = (float)PortParam[i].MsgNum; *(float*)&MsgBuf.MsgData[20*i+6] = (float)PortParam[i].ErrMsgNum; *(float*)&MsgBuf.MsgData[20*i+10] = (float)PortParam[i].LostSyncCnt; *(float*)&MsgBuf.MsgData[20*i+14] = (float)((PortParam[i].MsgNum != 0) ? (float)PortParam[i].ErrMsgNum / (float)PortParam[i].MsgNum : 0.0); *(float*)&MsgBuf.MsgData[20*i+18] = (float)((PortParam[i].UpTime || PortParam[i].DownTime) ? (float)PortParam[i].UpTime/(float)(PortParam[i].UpTime + PortParam[i].DownTime) : 0.0); } SendDataToAllHostSendBuf((u_char*)&MsgBuf, MsgBuf.MsgLen + sizeof(RTUMSGHEAD)); */ } //*************************************************************** //* 发送端口状态到主机数据 * //*************************************************************** void SendPortStatusToHost(int flag) { int i, portnum; HOSTMSG MsgBuf; SIO_PARAM_DEF *pSioParam; pSioParam = GetSioParamPtr(); portnum = DEFAULT_MAX_PORT_NUM; MsgBuf.MsgType = iLINESTATUS; MsgBuf.PortNumber = 0; MsgBuf.MsgLen = portnum*2; MsgBuf.EMsgLen = 0; for(i = 0; i < portnum; i++) { // 将端口状态复位 pSioParam[i].LineCommCnt++; if ( (((long)pSioParam[i].LineCommCnt*TIMER_CNT)/1000) > 60 ) { pSioParam[i].LineCommCnt = 0; pSioParam[i].Status = FALSE; } // wen 2006.01.14 增加端口偏移 //MsgBuf.MsgData[i*2] = (BYTE)i; MsgBuf.MsgData[i*2] = (BYTE)(i+FendMsg.iPortOffset); MsgBuf.MsgData[i*2+1] = flag ? (pSioParam[i].Status & 0x01) : 0x00; } SendDataToAllHostSendBuf((u_char*)&MsgBuf, MsgBuf.MsgLen + sizeof(HOSTMSGHEAD)); //SendPortStatisticsToHost(); } // wen 2003.01.08 前置机向服务器发送全数据时,提取数据值时,应 // 该判断该值的有效性。这样就不会发生遥信误报警的情况。 //*************************************************************** //* 送端口全数据到主机 * //*************************************************************** void SendPortAllDataToHost(void) { //static int test=0; char szDbg[256]; BOOL bSendFlag; int i; static int sendport = 0, count = 0; HOSTMSG SendAllDataBuf; AI_DEF aipntmsg; DI_DEF dipntmsg; PI_DEF pipntmsg; SIO_PARAM_DEF *pSioParam; //if (WaittingFlag == TRUE) // return; //if (DisbaleWriteAllDataToHostFlag) // return; #ifdef FEND_STANDBY_NOSEND // wen 2003.01.07 前置机为备用机时,不发送全数据给服务器 // 可以省去,因为备用机不做数据处理,其端口状态 PortParam[sendport].Status // 也不会变为TRUE if(!IsSendDatatoPort(-1)) return; #endif count++; if(count * TIMER_CNT < 1000) { return; } count = 0; pSioParam = GetSioParamPtr(); //if(test == 0) //{ // DebugPrint(">>>Enter SendAllData."); // test = 1; //} //else //{ // DebugPrint("<<PortType) { // 端口由停运---转为-->正常,需要有1 分钟来刷行该端口数据 // 否则发送上去的全数据会由于没有完全刷新而出现报警混乱。 // 最严重的后果是遥信报警反复,即我们所说的误报。 //if(pSioParam[sendport].iDelaySendAllData < (60000/TIMER_CNT)) if(pSioParam[sendport].iDelaySendAllData < 60) { pSioParam[sendport].iDelaySendAllData++; } else { bSendFlag = TRUE; break; } } } } else { pSioParam[sendport].iDelaySendAllData = 0; } sendport = (sendport + 1) % DEFAULT_MAX_PORT_NUM; } // test if(pSioParam[sendport].iDelaySendAllData == 60) { sprintf(szDbg, "SendAllData port=%d iDelaySendAllData=%d, bSendFlag=%d, status=%d", sendport, pSioParam[sendport].iDelaySendAllData, bSendFlag, pSioParam[sendport].Status); DebugPrint(szDbg); pSioParam[sendport].iDelaySendAllData++; } sendport = sendport % DEFAULT_MAX_PORT_NUM; //if((i >= DEFAULT_MAX_PORT_NUM) || (FALSE == bSendFlag)) if(FALSE == bSendFlag) { return; } // test //sprintf(szDbg, "SendAllData from port=%d", sendport); //DebugPrint(szDbg); // wen 2005.06.20 传送32bit模拟量数据 if(FendMsg.iSendAiof32Bit) { // 发送全遥测 SendAllDataBuf.MsgType = PGC3_AI32ALLDATA; // wen 2006.01.14 增加端口偏移 //SendAllDataBuf.PortNumber = sendport; SendAllDataBuf.PortNumber = sendport+FendMsg.iPortOffset; SendAllDataBuf.MsgLen = 0; SendAllDataBuf.EMsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = 0; SendAllDataBuf.MsgLen += sizeof(short); for(i = 0; i < pSioParam[sendport].m_psBaoHu->AiNum; i++) { if ((MAX_RTU_MSG_SIZE - SendAllDataBuf.MsgLen) < 8) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = i; SendAllDataBuf.MsgLen += sizeof(short); } if(GetPntMsg(sendport, i, (void *)&aipntmsg, AI_PNT_TYPE, PNT_ALL_MSG) == FALSE) { aipntmsg.RawValue = 0; } *(long*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = (long)aipntmsg.RawValue; SendAllDataBuf.MsgLen += sizeof(long); } if(SendAllDataBuf.MsgLen > sizeof(long)) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; } } else { // 发送全遥测 SendAllDataBuf.MsgType = iAIALLDATA; // wen 2006.01.14 增加端口偏移 //SendAllDataBuf.PortNumber = sendport; SendAllDataBuf.PortNumber = sendport+FendMsg.iPortOffset; SendAllDataBuf.MsgLen = 0; SendAllDataBuf.EMsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = 0; SendAllDataBuf.MsgLen += sizeof(short); for(i = 0; i < pSioParam[sendport].m_psBaoHu->AiNum; i++) { if ((MAX_RTU_MSG_SIZE - SendAllDataBuf.MsgLen) < 8) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = i; SendAllDataBuf.MsgLen += sizeof(short); } if(GetPntMsg(sendport, i, (void *)&aipntmsg, AI_PNT_TYPE, PNT_ALL_MSG) == FALSE) { aipntmsg.RawValue = 0; } //if(abs(aipntmsg.RawValue&0x0000ffff) < aipntmsg.Dead) //{ // pntmsg.RawValue = 0; //} //if(i == 1) //{ // sprintf(szDbg, "SendAllData pnt%d val=%d", i+1, (short)aipntmsg.RawValue); // DebugPrint(szDbg); //} *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = (short)aipntmsg.RawValue; SendAllDataBuf.MsgLen += sizeof(short); } if(SendAllDataBuf.MsgLen > sizeof(short)) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; } } // 发送全遥信 SendAllDataBuf.MsgType = iDIALLDATA; // wen 2006.01.14 增加端口偏移 //SendAllDataBuf.PortNumber = sendport; SendAllDataBuf.PortNumber = sendport+FendMsg.iPortOffset; SendAllDataBuf.MsgLen = 0; SendAllDataBuf.EMsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = 0; SendAllDataBuf.MsgLen += sizeof(short); for(i = 0; i < pSioParam[sendport].m_psBaoHu->DiNum; i++) { if ((MAX_RTU_MSG_SIZE - SendAllDataBuf.MsgLen) < 8) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = i; SendAllDataBuf.MsgLen += sizeof(short); } if(GetPntMsg(sendport, i, (void *)&dipntmsg, DI_PNT_TYPE, PNT_STATUS) == FALSE) { dipntmsg.Status = 0; } SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = dipntmsg.Status & 0x01; SendAllDataBuf.MsgLen += sizeof(char); } if (SendAllDataBuf.MsgLen > sizeof(short)) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; } /* // 发送全离线遥信 SendAllDataBuf.MsgType = iODALLDATA; // wen 2006.01.14 增加端口偏移 //SendAllDataBuf.PortNumber = sendport; SendAllDataBuf.PortNumber = sendport+FendMsg.iPortOffset; SendAllDataBuf.MsgLen = 0; SendAllDataBuf.EMsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = 0; SendAllDataBuf.MsgLen += sizeof(short); for(i = 0; i < min(PortParam[sendport].RevOdNum, MAX_OD_NUM); i++) { if ((MAX_RTU_MSG_SIZE - SendAllDataBuf.MsgLen) < 8) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(RTUMSGHEAD)); SendAllDataBuf.MsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = i; SendAllDataBuf.MsgLen += sizeof(short); } if (GetPntMsg(sendport, i, &pntmsg, OD_PNT_TYPE, PNT_STATUS) == FALSE) pntmsg.Status = 0; SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = pntmsg.Status & 0x01; SendAllDataBuf.MsgLen += sizeof(char); } if (SendAllDataBuf.MsgLen > sizeof(short)) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(RTUMSGHEAD)); SendAllDataBuf.MsgLen = 0; } */ // 发送全电度 SendAllDataBuf.MsgType = iPIALLDATA; // wen 2006.01.14 增加端口偏移 //SendAllDataBuf.PortNumber = sendport; SendAllDataBuf.PortNumber = sendport+FendMsg.iPortOffset; SendAllDataBuf.MsgLen = 0; SendAllDataBuf.EMsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = 0; SendAllDataBuf.MsgLen += sizeof(short); for(i = 0; i < pSioParam[sendport].m_psBaoHu->PiNum; i++) { if((MAX_RTU_MSG_SIZE - SendAllDataBuf.MsgLen) < 8) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; *(short*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = i; SendAllDataBuf.MsgLen += sizeof(short); } if(GetPntMsg(sendport, i, (void *)&pipntmsg, PI_PNT_TYPE, PNT_RAWVALUE) == FALSE) { pipntmsg.RawValue = 0; } *(u_long*)&SendAllDataBuf.MsgData[SendAllDataBuf.MsgLen] = pipntmsg.RawValue; SendAllDataBuf.MsgLen += sizeof(long); } if(SendAllDataBuf.MsgLen > sizeof(short)) { SendDataToAllHostSendBuf((u_char*)&SendAllDataBuf, SendAllDataBuf.MsgLen + sizeof(HOSTMSGHEAD)); SendAllDataBuf.MsgLen = 0; } sendport = (sendport + 1) % DEFAULT_MAX_PORT_NUM; } //*************************************************************** //* 填充 SOE 数据缓冲区 * //*************************************************************** void SetSoeData(int commidex, SOE_DEF *pSoeData) { int commid; // wen 2006.01.14 增加端口偏移 commid = commidex + FendMsg.iPortOffset; gRtuChangeMsg[SOEMSGNO].MsgType = iSOEDATA; gRtuChangeMsg[SOEMSGNO].EMsgLen = 0; if((gRtuChangeMsg[SOEMSGNO].PortNumber != commid) && gRtuChangeMsg[SOEMSGNO].MsgLen ) { SendDataToAllHostSendBuf((u_char*)&gRtuChangeMsg[SOEMSGNO], gRtuChangeMsg[SOEMSGNO].MsgLen + sizeof(HOSTMSGHEAD)); gRtuChangeMsg[SOEMSGNO].MsgLen = 0; } gRtuChangeMsg[SOEMSGNO].PortNumber = commid; gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = LOBYTE(pSoeData->iPntNo); // point low gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = HIBYTE(pSoeData->iPntNo); // point high gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = pSoeData->bStatus; // Status gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = LOBYTE(pSoeData->SoeTime.mSec); // ms low gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = HIBYTE(pSoeData->SoeTime.mSec); // ms high gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = (BYTE)pSoeData->SoeTime.Sec; // sec gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = (BYTE)pSoeData->SoeTime.Min; // min gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = (BYTE)pSoeData->SoeTime.Hour; // hour gRtuChangeMsg[SOEMSGNO].MsgData[gRtuChangeMsg[SOEMSGNO].MsgLen++] = (BYTE)pSoeData->SoeTime.Day; // day } //*************************************************************** //* 填充 遥控遥调返校 数据缓冲区 * //*************************************************************** void SetYkYtAckData( int portno, char *buf ) { int port; // wen 2006.01.14 增加端口偏移 //port = portno; port = portno+FendMsg.iPortOffset; gRtuChangeMsg[YKYTACKNO].MsgType = iACKDATA; gRtuChangeMsg[YKYTACKNO].EMsgLen = 0; if((gRtuChangeMsg[YKYTACKNO].PortNumber != port) && gRtuChangeMsg[YKYTACKNO].MsgLen ) { SendDataToAllHostSendBuf((u_char*)&gRtuChangeMsg[YKYTACKNO], gRtuChangeMsg[YKYTACKNO].MsgLen + sizeof(HOSTMSGHEAD)); gRtuChangeMsg[YKYTACKNO].MsgLen = 0; } gRtuChangeMsg[YKYTACKNO].PortNumber = port; gRtuChangeMsg[YKYTACKNO].MsgData[gRtuChangeMsg[YKYTACKNO].MsgLen++] = buf[0];// Point Low gRtuChangeMsg[YKYTACKNO].MsgData[gRtuChangeMsg[YKYTACKNO].MsgLen++] = buf[1];// Point High gRtuChangeMsg[YKYTACKNO].MsgData[gRtuChangeMsg[YKYTACKNO].MsgLen++] = buf[2];// 返校码 } void SelectHostSocketEvent(void) { struct timeval timeout; int i, inum, nfds; fd_set fdset_ro, fdset_wr, fdset_ex; inum = 0; nfds = 0; FD_ZERO(&fdset_ro); FD_ZERO(&fdset_wr); FD_ZERO(&fdset_ex); for(i=0; i 0) { memset((char*)&timeout, 0, sizeof(struct timeval)); // wen 2005.07.08 设置超时等待时间 //timeout.tv_usec = 200; if(select(nfds+1, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1) { return; } for(i=0; i>> %02d:%02d:%02d.%03d\n", // sm.Hour, sm.Min, sm.Sec, sm.mSec); //DebugPrint(szDbg); // 连接 LinkToHost(); // 连接是否成功以及对有效端口数据接收 //SelectHostSocketEvent(); SelectHostSocketEventEx(); // 发送数据 SendHostSendBufToHost(); // 发送端口状态 SendPortStatusToHost(1); // 发送全数据 SendPortAllDataToHost(); // 2006.01.13 增加前置机到服务器的对时功能 SendSystemTimeToHost(); } //*************************************************************** //* 向主机请求模拟量 * //*************************************************************** void MapAnPointToHost(int iMapOutPort, int iMapSavePort) { int i; HOSTMSG MapPointBuf; PROV_AI_PNT *pProvAi; SIO_PARAM_DEF *pSioParam; if((iMapOutPort < 1) || (iMapSavePort < 1)) { return; } pSioParam = GetSioParamPtr(); MapPointBuf.MsgType = iANPOINT; MapPointBuf.PortNumber = 0; MapPointBuf.MsgLen = 0; pProvAi = (PROV_AI_PNT *)pSioParam[iMapOutPort].m_psBaoHu->AiPtr; for(i = 0; i < pSioParam[iMapOutPort].m_psBaoHu->AiNum; i++) { if(pProvAi[i].Enable == 0) { continue; } MapPointBuf.MsgData[MapPointBuf.MsgLen++] = (u_char)pProvAi[i].wType; MapPointBuf.MsgData[MapPointBuf.MsgLen++] = (u_char)pProvAi[i].PortNo; *(short*)&MapPointBuf.MsgData[MapPointBuf.MsgLen] = pProvAi[i].PntNo; MapPointBuf.MsgLen += 2; } SendDataToAllHostSendBuf((u_char*)&MapPointBuf, MapPointBuf.MsgLen + sizeof(HOSTMSGHEAD)); } //*************************************************************** //* 向主机请求状态量 * //*************************************************************** void MapDiPointToHost(int iMapOutPort, int iMapSavePort) { int i; HOSTMSG MapPointBuf; PROV_DI_PNT *pProvDi; SIO_PARAM_DEF *pSioParam; if((iMapOutPort < 1) || (iMapSavePort < 1)) { return; } pSioParam = GetSioParamPtr(); MapPointBuf.MsgType = iDIPOINT; MapPointBuf.PortNumber = 0; MapPointBuf.MsgLen = 0; pProvDi = (PROV_DI_PNT *)pSioParam[iMapOutPort].m_psBaoHu->DiPtr; for(i = 0; i < pSioParam[iMapOutPort].m_psBaoHu->DiNum; i++) { if(pProvDi[i].Enable == 0) { continue; } // 主机离线量点为 'X' 类型 MapPointBuf.MsgData[MapPointBuf.MsgLen++] = (u_char)(pProvDi[i].wType == 'o' ? 'x' : pProvDi[i].wType); MapPointBuf.MsgData[MapPointBuf.MsgLen++] = (u_char)pProvDi[i].PortNo; *(short*)&MapPointBuf.MsgData[MapPointBuf.MsgLen] = pProvDi[i].PntNo; MapPointBuf.MsgLen += 2; } SendDataToAllHostSendBuf((u_char*)&MapPointBuf, MapPointBuf.MsgLen + sizeof(HOSTMSGHEAD)); } //*************************************************************** //* 主机模拟盘数据处理 * //*************************************************************** void FormHostMapDataProce(int iMapOutPort, int iMapSavePort, HOSTMSG *msg) { int i, j, iDataNum; float anval; AI_DEF aipmsg; DI_DEF dipmsg; PROV_AI_PNT *pProvAi; PROV_DI_PNT *pProvDi; SIO_PARAM_DEF *pSioParam; if((iMapOutPort < 1) || (iMapSavePort < 1)) { return; } pSioParam = GetSioParamPtr(); if(msg->MsgType == hMAPANDATA) { pProvAi = (PROV_AI_PNT *)pSioParam[iMapOutPort].m_psBaoHu->AiPtr; iDataNum = pSioParam[iMapOutPort].m_psBaoHu->AiNum; for(i=j=0; (i < iDataNum) && ((j+4) <= (int)msg->MsgLen); i++) { if(pProvAi[i].Enable == 0) { continue; } anval = *(float*)&msg->MsgData[j]; j += 4; aipmsg.RawValue = (int)(anval * pProvAi[i].fFactor); SetPntMsg(iMapSavePort-1, i, (void *)&aipmsg, AI_PNT_TYPE, PNT_RAWVALUE); } } else if(msg->MsgType == hMAPDIDATA) { pProvDi = (PROV_DI_PNT *)pSioParam[iMapOutPort].m_psBaoHu->DiPtr; iDataNum = pSioParam[iMapOutPort].m_psBaoHu->DiNum; for(i=j=0; (i < iDataNum) && (j < (int)msg->MsgLen); i++, j++) { if(pProvDi[i].Enable == 0) { continue; } dipmsg.Status = (msg->MsgData[j] & 0x01); SetPntMsg(iMapSavePort-1, i, (void *)&dipmsg, DI_PNT_TYPE, PNT_STATUS); } } } int GetFendTxdFlag(void) { // wen 2006.04.26 如果为并列运行,则下发标识为真 if(RUN_MODE_ALLHOT == FendMsg.iRunMode) { return TRUE; } return FendMsg.SendTxdDataFlag[FendMsg.FendIdx]; } int CheckIsFendIpAddr(u_long addr) { int i; bool bRetVal; u_long uFendAddr; bRetVal = false; for(i=0; iRawValue; pRtuChangeMsg[AIMSGNO].MsgLen += sizeof(long); break; } // 传送16bit模拟量数据 aiptr = (AI_DEF *)pntmsg; pRtuChangeMsg[AIMSGNO].MsgType = iAIDATA; pRtuChangeMsg[AIMSGNO].EMsgLen = 0; if((pRtuChangeMsg[AIMSGNO].PortNumber != commid) && pRtuChangeMsg[AIMSGNO].MsgLen) { SendDataToAllHostSendBuf((u_char*)&pRtuChangeMsg[AIMSGNO], pRtuChangeMsg[AIMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[AIMSGNO].MsgLen = 0; } pRtuChangeMsg[AIMSGNO].PortNumber = commid; if ((MAX_RTU_MSG_SIZE - pRtuChangeMsg[AIMSGNO].MsgLen) < 12) { SendDataToAllHostSendBuf((u_char*)&pRtuChangeMsg[AIMSGNO], pRtuChangeMsg[AIMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[AIMSGNO].MsgLen = 0; } *(short*)&(pRtuChangeMsg[AIMSGNO].MsgData[pRtuChangeMsg[AIMSGNO].MsgLen]) = point; pRtuChangeMsg[AIMSGNO].MsgLen += sizeof(short); *(short*)&(pRtuChangeMsg[AIMSGNO].MsgData[pRtuChangeMsg[AIMSGNO].MsgLen]) = (short)(aiptr->RawValue & 0x0000ffff); pRtuChangeMsg[AIMSGNO].MsgLen += sizeof(short); // test //if(point == 1) //{ // sprintf(szDbg, "AIChange: pnt=%d val=%d", point, (short)(aiptr->RawValue & 0x0000ffff)); // DebugPrint(szDbg); //} break; case DI_PNT_TYPE: diptr = (DI_DEF *)pntmsg; //if(PortParam[port].SoeInsertFlag) // MakeSoeData(port, point, pntmsg->Status & 0x01); pRtuChangeMsg[DIMSGNO].MsgType = iDIDATA; pRtuChangeMsg[DIMSGNO].EMsgLen = 0; if ((pRtuChangeMsg[DIMSGNO].PortNumber != commid) && pRtuChangeMsg[DIMSGNO].MsgLen) { SendDataToAllHostSendBuf((u_char*)&pRtuChangeMsg[DIMSGNO], pRtuChangeMsg[DIMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[DIMSGNO].MsgLen = 0; } pRtuChangeMsg[DIMSGNO].PortNumber = commid; if ((MAX_RTU_MSG_SIZE - pRtuChangeMsg[DIMSGNO].MsgLen) < 12) { SendDataToAllHostSendBuf((u_char *)&pRtuChangeMsg[DIMSGNO], pRtuChangeMsg[DIMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[DIMSGNO].MsgLen = 0; } *(short*)&(pRtuChangeMsg[DIMSGNO].MsgData[pRtuChangeMsg[DIMSGNO].MsgLen]) = point; pRtuChangeMsg[DIMSGNO].MsgLen += sizeof(short); pRtuChangeMsg[DIMSGNO].MsgData[pRtuChangeMsg[DIMSGNO].MsgLen] = diptr->Status & 0x01; pRtuChangeMsg[DIMSGNO].MsgLen += sizeof(BYTE); break; case OD_PNT_TYPE: /* pRtuChangeMsg[ODMSGNO].MsgType = iODDATA; pRtuChangeMsg[ODMSGNO].EMsgLen = 0; if ((pRtuChangeMsg[ODMSGNO].PortNumber != commid) && pRtuChangeMsg[ODMSGNO].MsgLen) { SendDataToAllHostSendBuf((u_char*)&pRtuChangeMsg[ODMSGNO], pRtuChangeMsg[ODMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[ODMSGNO].MsgLen = 0; } pRtuChangeMsg[ODMSGNO].PortNumber = commid; if ((MAX_RTU_MSG_SIZE - pRtuChangeMsg[ODMSGNO].MsgLen) < 12) { SendDataToAllHostSendBuf((u_char*)&pRtuChangeMsg[ODMSGNO], pRtuChangeMsg[ODMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[ODMSGNO].MsgLen = 0; } *(short*)&(pRtuChangeMsg[ODMSGNO].MsgData[pRtuChangeMsg[ODMSGNO].MsgLen]) = point; pRtuChangeMsg[ODMSGNO].MsgLen += sizeof(short); pRtuChangeMsg[ODMSGNO].MsgData[pRtuChangeMsg[ODMSGNO].MsgLen] = pntmsg->Status & 0x01; pRtuChangeMsg[ODMSGNO].MsgLen += sizeof(BYTE); */ break; case PI_PNT_TYPE: piptr = (PI_DEF *)pntmsg; pRtuChangeMsg[PIMSGNO].MsgType = iPIDATA; pRtuChangeMsg[PIMSGNO].EMsgLen = 0; if ((pRtuChangeMsg[PIMSGNO].PortNumber != commid) && pRtuChangeMsg[PIMSGNO].MsgLen) { SendDataToAllHostSendBuf((u_char*)&pRtuChangeMsg[PIMSGNO], pRtuChangeMsg[PIMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[PIMSGNO].MsgLen = 0; } pRtuChangeMsg[PIMSGNO].PortNumber = commid; if ((MAX_RTU_MSG_SIZE - pRtuChangeMsg[PIMSGNO].MsgLen) < 12) { SendDataToAllHostSendBuf((u_char*)&pRtuChangeMsg[PIMSGNO], pRtuChangeMsg[PIMSGNO].MsgLen + sizeof(RTUMSGHEAD)); pRtuChangeMsg[PIMSGNO].MsgLen = 0; } *(short*)&(pRtuChangeMsg[PIMSGNO].MsgData[pRtuChangeMsg[PIMSGNO].MsgLen]) = point; pRtuChangeMsg[PIMSGNO].MsgLen += sizeof (short); *(u_long*)&(pRtuChangeMsg[PIMSGNO].MsgData[pRtuChangeMsg[PIMSGNO].MsgLen]) = piptr->RawValue; pRtuChangeMsg[PIMSGNO].MsgLen += sizeof (long); break; } //WriteProvChangeData(pntmsg, type); } // 判断该端口是否下发数据 BOOL IsSendDatatoPort(int port) { FEND_DEF *pFendMsg; SIO_PARAM_DEF *pSioParam; //char szDbg[256]; //static int test=0; BOOL bReturn = TRUE; #ifdef PC_MACHINE // 该条件仅仅在windows模拟环境中有效 #if (FEND_OTHERDEV_DS3116 == 1) return TRUE; #endif #endif //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // wen 2006.01.14 增加并列运行方式 /* pFendMsg = GetFendMsgPtr(); if(port < 0) { if(pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] == FALSE) { bReturn = FALSE; } } else { pSioParam = GetSioParamPtr(); switch(pSioParam[port].iForceSendFlag) { case 1:// 强制下发 //bReturn = TRUE; break; case 2:// 强制不下发 bReturn = FALSE; break; case 0:// 正常情况下 default: // 本前置机不属于主前置机 if(pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] == FALSE) { bReturn = FALSE; } break; } } */ //================================================================================ pFendMsg = GetFendMsgPtr(); if(port < 0) { if(RUN_MODE_ALLHOT == pFendMsg->iRunMode) { bReturn = TRUE; } else if(pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] == FALSE) { bReturn = FALSE; } } else { pSioParam = GetSioParamPtr(); switch(pSioParam[port].iForceSendFlag) { case 1:// 强制下发 //bReturn = TRUE; break; case 2:// 强制不下发 bReturn = FALSE; break; case 0:// 正常情况下 default: // 本前置机不属于主前置机 if(RUN_MODE_ALLHOT == pFendMsg->iRunMode) { bReturn = TRUE; } else if(pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] == FALSE) { bReturn = FALSE; } break; } } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // 两个地方调用,时钟周期为20ms,20×200=4000ms÷2=2s //if(test == 200) //{ // sprintf(szDbg, "port=%d, SendTxd=%d", port, bReturn); // DebugPrint(szDbg); // test = 0; //} //else //{ // test++; //} return bReturn; } TCP_LINK_DEF *GetHostLinkPtr() { return HostLink; } FEND_DEF *GetFendMsgPtr() { return &FendMsg; } HOSTMSG *GetRtuChangeMsgPtr() { return gRtuChangeMsg; } #if 0 //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // 增加字节顺序转换函数 BOOL AllDataHostToRtuByteSequence(HOSTMSG *hmsg, ORTUMSG *pSendMsg) { int i; BOOL bRetVal; WORD *pWord, *pwSour; int *piSour, *piDest; long *plSour, *plDest; float *pfSour, *pfDest; SYSTEMTIME *pTime; bRetVal = TRUE; switch(hmsg->MsgType) { case iREQUESTHOSTSTATUS:// 请求主机状态 bRetVal = FALSE; break; case iTIMEINFORM: // 前置机对时 pTime = (SYSTEMTIME*)hmsg->MsgData; pWord = (WORD *)pSendMsg->MsgData; pWord[0] = SequenceHostToRtuWord(pTime->wYear); pWord[1] = SequenceHostToRtuWord(pTime->wMonth); pWord[2] = SequenceHostToRtuWord(pTime->wDay); pWord[3] = SequenceHostToRtuWord(pTime->wHour); pWord[4] = SequenceHostToRtuWord(pTime->wMinute); pWord[5] = SequenceHostToRtuWord(pTime->wSecond); pWord[6] = SequenceHostToRtuWord(pTime->wMilliseconds); break; case iAIDATA: // 变化遥测 case iAIALLDATA: // 遥测全数据 pWord = (WORD *)pSendMsg->MsgData; pwSour = (WORD *)hmsg->MsgData; for(i=0; iMsgLen; i+=2) { if((i+2) > hmsg->MsgLen) { break; } pWord[i/2] = SequenceHostToRtuWord(pwSour[i/2]); } break; // wen 2006.05.20 32bit传送模拟量数据(和电度量传送格式一致) case PGC3_AI32DATA: // 变化32位遥测数据 for(i=0; iMsgLen; i+=6) { if((i+6) > hmsg->MsgLen) { break; } pWord = (WORD *)&pSendMsg->MsgData[i]; pwSour = (WORD *)&hmsg->MsgData[i]; *pWord = SequenceHostToRtuWord(*pwSour); plDest = (long *)&pSendMsg->MsgData[i+2]; plSour = (long *)&hmsg->MsgData[i+2]; *plDest = SequenceHostToRtulong(*plSour); } break; case PGC3_AI32ALLDATA: // 遥测32位全数据 pWord = (WORD *)&pSendMsg->MsgData; pwSour = (WORD *)&hmsg->MsgData; *pWord = SequenceHostToRtuWord(*pwSour); plDest = (long *)&pSendMsg->MsgData[2]; plSour = (long *)&hmsg->MsgData[2]; for(i=2; iMsgLen; i+=4) { if((i+4) > hmsg->MsgLen) { break; } plDest[(i-2)/4] = SequenceHostToRtulong(plSour[(i-2)/4]); } break; case iDIDATA: // 变化遥信 case iODDATA: // 离线遥信数据 for(i=0; iMsgLen; i+=3) { if((i+3) > hmsg->MsgLen) { break; } pWord = (WORD *)&pSendMsg->MsgData[i]; pwSour = (WORD *)&hmsg->MsgData[i]; // wen 2006.05.20 修改遥信变化数据字节转换的bug,应该为WORD类型 //*pWord = SequenceHostToRtuDWord(*pwSour); *pWord = SequenceHostToRtuWord(*pwSour); pSendMsg->MsgData[i+2] = hmsg->MsgData[i+2]; } break; case iPIDATA: // 变化电度 for(i=0; iMsgLen; i+=6) { if((i+6) > hmsg->MsgLen) { break; } pWord = (WORD *)&pSendMsg->MsgData[i]; pwSour = (WORD *)&hmsg->MsgData[i]; *pWord = SequenceHostToRtuWord(*pwSour); plDest = (long *)&pSendMsg->MsgData[i+2]; plSour = (long *)&hmsg->MsgData[i+2]; *plDest = SequenceHostToRtulong(*plSour); } break; case iSOEDATA: // SOE 数据 memcpy(pSendMsg->MsgData, hmsg->MsgData, hmsg->MsgLen); break; case iACKDATA: // 遥控遥调返校 memcpy(pSendMsg->MsgData, hmsg->MsgData, hmsg->MsgLen); break; case WUXI_ZHUANFA_AI_TO_HOST: pfDest = (float *)pSendMsg->MsgData; pfSour = (float *)hmsg->MsgData; for(i=0; iMsgLen; i+=4) { if((i+4) > hmsg->MsgLen) { break; } *pfDest = SequenceHostToRtufloat(*pfSour); } break; case WUXI_ZHUANFA_PI_TO_HOST: memcpy(pSendMsg->MsgData, hmsg->MsgData, hmsg->MsgLen); break; case iODALLDATA: // 离线遥信全数据 memcpy(pSendMsg->MsgData, hmsg->MsgData, hmsg->MsgLen); break; case iWUFANGYKYTREQ: // 五防遥控遥调请求 for(i=0; iMsgLen; i+=8) { if((i+8) > hmsg->MsgLen) { break; } pWord = (WORD *)&pSendMsg->MsgData[i]; pwSour = (WORD *)&hmsg->MsgData[i]; pWord[0] = SequenceHostToRtuWord(pwSour[0]); pWord[1] = SequenceHostToRtuWord(pwSour[1]); piDest = (int *)&pSendMsg->MsgData[i+4]; piSour = (int *)&hmsg->MsgData[i+4]; *piDest = SequenceHostToRtuint(*piSour); } break; case iDIALLDATA: // 遥信全数据 pWord = (WORD *)&pSendMsg->MsgData; pwSour = (WORD *)&hmsg->MsgData; *pWord = SequenceHostToRtuWord(*pwSour); memcpy(&pSendMsg->MsgData[2], &hmsg->MsgData[2], hmsg->MsgLen-2); break; case iPIALLDATA: // 电度全数据 pWord = (WORD *)&pSendMsg->MsgData; pwSour = (WORD *)&hmsg->MsgData; *pWord = SequenceHostToRtuWord(*pwSour); plDest = (long *)&pSendMsg->MsgData[2]; plSour = (long *)&hmsg->MsgData[2]; for(i=2; iMsgLen; i+=4) { if((i+4) > hmsg->MsgLen) { break; } plDest[(i-2)/4] = SequenceHostToRtulong(plSour[(i-2)/4]); } break; case iBYPASSDATA: // 直通数据 memcpy(pSendMsg->MsgData, hmsg->MsgData, hmsg->MsgLen); break; case iODPOINT: // 读离线量点数据 memcpy(pSendMsg->MsgData, hmsg->MsgData, hmsg->MsgLen); break; case iANPOINT: // 读模拟量点数据 case iDIPOINT: // 读数字量点数据 for(i=0; iMsgLen; i+=4) { if((i+4) > hmsg->MsgLen) { break; } pSendMsg->MsgData[i] = hmsg->MsgData[i]; pSendMsg->MsgData[i+1] = hmsg->MsgData[i+1]; pWord = (WORD *)&pSendMsg->MsgData[i+2]; pwSour = (WORD *)&hmsg->MsgData[i+2]; *pWord = SequenceHostToRtuWord(*pwSour); } break; case iLINESTATUS: // 端口线路状态 memcpy(pSendMsg->MsgData, hmsg->MsgData, hmsg->MsgLen); break; case iNETTESTMSG: // 网络状态包 break; case iNETNAMEPLATE: // 网络标示包 pSendMsg->MsgData[0] = hmsg->MsgData[0]; pWord = (WORD *)&pSendMsg->MsgData[1]; pwSour = (WORD *)&hmsg->MsgData[1]; *pWord = SequenceHostToRtuWord(*pwSour); break; default: bRetVal = FALSE; break; } if(bRetVal == TRUE) { pSendMsg->MsgType = (BYTE)hmsg->MsgType; pSendMsg->PortNumber = (BYTE)hmsg->PortNumber; pSendMsg->MsgLen = SequenceHostToRtuWord(hmsg->MsgLen); } return bRetVal; } BOOL AllDataRtuToHostByteSequence(HOSTMSG *hmsg) { int i; BOOL bRetVal; SYSTEMTIME *pTime; bRetVal = TRUE; switch(hmsg->MsgType) { case hHOSTSTATUS: // 主机状态 for(i = 0; i < MAX_HOST; i++) { SequenceRtuToHost((char *)&hmsg->MsgData[i*sizeof(int)], sizeof(int)); } break; case NET_PROFILE_UPDATE: // 主机下发更改数据库指令 break; case hTIMEINFORM: // 主机对时 pTime = (SYSTEMTIME*)hmsg->MsgData; pTime->wYear = SequenceRtuToHostWord(pTime->wYear); pTime->wMonth = SequenceRtuToHostWord(pTime->wMonth); pTime->wDay = SequenceRtuToHostWord(pTime->wDay); pTime->wHour = SequenceRtuToHostWord(pTime->wHour); pTime->wMinute = SequenceRtuToHostWord(pTime->wMinute); pTime->wSecond = SequenceRtuToHostWord(pTime->wSecond); pTime->wMilliseconds = SequenceRtuToHostWord(pTime->wMilliseconds); break; case hYKYTCMD: // 遥控遥调命令 if(hmsg->MsgLen >= 10) // 多条遥调遥控命令 { // ??? 多帧的结构 SequenceRtuToHost((char *)&hmsg->MsgData[1], 2); } else { // 遥控遥调反校失败 SequenceRtuToHost((char *)&hmsg->MsgData[1], 2); } break; case hBYPASSCMD: // 直通数据 break; case hMAPANDATA: // 模拟量点数据 for(i=0; i<(int)hmsg->MsgLen; i+=4) { SequenceRtuToHost((char *)&hmsg->MsgData[i], sizeof(float)); } break; case hMAPDIDATA: // 数字量点数据 break; case hDATA_OUTPUT_CTRL: // 数据输出控制 break; case hRELOADDATABASE: // 重新装入数据库 break; case hNETTESTMSG: // 网络状态包 break; case hMAPALLOP: // 模拟盘全盘操作 switch( hmsg->MsgData[0] ) { case 0: // 全屏操作 SequenceRtuToHost((char *)&hmsg->MsgData[1], sizeof(DWORD)); break; case 1: // 单点遥测操作 SequenceRtuToHost((char *)&hmsg->MsgData[1], sizeof(WORD)); SequenceRtuToHost((char *)&hmsg->MsgData[3], sizeof(float)); break; case 2: // 单点遥信操作 SequenceRtuToHost((char *)&hmsg->MsgData[1], sizeof(WORD)); break; } break; default: bRetVal = FALSE; break; } return bRetVal; } //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ void SendSystemTimeToHost(void) { static WORD tmpm = 0; DAY_TIME CurTime; HOSTMSG rtumsg; if((SystemTimeFlag == 0) || (SystemTimeMode != 3)) { return; } GetLocalTimeEx(&CurTime); if(CurTime.Sec) { return; } if(tmpm == CurTime.Min) { return; } tmpm = CurTime.Min; *(WORD*)&rtumsg.MsgData[0] = CurTime.Year; *(WORD*)&rtumsg.MsgData[2] = CurTime.Month; *(WORD*)&rtumsg.MsgData[4] = 0; *(WORD*)&rtumsg.MsgData[6] = CurTime.Day; *(WORD*)&rtumsg.MsgData[8] = CurTime.Hour; *(WORD*)&rtumsg.MsgData[10] = CurTime.Min; *(WORD*)&rtumsg.MsgData[12] = CurTime.Sec; *(WORD*)&rtumsg.MsgData[14] = CurTime.mSec; rtumsg.MsgType = iTIMEINFORM; rtumsg.PortNumber = 0; rtumsg.MsgLen = 16; SendDataToAllHostSendBuf( (u_char*)&rtumsg, rtumsg.MsgLen + sizeof(HOSTMSGHEAD)); } #endif