|
|
/************************************************************************************
|
|
|
*
|
|
|
* 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;
|
|
|
}
|
|
|
}
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
|
|
|
// 两个地方调用,时钟周期为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; 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
|