|
|
|
|
|
|
|
|
//#include "stdafx.h"
|
|
|
#include "udpcomm.h"
|
|
|
#include "commport.h"
|
|
|
#include "udpping.h"
|
|
|
#include "tcphost.h"
|
|
|
//#include "qt_public.h"
|
|
|
//#include <qapplication.h>
|
|
|
//#include "WidgetMainWnd.h"
|
|
|
|
|
|
extern FUNCTION_CALL *FunCallPtr;
|
|
|
extern SIO_PARAM_DEF SioParam[];
|
|
|
|
|
|
extern int CurPort;
|
|
|
extern int RealDataDispFlag;
|
|
|
extern char IniFilePath[256];
|
|
|
|
|
|
int giRealDataToFile = 1;
|
|
|
|
|
|
UDP_SET_DEF UdpParam;
|
|
|
HOST_IP_ADDR HostIpAddr;
|
|
|
|
|
|
int UdpParamInitFlag = 0;
|
|
|
|
|
|
int iDevNum = 0;
|
|
|
int iCurDevIdx = 0;
|
|
|
DEV_DEF DevParam[MAX_DEV_NUM];
|
|
|
|
|
|
int SendCnt = 0;
|
|
|
int RecvCnt = 0;
|
|
|
|
|
|
char gCurConfigFileName[512];
|
|
|
|
|
|
void InitGlobalMember()
|
|
|
{
|
|
|
memset(gCurConfigFileName, 0, sizeof(gCurConfigFileName));
|
|
|
}
|
|
|
|
|
|
void GetHostIpAddr(void)
|
|
|
{
|
|
|
int i;
|
|
|
WSADATA WSAData;
|
|
|
struct hostent *test;
|
|
|
struct in_addr *addr, inaddr;
|
|
|
char name[256];
|
|
|
|
|
|
memset((char*)&HostIpAddr, 0, sizeof(HOST_IP_ADDR));
|
|
|
|
|
|
if(WSAStartup(MAKEWORD(2, 1), (LPWSADATA)&WSAData) != 0)
|
|
|
return;
|
|
|
|
|
|
gethostname(name, 100);
|
|
|
test = gethostbyname(name);
|
|
|
|
|
|
test->h_addrtype = test->h_addrtype;
|
|
|
|
|
|
for (i = 0; i < MAX_NET_NUM; i++)
|
|
|
{
|
|
|
addr = (struct in_addr *)test->h_addr_list[i];
|
|
|
if(addr == NULL)
|
|
|
break;
|
|
|
|
|
|
inaddr = *((in_addr *)test->h_addr_list[i]);
|
|
|
|
|
|
HostIpAddr.AllIpAddr[i] = ntohl(inaddr.S_un.S_addr);
|
|
|
|
|
|
if(IN_CLASSA(HostIpAddr.AllIpAddr[i])) /*A类地址*/
|
|
|
{
|
|
|
HostIpAddr.NetMaskIpAddr[i] = IN_CLASSA_NET;
|
|
|
HostIpAddr.MainIpAddr[i] = (HostIpAddr.AllIpAddr[i] & IN_CLASSA_NET);
|
|
|
HostIpAddr.BroadCastIpAddr[i] = (HostIpAddr.AllIpAddr[i] & IN_CLASSA_NET) | IN_CLASSA_HOST;
|
|
|
}
|
|
|
else if(IN_CLASSB(HostIpAddr.AllIpAddr[i])) /*B类地址*/
|
|
|
{
|
|
|
HostIpAddr.NetMaskIpAddr[i] = IN_CLASSB_NET;
|
|
|
HostIpAddr.MainIpAddr[i] = (HostIpAddr.AllIpAddr[i] & IN_CLASSB_NET);
|
|
|
HostIpAddr.BroadCastIpAddr[i] = (HostIpAddr.AllIpAddr[i] & IN_CLASSB_NET) | IN_CLASSB_HOST;
|
|
|
}
|
|
|
else if(IN_CLASSC(HostIpAddr.AllIpAddr[i])) /*C类地址*/
|
|
|
{
|
|
|
HostIpAddr.NetMaskIpAddr[i] = IN_CLASSC_NET;
|
|
|
HostIpAddr.MainIpAddr[i] = (HostIpAddr.AllIpAddr[i] & IN_CLASSC_NET);
|
|
|
HostIpAddr.BroadCastIpAddr[i] = (HostIpAddr.AllIpAddr[i] & IN_CLASSC_NET) | IN_CLASSC_HOST;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//创建用于系统配置的UDP socket
|
|
|
void CreatUdpSetSock(void)
|
|
|
{
|
|
|
int tmp;
|
|
|
char szConfig[256];
|
|
|
|
|
|
//GetCurrentDirectory(sizeof(szDir), szDir);
|
|
|
sprintf(szConfig, "%s/config.ini", IniFilePath);
|
|
|
|
|
|
if(UdpParamInitFlag == 0)
|
|
|
{
|
|
|
memset((char*)&UdpParam, 0, sizeof(UDP_SET_DEF));
|
|
|
|
|
|
UdpParam.PortNumber = GetPrivateProInt("NetCommPort", "UdpCommPort", 0, szConfig);
|
|
|
if(UdpParam.PortNumber == 0)
|
|
|
{
|
|
|
UdpParam.PortNumber = DEFAULT_UDP_COMM_PORT;
|
|
|
}
|
|
|
|
|
|
GetHostIpAddr();
|
|
|
UdpParamInitFlag = 1;
|
|
|
}
|
|
|
|
|
|
if(UdpParam.Socket)
|
|
|
return;
|
|
|
|
|
|
UdpParam.Socket = socket(AF_INET, SOCK_DGRAM, 0);
|
|
|
if(UdpParam.Socket <= 0)
|
|
|
{
|
|
|
UdpParam.Socket = 0;
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
// wen 2005.12.01 在这里初始化数据
|
|
|
InitGlobalMember();
|
|
|
|
|
|
//设置socket输入输出绶冲
|
|
|
tmp = MAX_NET_BUF_SIZE;
|
|
|
setsockopt(UdpParam.Socket, SOL_SOCKET, SO_RCVBUF, (char*)&tmp, sizeof(tmp));
|
|
|
tmp = MAX_NET_BUF_SIZE;
|
|
|
setsockopt(UdpParam.Socket, SOL_SOCKET, SO_SNDBUF, (char*)&tmp, sizeof(tmp));
|
|
|
|
|
|
tmp = 1;
|
|
|
setsockopt(UdpParam.Socket, SOL_SOCKET, SO_BROADCAST, (char*)&tmp, sizeof(tmp)); // 广播
|
|
|
|
|
|
//让配置socket 能收不同网段的配置命令
|
|
|
memset(&UdpParam.Addr, 0, sizeof(UdpParam.Addr));
|
|
|
UdpParam.Addr.sin_family = AF_INET;
|
|
|
UdpParam.Addr.sin_port = htons(UdpParam.PortNumber);
|
|
|
|
|
|
// wen 2005.03.08 修改ip为指定的地址
|
|
|
UdpParam.Addr.sin_addr.s_addr = htonl(INADDR_ANY);
|
|
|
//UdpParam.Addr.sin_addr.s_addr = inet_addr("192.168.1.200");
|
|
|
|
|
|
if(bind(UdpParam.Socket, (struct sockaddr *)&UdpParam.Addr, sizeof(UdpParam.Addr)) < 0)
|
|
|
{
|
|
|
// windows
|
|
|
//DWORD dwerror = GetLastError();
|
|
|
|
|
|
closesocket(UdpParam.Socket);
|
|
|
UdpParam.Socket = 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void CloseUdpSetSock(void)
|
|
|
{
|
|
|
if(UdpParam.Socket)
|
|
|
{
|
|
|
closesocket(UdpParam.Socket);
|
|
|
}
|
|
|
|
|
|
UdpParam.Socket = 0;
|
|
|
}
|
|
|
|
|
|
int CheckIsMySelftIpAddr(u_long addr)
|
|
|
{
|
|
|
int i;
|
|
|
|
|
|
for(i = 0; i < MAX_NET_NUM; i++)
|
|
|
{
|
|
|
if(addr == HostIpAddr.AllIpAddr[i])
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 定义前置机功能
|
|
|
#ifdef FUNCTION_FEND
|
|
|
#if (FEND_OTHERDEV_DS3116 == 0)
|
|
|
// 非ds-3116设备时,需要用他来确定是否为另一个前置机
|
|
|
return CheckIsFendIpAddr(addr);
|
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
int CheckIsCurDevIpAddr(u_long addr)
|
|
|
{
|
|
|
//int i;
|
|
|
|
|
|
//for(i = 0; i < MAX_NET_NUM; i++)
|
|
|
{
|
|
|
if(addr == DevParam[iCurDevIdx].CurCommIp)
|
|
|
{
|
|
|
return true;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
//接收网络配置网络命令
|
|
|
void SetUdpRecv(void)
|
|
|
{
|
|
|
struct timeval outtime;
|
|
|
int len;
|
|
|
int addr_len = sizeof(struct sockaddr_in);
|
|
|
fd_set set;
|
|
|
u_char recvbuf[MAX_NET_BUF_SIZE];
|
|
|
//char szDbg[128];
|
|
|
|
|
|
CreatUdpSetSock();
|
|
|
|
|
|
if(UdpParam.Socket == 0)
|
|
|
return;
|
|
|
|
|
|
memset((char*)&outtime, 0, sizeof(struct timeval));
|
|
|
memset((char*)&UdpParam.Addr, 0, sizeof(UdpParam.Addr));
|
|
|
FD_ZERO(&set);
|
|
|
FD_SET(UdpParam.Socket, &set);
|
|
|
|
|
|
for(; ;)
|
|
|
{
|
|
|
//异步收
|
|
|
if(select(FD_SETSIZE, &set, NULL, NULL, &outtime) < 1)
|
|
|
break;
|
|
|
|
|
|
len = recvfrom(UdpParam.Socket, (char*)recvbuf, MAX_NET_BUF_SIZE,0, (struct sockaddr *)&UdpParam.Addr, &addr_len) ;
|
|
|
|
|
|
if(len < 1)
|
|
|
break;
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
// wen 2005.09.28 增加对udp通讯端口的显示
|
|
|
if(RealDataDispFlag)
|
|
|
{
|
|
|
if((CurPort == GetMaxPort()) && (CheckIsCurDevIpAddr(ntohl(UdpParam.Addr.sin_addr.s_addr))))
|
|
|
{
|
|
|
RTUMSG *msg;
|
|
|
WORD wLen, wType;
|
|
|
BYTE *ptr;
|
|
|
|
|
|
msg = (RTUMSG *)recvbuf;
|
|
|
if(IsNetSequence() == TRUE)
|
|
|
{
|
|
|
wType = msg->MsgType;
|
|
|
wLen = msg->MsgLen;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ptr = (BYTE *)&msg->MsgType;
|
|
|
wType = ptr[0] * 256 + ptr[1];
|
|
|
ptr = (BYTE *)&msg->MsgLen;
|
|
|
wLen = ptr[0] * 256 + ptr[1];
|
|
|
}
|
|
|
WatchDataPutDispBuf(msg->PortIdx, SDS_SIO_RECV_DATA, msg->MsgData, wLen);
|
|
|
}
|
|
|
}
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
if(CheckIsMySelftIpAddr(ntohl(UdpParam.Addr.sin_addr.s_addr)) == false)
|
|
|
{
|
|
|
/*
|
|
|
if(UdpParam.Addr.sin_addr.S_un.S_addr != 0xd802a8c0)
|
|
|
{
|
|
|
sprintf(szDbg, "IP(recv): %d.%d.%d.%d:%d",
|
|
|
UdpParam.Addr.sin_addr.S_un.S_un_b.s_b1,
|
|
|
UdpParam.Addr.sin_addr.S_un.S_un_b.s_b2,
|
|
|
UdpParam.Addr.sin_addr.S_un.S_un_b.s_b3,
|
|
|
UdpParam.Addr.sin_addr.S_un.S_un_b.s_b4,
|
|
|
UdpParam.Addr.sin_port);
|
|
|
DebugPrint(szDbg);
|
|
|
}
|
|
|
*/
|
|
|
|
|
|
void SetUdpRecvDataProcess(u_long ipaddr, u_char *buf, int len);
|
|
|
SetUdpRecvDataProcess(ntohl(UdpParam.Addr.sin_addr.s_addr), recvbuf, len);
|
|
|
}
|
|
|
//else
|
|
|
//{
|
|
|
// DebugPrint("Recv self.");
|
|
|
//}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
//发送配置命令,引入IP地址,可以自由采用点对点,全网广播发送方式
|
|
|
int SetUdpSend(u_long ipaddr, char *buf, int len)
|
|
|
{
|
|
|
struct sockaddr_in addr;
|
|
|
int slen;
|
|
|
|
|
|
if(UdpParam.Socket == 0)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
// 定义前置机功能
|
|
|
#ifdef FUNCTION_FEND
|
|
|
// wen 2005.10.12 增加是否下发前置机的判断
|
|
|
#if (FEND_OTHERDEV_DS3116 == 0)
|
|
|
if(GetFendTxdFlag() == 0)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
#endif
|
|
|
#endif
|
|
|
|
|
|
if(len == 0)
|
|
|
{
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
memset(&addr, 0, sizeof(addr));
|
|
|
|
|
|
addr.sin_family = AF_INET;
|
|
|
addr.sin_port = htons(UdpParam.PortNumber);
|
|
|
addr.sin_addr.s_addr = ntohl(ipaddr);
|
|
|
|
|
|
slen = sendto(UdpParam.Socket, buf, len, 0,
|
|
|
(struct sockaddr *)&addr, sizeof(struct sockaddr_in));
|
|
|
|
|
|
if(slen != len)
|
|
|
{
|
|
|
closesocket(UdpParam.Socket);
|
|
|
UdpParam.Socket = 0;
|
|
|
|
|
|
return false;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
RTUMSG *msg;
|
|
|
WORD wLen, wType;
|
|
|
BYTE *ptr;
|
|
|
|
|
|
wLen = 0x55AA;
|
|
|
ptr = (BYTE *)&wLen;
|
|
|
|
|
|
msg = (RTUMSG *)buf;
|
|
|
if(ptr[0] == 0x55)
|
|
|
{
|
|
|
wType = msg->MsgType;
|
|
|
wLen = msg->MsgLen;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
ptr = (BYTE *)&msg->MsgType;
|
|
|
wType = ptr[0] * 256 + ptr[1];
|
|
|
ptr = (BYTE *)&msg->MsgLen;
|
|
|
wLen = ptr[0] * 256 + ptr[1];
|
|
|
}
|
|
|
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
// wen 2005.09.28 增加对udp通讯端口的显示
|
|
|
/*if((CurPort == msg->PortIdx) && RealDataDispFlag)
|
|
|
{
|
|
|
if(SDS_SIO_SEND_DATA == wType)
|
|
|
{
|
|
|
WatchDataPutDispBuf(msg->PortIdx, SDS_SIO_SEND_DATA, msg->MsgData, wLen);
|
|
|
}
|
|
|
}*/
|
|
|
if(RealDataDispFlag)
|
|
|
{
|
|
|
if(CurPort == msg->PortIdx)
|
|
|
{
|
|
|
if(SDS_SIO_SEND_DATA == wType)
|
|
|
{
|
|
|
WatchDataPutDispBuf(msg->PortIdx, SDS_SIO_SEND_DATA, msg->MsgData, wLen);
|
|
|
}
|
|
|
}
|
|
|
else if(CurPort == GetMaxPort())
|
|
|
{
|
|
|
WatchDataPutDispBuf(msg->PortIdx, SDS_SIO_SEND_DATA, msg->MsgData, wLen);
|
|
|
}
|
|
|
}
|
|
|
//++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
}
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
//填充配置结果,返包到上行绶冲
|
|
|
int FillAndSendCmd(u_long ipaddr, u_char port, WORD cmd, u_char *retbuf, int len)
|
|
|
{
|
|
|
RTUMSG rtumsg;
|
|
|
u_char *ptr;
|
|
|
int tmp = 0;
|
|
|
|
|
|
rtumsg.PortIdx = port;
|
|
|
ptr = (u_char*)&rtumsg.MsgType;
|
|
|
ptr[0] = HIBYTE(cmd);
|
|
|
ptr[1] = LOBYTE(cmd);
|
|
|
ptr[2] = HIBYTE(len);
|
|
|
ptr[3] = LOBYTE(len);
|
|
|
|
|
|
if(len)
|
|
|
memmove((char *)rtumsg.MsgData, retbuf, len);
|
|
|
|
|
|
if(ipaddr)
|
|
|
tmp = SetUdpSend(ipaddr, (char*)&rtumsg, sizeof(RTUMSGHEAD) + len);
|
|
|
else
|
|
|
{
|
|
|
if(DevParam[iCurDevIdx].CurCommIp)
|
|
|
tmp = SetUdpSend(DevParam[iCurDevIdx].CurCommIp, (char*)&rtumsg, sizeof(RTUMSGHEAD) + len);
|
|
|
}
|
|
|
|
|
|
return tmp;
|
|
|
}
|
|
|
|
|
|
int GetSdsIpAddr(void)
|
|
|
{
|
|
|
/*SYSTEMTIME sm;
|
|
|
char szInfo[128];
|
|
|
|
|
|
GetLocalTime(&sm);
|
|
|
sprintf(szInfo, "%02d_%02d:%02d:%02d.%03d GetSdsIpAddr\n",
|
|
|
sm.wDay, sm.wHour, sm.wMinute, sm.wSecond, sm.wMilliseconds);
|
|
|
OutputDebugString(szInfo);*/
|
|
|
|
|
|
return FillAndSendCmd(INADDR_BROADCAST, 0, SDS_N_GET_IP_ADDR, NULL, 0);
|
|
|
}
|
|
|
|
|
|
void ValueToBuf(u_char *buf, u_long val, int len)
|
|
|
{
|
|
|
switch(len)
|
|
|
{
|
|
|
case 2:
|
|
|
buf[0] = HIBYTE(LOWORD(val));
|
|
|
buf[1] = LOBYTE(LOWORD(val));
|
|
|
break;
|
|
|
case 4:
|
|
|
buf[0] = HIBYTE(HIWORD(val));
|
|
|
buf[1] = LOBYTE(HIWORD(val));
|
|
|
buf[2] = HIBYTE(LOWORD(val));
|
|
|
buf[3] = LOBYTE(LOWORD(val));
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
u_long BufToValue(u_char *buf, int len)
|
|
|
{
|
|
|
u_long retv;
|
|
|
|
|
|
switch(len)
|
|
|
{
|
|
|
case 2:
|
|
|
retv = BYTE1(buf[0]) + BYTE0(buf[1]);
|
|
|
break;
|
|
|
|
|
|
case 4:
|
|
|
retv = BYTE3(buf[0]) + BYTE2(buf[1]) + BYTE1(buf[2]) + BYTE0(buf[3]);
|
|
|
break;
|
|
|
}
|
|
|
return retv;
|
|
|
}
|
|
|
|
|
|
void AddDispLine(DISP_LINE_BUF *dispbuf, char *msg)
|
|
|
{
|
|
|
char szbuf[128], tmp[128];
|
|
|
int k;
|
|
|
|
|
|
k = strlen(msg);
|
|
|
if(k == 0)
|
|
|
return;
|
|
|
|
|
|
if(k > 120)
|
|
|
msg[120] = 0;
|
|
|
|
|
|
k = 120 - strlen(msg);
|
|
|
|
|
|
strcpy(szbuf, msg);
|
|
|
if(k > 0)
|
|
|
{
|
|
|
memset(tmp, ' ', 120);
|
|
|
tmp[k] = 0;
|
|
|
|
|
|
strcat(szbuf, tmp);
|
|
|
}
|
|
|
|
|
|
strcpy(dispbuf->Line[dispbuf->Rear], szbuf);
|
|
|
dispbuf->Rear = (dispbuf->Rear + 1) % MAX_DISP_LINE;
|
|
|
|
|
|
// 当缓冲区满后, 丢掉前半个缓冲区内数据,否则,
|
|
|
// 我们无法停下来观看已有数据,它可能一直滚动,
|
|
|
// 因为每添加一行我们的指针不得不退让一行
|
|
|
dispbuf->LineCnt = dispbuf->LineCnt + 1;
|
|
|
if(dispbuf->LineCnt == MAX_DISP_LINE)
|
|
|
{
|
|
|
dispbuf->LineCnt -= MAX_DISP_LINE / 2;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void WatchDataPutDispBuf(int port, WORD type, u_char *buf, int len)
|
|
|
{
|
|
|
int i, j, k, linechar;
|
|
|
char szbuf[256], tmp[256], tchar;
|
|
|
SYSTEMTIME st;
|
|
|
|
|
|
if(giRealDataToFile == 1)
|
|
|
{
|
|
|
WatchDataPutDispBufToFile(port, type, buf, len);
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
linechar = 18;
|
|
|
|
|
|
tchar = type == SDS_SIO_SEND_DATA ? 'S' : 'R';
|
|
|
|
|
|
GetLocalTime(&st);
|
|
|
|
|
|
szbuf[0] = tchar;
|
|
|
sprintf((char*)&szbuf[1], "%04d-%02d-%02d %02d:%02d:%02d.%03d 端口%d %s 数据, 长度 = %d",
|
|
|
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
|
|
|
port + 1, type == SDS_SIO_SEND_DATA ? "发送" : "接收", len);
|
|
|
|
|
|
AddDispLine(&DevParam[iCurDevIdx].WatchDispLine, szbuf);
|
|
|
|
|
|
for (i = 0; i < len; i += linechar)
|
|
|
{
|
|
|
szbuf[0] = tchar;
|
|
|
sprintf((char*)&szbuf[1], "%04d: ", i);
|
|
|
|
|
|
k = min(linechar, len - i);
|
|
|
|
|
|
for (j = 0; j < k; j++)
|
|
|
{
|
|
|
sprintf(tmp, "%02X ", buf[i+j]);
|
|
|
strcat(szbuf, tmp);
|
|
|
if(((j + 1) % 6) == 0)
|
|
|
strcat(szbuf, " ");
|
|
|
}
|
|
|
|
|
|
AddDispLine(&DevParam[iCurDevIdx].WatchDispLine, szbuf);
|
|
|
}
|
|
|
|
|
|
sprintf(szbuf, "%c", tchar);
|
|
|
strcat(szbuf, " ");
|
|
|
|
|
|
AddDispLine(&DevParam[iCurDevIdx].WatchDispLine, szbuf);
|
|
|
}
|
|
|
|
|
|
void WatchDataPutDispBufToFile(int port, WORD type, u_char *buf, int len)
|
|
|
{
|
|
|
int i, j, k, linechar;
|
|
|
char szbuf[256], tmp[256], tchar;
|
|
|
char szFileName[256];
|
|
|
FILE *fp;
|
|
|
SYSTEMTIME st;
|
|
|
|
|
|
linechar = 18;
|
|
|
|
|
|
tchar = type == SDS_SIO_SEND_DATA ? 'S' : 'R';
|
|
|
|
|
|
GetLocalTime(&st);
|
|
|
|
|
|
//getcwd(szFileName, sizeof(szFileName));
|
|
|
sprintf(szFileName, "%s\\log\\realdata%02d.txt", IniFilePath, port+1);
|
|
|
fp = fopen(szFileName, "a");
|
|
|
|
|
|
szbuf[0] = tchar;
|
|
|
sprintf((char*)&szbuf[1], "%04d-%02d-%02d %02d:%02d:%02d.%03d 端口%d %s 数据, 长度 = %d",
|
|
|
st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, st.wSecond, st.wMilliseconds,
|
|
|
port + 1, type == SDS_SIO_SEND_DATA ? "发送" : "接收", len);
|
|
|
|
|
|
AddDispLine(&DevParam[iCurDevIdx].WatchDispLine, szbuf);
|
|
|
|
|
|
if(fp)
|
|
|
{
|
|
|
strcat(szbuf, "\n");
|
|
|
fwrite(szbuf, sizeof(char), strlen(szbuf), fp);
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < len; i += linechar)
|
|
|
{
|
|
|
szbuf[0] = tchar;
|
|
|
sprintf((char*)&szbuf[1], "%04d: ", i);
|
|
|
|
|
|
k = min(linechar, len - i);
|
|
|
|
|
|
for (j = 0; j < k; j++)
|
|
|
{
|
|
|
sprintf(tmp, "%02X ", buf[i+j]);
|
|
|
strcat(szbuf, tmp);
|
|
|
if(((j + 1) % 6) == 0)
|
|
|
strcat(szbuf, " ");
|
|
|
}
|
|
|
|
|
|
AddDispLine(&DevParam[iCurDevIdx].WatchDispLine, szbuf);
|
|
|
|
|
|
if(fp)
|
|
|
{
|
|
|
strcat(szbuf, "\n");
|
|
|
fwrite(szbuf, sizeof(char), strlen(szbuf), fp);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
sprintf(szbuf, "%c", tchar);
|
|
|
strcat(szbuf, " ");
|
|
|
|
|
|
AddDispLine(&DevParam[iCurDevIdx].WatchDispLine, szbuf);
|
|
|
|
|
|
if(fp)
|
|
|
{
|
|
|
strcpy(szbuf, " \n");
|
|
|
fwrite(szbuf, sizeof(char), strlen(szbuf), fp);
|
|
|
fclose(fp);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int FindDev( u_long ipaddr )
|
|
|
{
|
|
|
int i, j;
|
|
|
|
|
|
for ( i = 0; i < iDevNum; i++ )
|
|
|
{
|
|
|
for( j = 0; j < MAX_NET_NUM; j++ )
|
|
|
{
|
|
|
if ( DevParam[i].IpAddr[j] == 0 )
|
|
|
continue;
|
|
|
|
|
|
if ( DevParam[i].IpAddr[j] == ipaddr )
|
|
|
return i;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
int AddDev( u_long *addr, int num )
|
|
|
{
|
|
|
int i, dev;
|
|
|
|
|
|
for ( i = 0; i < num; i++ )
|
|
|
{
|
|
|
if ( addr[i] )
|
|
|
{
|
|
|
dev = FindDev( addr[i] );
|
|
|
if ( dev >= 0 )
|
|
|
return dev;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
// 新设备
|
|
|
iDevNum++;
|
|
|
|
|
|
return iDevNum - 1;
|
|
|
}
|
|
|
|
|
|
void SetUdpRecvDataProcess(u_long ipaddr, u_char *buf, int len)
|
|
|
{
|
|
|
RTUMSG *msg;
|
|
|
int plen, i, k, dev, net;
|
|
|
u_long addr[MAX_NET_NUM];
|
|
|
WORD tmp;
|
|
|
char *ptr;
|
|
|
//char szInfo[256];
|
|
|
|
|
|
for(plen = 0; plen < len;)
|
|
|
{
|
|
|
msg = (RTUMSG*)&buf[plen];
|
|
|
//让数值为高字节前,低字节后(但此处无特别的作用,仅为了与机器无关而设)
|
|
|
tmp = BYTE1(buf[plen+1]) + BYTE0(buf[plen+2]);
|
|
|
msg->MsgType = tmp;
|
|
|
tmp = BYTE1(buf[plen+3]) + BYTE0(buf[plen+4]);
|
|
|
msg->MsgLen = tmp;
|
|
|
|
|
|
plen += (msg->MsgLen + sizeof(RTUMSGHEAD));
|
|
|
|
|
|
//if(!(msg->MsgType & 0x8000))
|
|
|
//{
|
|
|
// continue;
|
|
|
//}
|
|
|
|
|
|
switch(msg->MsgType & 0x3fff)
|
|
|
{
|
|
|
// 获取系统IP到上行
|
|
|
// 0x00 - 0x03字节: 第一网卡地址IP地址
|
|
|
// 0x044 - 0x07字节: 第二网卡地址IP地址
|
|
|
// 0x08字节: 端口数目总数,包括网络通讯端口
|
|
|
// 0x09 - 0xd字节: 保留
|
|
|
// 0x0e字节: 串行通讯端口数目
|
|
|
// 0x0f字节: 网络通讯端口数目
|
|
|
// 0x10 - 4个带0x00结尾的字符串,它们是设备名称、软件版本、
|
|
|
// 软件版本日期和制造厂商名称
|
|
|
// 接下来,如果网卡数量多于2个,接着填写从第三网卡
|
|
|
// 开始的网络IP地址
|
|
|
case SDS_GET_IP_ADDR:
|
|
|
case SDS_N_GET_IP_ADDR:
|
|
|
if(!(msg->MsgType & 0x8000))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
for (i = 0; i < 2; i++)
|
|
|
{
|
|
|
addr[i] = BYTE3(msg->MsgData[i*4+0])
|
|
|
+ BYTE2(msg->MsgData[i*4+1])
|
|
|
+ BYTE1(msg->MsgData[i*4+2])
|
|
|
+ BYTE0(msg->MsgData[i*4+3]);
|
|
|
|
|
|
/*sprintf(szInfo, "NET%d: %d.%d.%d.%d\n",
|
|
|
i+1, msg->MsgData[i*4+0],
|
|
|
msg->MsgData[i*4+1],
|
|
|
msg->MsgData[i*4+2],
|
|
|
msg->MsgData[i*4+3]);
|
|
|
OutputDebugString(szInfo);*/
|
|
|
}
|
|
|
|
|
|
// 跳过4个字符串
|
|
|
k = 0x10;
|
|
|
ptr = (char*)&msg->MsgData[k];
|
|
|
k += (strlen(ptr) + 1);
|
|
|
ptr = (char*)&msg->MsgData[k];
|
|
|
k += (strlen(ptr) + 1);
|
|
|
ptr = (char*)&msg->MsgData[k];
|
|
|
k += (strlen(ptr) + 1);
|
|
|
ptr = (char*)&msg->MsgData[k];
|
|
|
k += (strlen(ptr) + 1);
|
|
|
|
|
|
net = (msg->MsgLen - k) / 4;
|
|
|
|
|
|
if((net + 2) > MAX_NET_NUM)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
for (i = 0; i < net; i++)
|
|
|
{
|
|
|
addr[2+i] = BYTE3(msg->MsgData[k+0])
|
|
|
+ BYTE2(msg->MsgData[k+1])
|
|
|
+ BYTE1(msg->MsgData[k+2])
|
|
|
+ BYTE0(msg->MsgData[k+3]);
|
|
|
|
|
|
/*sprintf(szInfo, "NET%d: %d.%d.%d.%d\n",
|
|
|
i+3, msg->MsgData[k+0],
|
|
|
msg->MsgData[k+1],
|
|
|
msg->MsgData[k+2],
|
|
|
msg->MsgData[k+3]);
|
|
|
OutputDebugString(szInfo);*/
|
|
|
|
|
|
k += 4;
|
|
|
}
|
|
|
net += 2;
|
|
|
|
|
|
dev = AddDev(&addr[0], net);
|
|
|
DevParam[dev].CurCommIp = ipaddr;
|
|
|
for (i = 0; i < MAX_NET_NUM; i++)
|
|
|
{
|
|
|
if(i < net)
|
|
|
{
|
|
|
if(DevParam[dev].IpAddr[i])
|
|
|
{
|
|
|
if(DevParam[dev].IpAddr[i] != addr[i])
|
|
|
DevParam[dev].IpAddrChangeFlag = 1;
|
|
|
}
|
|
|
DevParam[dev].IpAddr[i] = addr[i];
|
|
|
}
|
|
|
else
|
|
|
DevParam[dev].IpAddr[i] = 0;
|
|
|
}
|
|
|
DevParam[dev].NetNum = net;
|
|
|
DevParam[dev].PortNum = msg->MsgData[8];
|
|
|
DevParam[dev].SerialPortNum = msg->MsgData[0x0e];
|
|
|
DevParam[dev].NetPortNum = msg->MsgData[0x0f];
|
|
|
break;
|
|
|
|
|
|
case SDS_SIO_SET_CONFIG_FILE:
|
|
|
if(!(msg->MsgType & 0x8000))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
//dev = FindDev(ipaddr);
|
|
|
//if (dev < 0)
|
|
|
// break;
|
|
|
|
|
|
//ClrWaitFlag(dev);
|
|
|
|
|
|
tmp = BYTE1(msg->MsgData[0]) + BYTE0(msg->MsgData[1]);
|
|
|
|
|
|
// 传输错误, 重来
|
|
|
if((msg->MsgType & 0xc000) == 0x4000)
|
|
|
{
|
|
|
tmp = 0;
|
|
|
}
|
|
|
SetDevConfigFile(tmp + 1);
|
|
|
break;
|
|
|
|
|
|
case SDS_SIO_RECV_DATA:
|
|
|
if(!CheckIsCurDevIpAddr(ipaddr))
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
if(FunCallPtr[SioParam[msg->PortIdx].ProtocolIdx].RecvData)
|
|
|
{
|
|
|
FunCallPtr[SioParam[msg->PortIdx].ProtocolIdx].RecvData(msg->PortIdx,
|
|
|
msg->MsgData, msg->MsgLen);
|
|
|
|
|
|
//SioParam[msg->PortIdx].RecvCharNum += msg->MsgLen;
|
|
|
}
|
|
|
// wen 2004.11.25 删除数据缓冲区数据长度(保持和5249中的程序一致)
|
|
|
SioParam[msg->PortIdx].RecvBuf.MsgCnt = 0;
|
|
|
|
|
|
SioParam[msg->PortIdx].RecvCharNum += msg->MsgLen;
|
|
|
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
// wen 2006.04.24 如果仅仅是接收到数据,不认为端口状态为正常,
|
|
|
// 必须是修改了数据库点才认为是端口正常。子站除外。
|
|
|
//SioParam[msg->PortIdx].LineCommCnt = 0;
|
|
|
//SioParam[msg->PortIdx].Status = TRUE;
|
|
|
//=============================================================
|
|
|
SioParam[msg->PortIdx].LineCommCnt = 0;
|
|
|
if(SioParam[msg->PortIdx].m_psBaoHu)
|
|
|
{
|
|
|
// 如果为子站
|
|
|
if(SioParam[msg->PortIdx].m_psBaoHu->PortType)
|
|
|
{
|
|
|
SioParam[msg->PortIdx].Status = TRUE;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
SioParam[msg->PortIdx].Status = TRUE;
|
|
|
}
|
|
|
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
|
|
|
//if((CurPort == msg->PortIdx) && RealDataDispFlag)
|
|
|
//{
|
|
|
// WatchDataPutDispBuf(msg->PortIdx, SDS_SIO_RECV_DATA, msg->MsgData, msg->MsgLen);
|
|
|
//}
|
|
|
break;
|
|
|
case SDS_SIO_SEND_DATA:
|
|
|
// 数据已经接收
|
|
|
//sprintf(szInfo, "TIP_(%08d): port=%d Send Data is received.\n",
|
|
|
// getpid(), msg->PortIdx+1);
|
|
|
//DebugPrint(szInfo);
|
|
|
break;
|
|
|
default:
|
|
|
//sprintf(szInfo, "ERR_(%08d): port=%d Recv Error(Func=%d).",
|
|
|
// getpid(), msg->PortIdx+1, msg->MsgType);
|
|
|
//DebugPrint(szInfo);
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
void SetDevConfigFile(int blk)
|
|
|
{
|
|
|
if(SetDevConfigFileEx(gCurConfigFileName, blk) != 0)
|
|
|
{
|
|
|
//((CWidgetMainWnd *)qApp->mainWidget())->RestoreCursor();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
int SetDevConfigFileEx(char *szPortConfigName, int blk)
|
|
|
{
|
|
|
char szbuf[1024];
|
|
|
int idx, blklen, iSendLen;
|
|
|
FILE *fp;
|
|
|
|
|
|
if(!DevParam[iCurDevIdx].CurCommIp)
|
|
|
{
|
|
|
////QTMessageBox("设备配置文件...", "无有效设备!!!");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if(szPortConfigName == NULL)
|
|
|
{
|
|
|
//QTMessageBox("设备配置文件...", "下装设备配置文件名称错误!!!");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
if(strlen(szPortConfigName) == 0)
|
|
|
{
|
|
|
//QTMessageBox("设备配置文件...", "下装设备配置文件名称错误!!!");
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
// wen 2005.12.01 在这里设置全局的配置文件名称
|
|
|
if(blk == 0)
|
|
|
{
|
|
|
strcpy(gCurConfigFileName, szPortConfigName);
|
|
|
}
|
|
|
|
|
|
fp = fopen(szPortConfigName, "rb");
|
|
|
if(fp == NULL)
|
|
|
{
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
for(idx = 0; ; idx++)
|
|
|
{
|
|
|
blklen = fread((char*)&szbuf[2], 1, BLK_SIZE, fp);
|
|
|
if(blklen < 1)
|
|
|
{
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
if(idx == blk)
|
|
|
{
|
|
|
szbuf[0] = HIBYTE(blk);
|
|
|
szbuf[1] = LOBYTE(blk);
|
|
|
iSendLen = FillAndSendCmd(0, 0, SDS_SIO_SET_CONFIG_FILE, (u_char*)szbuf, blklen + 2);
|
|
|
fclose(fp);
|
|
|
if(iSendLen == 0)
|
|
|
{
|
|
|
//QTMessageBox("设备配置文件...", "下装设备配置文件失败!!!");
|
|
|
return -1;
|
|
|
}
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
fclose(fp);
|
|
|
//MessageBox(NULL, "设备配置文件设置完成!!!", "设备配置文件...", MB_OK | MB_ICONINFORMATION);
|
|
|
//QTMessageBox("设备配置文件...", "设备配置文件设置完成!!!");
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
void SetDevTime()
|
|
|
{
|
|
|
BYTE buf[16];
|
|
|
DAY_TIME sm;
|
|
|
|
|
|
GetLocalTimeEx(&sm);
|
|
|
|
|
|
buf[0] = HIBYTE(sm.Year);
|
|
|
buf[1] = LOBYTE(sm.Year);
|
|
|
buf[2] = 0;
|
|
|
buf[3] = sm.Month;
|
|
|
buf[4] = 0;
|
|
|
buf[5] = sm.Day;
|
|
|
buf[6] = 0;
|
|
|
buf[7] = sm.Hour;
|
|
|
buf[8] = 0;
|
|
|
buf[9] = sm.Min;
|
|
|
buf[10] = 0;
|
|
|
buf[11] = sm.Sec;
|
|
|
|
|
|
FillAndSendCmd(INADDR_BROADCAST, 0, SDS_SIO_SET_SYSTEM_TIME, buf, 12);
|
|
|
}
|
|
|
|
|
|
void ResetDev(int iDevNo)
|
|
|
{
|
|
|
if(iDevNo >= 0)
|
|
|
{
|
|
|
FillAndSendCmd(DevParam[iDevNo].CurCommIp, 0, SDS_SIO_RESET, NULL, 0);
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
FillAndSendCmd(0, 0, SDS_SIO_RESET, NULL, 0);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
BOOL isUdpSocketExist()
|
|
|
{
|
|
|
if(UdpParam.Socket)
|
|
|
{
|
|
|
return TRUE;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
return FALSE;
|
|
|
}
|
|
|
}
|