#include "stdafx.h" #include "tcpprocess.h" #include "Global.h" #include "struct.h" #include "NoticeQueue.h" #include "Syslib.h" HANDLE g_TCPResponseThread = NULL; HANDLE g_TCPRequestThread = NULL; DWORD g_dwTcpVariantTick = 0; CRITICAL_SECTION g_csTcpReadOneData; HANDLE g_hSemNet; // 临时测试变量 int g_nIndex = 0; //rtu动态库输出函数 HINSTANCE g_hTCPLibModule = NULL; TCP_DLLInitNet pTCP_DLLInitNet = NULL; TCP_DLLInit pTCP_DLLInit = NULL; TCP_DLLUnInit pTCP_DLLUnInit = NULL; TCP_DLLRequestStatusData pTCP_DLLRequestStatusData = NULL; TCP_DLLWrite pTCP_DLLWrite = NULL; TCP_DLLRequestWrStatusData pTCP_DLLRequestWrStatusData = NULL; TCP_DLLCloseNet pTCP_DllCloseNet = NULL; int TcpCommandSend(); int TcpResponseValue(); BOOL LoadTcpDll(CString strpath) { char strFile[256] = {0}; g_hTCPLibModule = NULL; sprintf(strFile, "%s\\dll\\modbustcp.dll", strpath); InitializeCriticalSection( &g_csTcpReadOneData ); MTVERIFY( g_hSemNet = CreateEvent( NULL, TRUE, TRUE, "Server::ModbusTcpNet" ) ); g_hTCPLibModule = AfxLoadLibrary(strFile); //RTU 动态库初始化 if (NULL != g_hTCPLibModule) { pTCP_DLLInitNet =( TCP_DLLInitNet)::GetProcAddress(g_hTCPLibModule, "TCP_DLLInitNet"); pTCP_DllCloseNet =( TCP_DLLCloseNet)::GetProcAddress(g_hTCPLibModule, "TCP_DLLCloseNet"); pTCP_DLLInit = (TCP_DLLInit)::GetProcAddress(g_hTCPLibModule, "TCP_DLLInit"); pTCP_DLLUnInit = (TCP_DLLUnInit)::GetProcAddress(g_hTCPLibModule, "TCP_DLLUnInit"); pTCP_DLLRequestStatusData = (TCP_DLLRequestStatusData)::GetProcAddress(g_hTCPLibModule, "TCP_DLLRequestStatusData"); pTCP_DLLWrite = (TCP_DLLWrite)::GetProcAddress(g_hTCPLibModule, "TCP_DLLWrite"); pTCP_DLLRequestWrStatusData = (TCP_DLLRequestWrStatusData)::GetProcAddress(g_hTCPLibModule, "TCP_DLLRequestWrStatusData"); return TRUE; } else { return FALSE; } } BOOL InitTcpNet(int nAddr, int nNetPort, char strIpAddr[32]) { if (pTCP_DLLInitNet(nAddr, nNetPort, strIpAddr))//初始化串口 return TRUE; else return FALSE; } void CloseTcpNet(int nAddr, int nNetPort, char strIpAddr[32]) { if( pTCP_DllCloseNet ) { pTCP_DllCloseNet(nAddr, nNetPort, strIpAddr); } } int TcpRequestData( int nNetPort, int nDevAddr, char chIpAddr[32], int nRegNum, int nRegStartAddr, int nFuncCode) { int nRet = 0; #if 0 if( WaitForSingleObject(g_hSemNet, 0) == WAIT_OBJECT_0 ) // 有信号才发送数据 { g_nIndex++; ResetEvent( g_hSemNet ); //TRACE("开始请求一次数据\r\n"); nRet = pTCP_DLLInit(nNetPort, nDevAddr, chIpAddr, nRegNum, nRegStartAddr, 0, 0, nFuncCode); return nRet; } else { return ERR_CODE_MODBUS_TCP_NET_BUSY; } #else nRet = pTCP_DLLInit(nNetPort, nDevAddr, chIpAddr, nRegNum, nRegStartAddr, 0, 0, nFuncCode); return nRet; #endif } int TcpSingleResponseData(char chDevUid[20], int iVarID) { int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) return -1; CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; EnterCriticalSection(&g_csTcpReadOneData); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection(&g_csTcpReadOneData); char chMsg[80] = {0}; int nRet = pTCP_DLLRequestStatusData(pDev->m_iIpport, pDev->m_iDevideaddr, (char *)(LPCTSTR)pDev->m_strIp, chMsg); if( nRet != 0 ) { return nRet; } DWORD nValue = 0; WORD wdValue = 0; double fCoef = pBaseVar->m_dbCoefficient; int nDataLen = pBaseVar->m_iDataLen; int nVarItemID = pBaseVar->m_nVarItemID; if( nVarItemID > 0 )//BIT位变量 { int nStartBit = pBaseVar->m_nStartBit; int nEndBit = pBaseVar->m_nEndBit; int nStartReg, nEndReg; if( nEndBit - nStartBit < 7 )// 一般告警状态会这样子定义,Modbus Rtu 码暂时没有碰到,没有经过调试,待测试 { if( nDataLen == 1 ) { nValue = chMsg[0]; } else if( nDataLen == 2 ) { memcpy(&wdValue, chMsg, sizeof(WORD)); nValue = (DWORD)htons(wdValue); } } // 特殊变量处理(例如,一个命令返回两个变量的情况) else if( nEndBit - nStartBit == 7 ) // 1个字节的情况 { nStartReg = (int)nStartBit / 8; nEndReg = (int)(nEndBit + 1) / 8; nValue = chMsg[nStartReg]; } else if( nEndBit - nStartBit == 15 ) // 2个字节的情况 { nStartReg = (int)nStartBit / 8; nEndReg = (int)(nEndBit + 1) / 8; memcpy(&wdValue, chMsg, sizeof(WORD)); nValue = (DWORD)htons(wdValue); } EnterCriticalSection( &g_csTcpReadOneData ); pBaseVar->m_dbData = (double)(nValue * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csTcpReadOneData ); //TRACE2("变量ID%d, 值=%d\r\n", iVarID, nValue); } else { // 联合类型变量做特殊处理 if( pBaseVar->m_nVarTypeID >= UNION_TYPE_MIN_ID && pBaseVar->m_nVarTypeID <= UNION_TYPE_MAX_ID ) { if( nDataLen == 2 ) { //int类型 union __UNION_VAR_INT{ char ch[2]; int value; }unionVarInt; unionVarInt.ch[0] = chMsg[1]; unionVarInt.ch[1] = chMsg[0]; EnterCriticalSection( &g_csTcpReadOneData ); pBaseVar->m_dbData = (double)(unionVarInt.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csTcpReadOneData ); //TRACE2("联合类型变量ID%d, 值=%d\r\n", iVarID, unionVarInt.value); } else if( nDataLen == 4 ) { //float类型 union __UNION_VAR_FLOAT{ char ch[4]; float value; }unionVarFloat; unionVarFloat.ch[0] = chMsg[3]; unionVarFloat.ch[1] = chMsg[2]; unionVarFloat.ch[2] = chMsg[1]; unionVarFloat.ch[3] = chMsg[0]; EnterCriticalSection( &g_csTcpReadOneData ); pBaseVar->m_dbData = (double)(unionVarFloat.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csTcpReadOneData ); //TRACE2("联合类型变量ID%d, 值=%.1f\r\n", iVarID, unionVarFloat.value); } else if( nDataLen == 8 ) { //double类型 union __UNION_VAR_DOUBLE{ char ch[8]; double value; }unionVarDouble; unionVarDouble.ch[0] = chMsg[7]; unionVarDouble.ch[1] = chMsg[6]; unionVarDouble.ch[2] = chMsg[5]; unionVarDouble.ch[3] = chMsg[4]; unionVarDouble.ch[4] = chMsg[3]; unionVarDouble.ch[5] = chMsg[2]; unionVarDouble.ch[6] = chMsg[1]; unionVarDouble.ch[7] = chMsg[0]; EnterCriticalSection( &g_csTcpReadOneData ); pBaseVar->m_dbData = (double)(unionVarDouble.value * fCoef); if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csTcpReadOneData ); //TRACE2("联合类型变量ID%d, 值=%.1f\r\n", iVarID, unionVarDouble.value); } } else { switch( nDataLen ) { case 1: nValue = chMsg[0]; break; case 2: WORD wdValue; memcpy(&wdValue, chMsg, sizeof(WORD)); //wdValue = htons(wdValue); nValue = htons(wdValue); break; case 3: // 一般为字符串类型,不作处理 break; case 4: // 保留,暂时不知道什么处理 break; case 5: // 一般为字符串类型,不作处理 break; case 6: // 一般为字符串类型,不作处理 break; case 7: // 一般为字符串类型,不作处理 break; case 8: // 保留,暂时没有用到 break; } EnterCriticalSection( &g_csTcpReadOneData ); if( pBaseVar->m_nMaxValues != 0 || pBaseVar->m_nMinValues != 0 || pBaseVar->m_nMaxConvtRate != 0 || pBaseVar->m_nMinConvtRate != 0 ) { double fScale = (double)(pBaseVar->m_nMaxConvtRate - pBaseVar->m_nMinConvtRate) / (double)(pBaseVar->m_nMaxValues - pBaseVar->m_nMinValues); CString strUid = pDev->m_strUid; if( strUid.Find("5.4.63") != -1 ) // 暂时还没有好的方案处理C2000设备计算公式,只好做特殊处理,待完善 { // (读数/4096*20-最小电流值)*((最大比例-最小比例)/(最大电流值-最小电流值)) +最小比例 if( nValue > 0 ) { pBaseVar->m_dbData = ((double)nValue / 4096 * 20 - pBaseVar->m_nMinValues) * fScale + pBaseVar->m_nMinConvtRate; } else { pBaseVar->m_dbData = 0.0; } } else { pBaseVar->m_dbData = nValue * fCoef * fScale; } } else { pBaseVar->m_dbData = (double)(nValue * fCoef); } if( pBaseVar->m_nRearm != 0 ) { pBaseVar->m_dbData = pBaseVar->m_dbData + pBaseVar->m_nRearm; } LeaveCriticalSection( &g_csTcpReadOneData ); //TRACE2("普通变量ID%d, 值=%f\r\n", iVarID, g_TcpReadOneData.dbData); } } EnterCriticalSection(&g_csTcpReadOneData); pDev->m_dwOnlineTick = GetTickCount(); LeaveCriticalSection(&g_csTcpReadOneData); return 0; } int TcpRequestWriteData( int nNetPort, int nDevAddr, char chIpAddr[32], int nRegNum, int nRegStartAddr, int nFuncCode, int nRegValue) { int nRet = 0; g_nIndex++; //ResetEvent( g_hSemNet ); //TRACE("开始请求一次数据\r\n"); nRet = pTCP_DLLWrite(nNetPort, nDevAddr, chIpAddr, nRegNum, nRegStartAddr, 0, 0, nFuncCode, nRegValue); return nRet; } int TcpSingleResponseWriteData(char chDevUid[20], int iVarID) { int nDeviceIndex = -1, nVarIndex = -1; BOOL bFind = FindVar(chDevUid, iVarID, nDeviceIndex, nVarIndex); if( bFind == FALSE ) return -1; CDevice *pDev = g_pDevicesManager->m_Devices[nDeviceIndex]; CBaseVar *pBaseVar = pDev->m_Vars[nVarIndex]; int nWriteResult; int nRet = pTCP_DLLRequestWrStatusData(pDev->m_iIpport, pDev->m_iDevideaddr, (char *)(LPCTSTR)pDev->m_strIp, nWriteResult); if( nRet != 0 ) { return nRet; } return 0; } void UnInitTcpDll() { if (g_hTCPLibModule != NULL && ( NULL != pTCP_DLLUnInit )) { if( g_hSemNet ) { MTVERIFY( SetEvent(g_hSemNet) ); } pTCP_DLLUnInit(); } if( g_hSemNet ) { MTVERIFY( CloseHandle( g_hSemNet )); } DeleteCriticalSection( &g_csTcpReadOneData ); if (g_hTCPLibModule!= NULL) { AfxFreeLibrary(g_hTCPLibModule); g_hTCPLibModule = NULL; } }