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

3221 lines
77 KiB
C++

This file contains ambiguous Unicode characters!

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

/************************************************************************************
*
* 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; (i<MAX_ADDR) && (j<MAX_NET_NUM); j++)
{
FendMsg.TcpIpAddr[i][0] = 0x00;
// 判断是否前置机IP地址(针对于ds-3116的3地址的情况)
if(false == CheckIsFendIpAddr(HostIpAddr.AllIpAddr[j]))
{
continue;
}
ULongToIPString(FendMsg.TcpIpAddr[i], HostIpAddr.AllIpAddr[j]);
//DebugPrint(FendMsg.TcpIpAddr[i]);
FendMsg.AllIpAddr[i] = HostIpAddr.AllIpAddr[j];
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;
}
i++;
}
for(i = 0; i < (int)strlen(FendMsg.Name); i++)
{
FendMsg.Name[i] = toupper(FendMsg.Name[i]);
}
return TRUE;
}
BOOL InitFendMsg(void)
{
int i, j;
struct hostent *test;
struct in_addr *addr, inaddr;
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.LinkFlag = GetPrivateProInt("前置机", "前置机连接", 2, InitFileName) % 3;
FendMsg.LinkFlag = 2;
FendMsg.EnableLink = GetPrivateProInt("前置机", "允许前置机连接", 1, InitFileName);
FendMsg.EnableLink = FendMsg.EnableLink ? 1 : 0;
gethostname(FendMsg.Name, 100);
test = gethostbyname(FendMsg.Name);
for(i = 0; i < MAX_ADDR; i++)
{
FendMsg.TcpIpAddr[i][0] = 0x00;
addr = (struct in_addr *)test->h_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("<<<Enter SendAllData.");
// test = 0;
//}
bSendFlag = FALSE;
for(i = 0; i < DEFAULT_MAX_PORT_NUM; i++)
{
if(pSioParam[sendport].Status)
{
if(pSioParam[sendport].m_psBaoHu)
{
if(PROTOCOL_MASTER == pSioParam[sendport].m_psBaoHu->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<MAX_HOST; i++)
{
if(INVALID_SOCKET == HostLink[i].SocketId)
{
continue;
}
inum++;
FD_SET(HostLink[i].SocketId, &fdset_ro);
FD_SET(HostLink[i].SocketId, &fdset_wr);
FD_SET(HostLink[i].SocketId, &fdset_ex);
if((u_32)nfds < HostLink[i].SocketId)
{
nfds = HostLink[i].SocketId;
}
}
if(inum > 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<MAX_HOST; i++)
{
if(INVALID_SOCKET == HostLink[i].SocketId)
{
continue;
}
// 首先判断socket是否异常
if(FD_ISSET(HostLink[i].SocketId, &fdset_ex))
{
CloseHostSocket(HostLink[i].SocketId, ERROR_CLOSE_NET);
continue;
}
if(TRUE == HostLink[i].InitOk)
{
// socket可读
if(FD_ISSET(HostLink[i].SocketId, &fdset_ro))
{
// 将该socket中的数据读完
/*
if(ReadHost(i) == FALSE)
{
// 端口已经关闭
CloseHostSocket(HostLink[i].SocketId, HOST_CLOSE_NET);
continue;
}
else
{
ReadDataFormHost(HostLink[i].SocketId);
}
*/
if(ReadDataFormHost(HostLink[i].SocketId) == FALSE)
{
// 关闭SOCKET端口
CloseHostSocket(HostLink[i].SocketId, HOST_CLOSE_NET);
continue;
}
}
}
// socket可写
if(FALSE == HostLink[i].InitOk)
{
if(FD_ISSET(HostLink[i].SocketId, &fdset_wr))
{
HostConnect(HostLink[i].SocketId, 0);
}
}
}
}
}
void SelectHostSocketEventEx(void)
{
struct timeval timeout;
int i, nfds;//, retval
fd_set fdset_ro, fdset_wr, fdset_ex;
int _err = 0;
int _err_len = sizeof(_err);
for(i=0; i<MAX_HOST; i++)
{
if(INVALID_SOCKET == HostLink[i].SocketId)
{
continue;
}
FD_ZERO(&fdset_ro);
FD_ZERO(&fdset_wr);
FD_ZERO(&fdset_ex);
FD_SET(HostLink[i].SocketId, &fdset_ro);
FD_SET(HostLink[i].SocketId, &fdset_wr);
FD_SET(HostLink[i].SocketId, &fdset_ex);
nfds = HostLink[i].SocketId+1;
memset((char*)&timeout, 0, sizeof(struct timeval));
// wen 2005.07.08 设置超时等待时间
//timeout.tv_usec = 200;
if(TRUE == HostLink[i].InitOk)
{
if(select(nfds, &fdset_ro, &fdset_wr, &fdset_ex, &timeout) < 1)
{
continue;
}
}
else
{
if(select(nfds, NULL, &fdset_wr, &fdset_ex, &timeout) < 1)
{
continue;
}
}
#ifdef OS_WINDOWS
// 首先判断socket是否异常
if(FD_ISSET(HostLink[i].SocketId, &fdset_ex))
{
CloseHostSocket(HostLink[i].SocketId, ERROR_CLOSE_NET);
continue;
}
#endif
if(TRUE == HostLink[i].InitOk)
{
// socket可读
if(FD_ISSET(HostLink[i].SocketId, &fdset_ro))
{
if(ReadDataFormHost(HostLink[i].SocketId) == FALSE)
{
// 关闭SOCKET端口
CloseHostSocket(HostLink[i].SocketId, HOST_CLOSE_NET);
continue;
}
}
}
// socket可写
if(FALSE == HostLink[i].InitOk)
{
if(FD_ISSET(HostLink[i].SocketId, &fdset_wr))
{
//#ifdef OS_WINDOWS
HostConnect(HostLink[i].SocketId, 0);
/*#else
retval = getsockopt(HostLink[i].SocketId, SOL_SOCKET, SO_ERROR, (char *)&_err, &_err_len);
if((0 == retval) && (_err == 0))
{
HostConnect(HostLink[i].SocketId, 0);
}
else
{
CloseHostSocket(HostLink[i].SocketId, ERROR_CLOSE_NET);
}
#endif*/
}
}
}
}
void TcpHostTimer(void)
{
//DAY_TIME sm;
//char szDbg[256];
//GetLocalTimeEx(&sm);
//sprintf(szDbg, "Begin>>> %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; i<MAX_FEND*MAX_ADDR; i++)
{
uFendAddr = ntohl(inet_addr(FendMsg.SetTcpIpAddr[i]));
if(uFendAddr == addr)
{
bRetVal = true;
break;
}
}
return bRetVal;
}
//***************************************************************
//* 写变化数据到变化数据缓冲区 *
//***************************************************************
void WriteChangeData(int commidex, int point, void *pntmsg, BYTE type)
{
//char szDbg[256];
AI_DEF *aiptr;
DI_DEF *diptr;
PI_DEF *piptr;
HOSTMSG *pRtuChangeMsg;
int commid;
//if (WriteChangeFlag == 0)
// return;
// wen 2006.01.14 增加端口偏移
commid = commidex + FendMsg.iPortOffset;
pRtuChangeMsg = GetRtuChangeMsgPtr();
switch (type)
{
case AI_PNT_TYPE:
// wen 2006.05.20 传送32bit模拟量数据
if(FendMsg.iSendAiof32Bit)
{
aiptr = (AI_DEF *)pntmsg;
pRtuChangeMsg[AIMSGNO].MsgType = PGC3_AI32DATA;
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);
*(long*)&(pRtuChangeMsg[AIMSGNO].MsgData[pRtuChangeMsg[AIMSGNO].MsgLen]) = (long)aiptr->RawValue;
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;
}
}
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// 两个地方调用时钟周期为20ms20×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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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; i<hmsg->MsgLen; 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