From 3d9c1cca107e136b81ce042a249a313401693be6 Mon Sep 17 00:00:00 2001 From: Jonny007-MKD Date: Tue, 27 May 2014 11:03:56 +0000 Subject: [PATCH] Merging branch writeDbg into trunk --- Modbus/ModbusNet.cfg | 305 +++++++++--------- Modbus/include/CAPL/ModbusClient.can | 51 +-- Modbus/include/CAPL/include/Common.cin | 182 +++++++++++ Modbus/include/CAPL/include/EilCommon.cin | 32 +- .../CAPL/include/ModbusClientCommon.cin | 208 +++++++----- .../CAPL/include/ModbusCommonStructs.cin | 10 + .../CAPL/include/ModbusEilClientCommon.cin | 9 +- .../include/CAPL/include/ModbusFunctions.cin | 9 +- Modbus/include/CAPL/include/TcpCommon.cin | 68 ++-- Modbus/include/CAPL/include/UdpCommon.cin | 53 +-- 10 files changed, 597 insertions(+), 330 deletions(-) diff --git a/Modbus/ModbusNet.cfg b/Modbus/ModbusNet.cfg index fcd318c..d123db7 100644 --- a/Modbus/ModbusNet.cfg +++ b/Modbus/ModbusNet.cfg @@ -1,4 +1,4 @@ -;CANoe Version |4|7|1|55200 ModbusNet +;CANoe Version |4|7|1|38837 ModbusNet Version: 8.2.40 Build 40 32 PRO 10 @@ -1566,7 +1566,7 @@ End_Of_Serialized_Data 14 6 1 14 -ver=2: FT TF TF FF FT FT;F T Config;F T Ethernet1;F T GLLogger;T F _Statistics +ver=2: FT TF TF FF FT FF;F T Config;F T Ethernet1;F T GLLogger;T F _Statistics End_Of_Serialized_Data 14 7 0 @@ -1592,10 +1592,7 @@ End_Of_Serialized_Data 14 16 0 17 -1 -14 -ver=2: FT -End_Of_Serialized_Data 14 +0 18 0 19 @@ -1610,29 +1607,29 @@ End_Of_Serialized_Data 14 22 1 14 -ver=2: FT +ver=2: FF End_Of_Serialized_Data 14 23 1 14 -ver=2: FT +ver=2: FF End_Of_Serialized_Data 14 24 1 14 -ver=2: FT +ver=2: FF End_Of_Serialized_Data 14 25 0 26 1 14 -ver=2: FT +ver=2: FF End_Of_Serialized_Data 14 27 1 14 -ver=2: FT +ver=2: FF End_Of_Serialized_Data 14 0 2 @@ -3503,11 +3500,11 @@ Trace Window End_Of_Object VLogExportPersister 15 End_Of_Serialized_Data 14 -3 +1 0 0 290 -0 +1 160 1 "" End_Of_Object VTraceControlCfg 14 @@ -4244,7 +4241,7 @@ End_Of_Serialized_Data 14 End_Of_Object VSysVarObject 14 [Begin_of_Item] 2 13 -1 1 2 0 0 16777215 +1 1 10 0 0 16777215 0 1000 0 0 [End_of_Item] VSysVarObject 14 Begin_Of_Object @@ -4391,7 +4388,7 @@ End_Of_Object VSysVarObject 14 1 1 2 0 0 16777215 10 10000 10 0 [End_of_Item] -34 220 16 151 75 75 44 156 191 100 1 +34 220 16 167 75 75 44 156 191 100 1 35 35 30 1 1 0 1 0 0 1 1 1 0 1 @@ -4597,7 +4594,7 @@ End_Of_Object VGrMnBox 3 VDOLocalInfoStruct 3 Begin_Of_Object 3 1 -187 +191 VDAOBus 4 Begin_Of_Object 1 1 @@ -4709,7 +4706,7 @@ End_Of_Object VIPBStackSetting 8 NDebugger::VDebuggerHost 8 Begin_Of_Object 2 0 -23 +27 NDebugger::VFile 9 Begin_Of_Object 1 1 "ModbusTcpCommon.cin" @@ -4807,23 +4804,43 @@ NDebugger::VFile 9 Begin_Of_Object End_Of_Object NDebugger::VFile 9 NDebugger::VFile 9 Begin_Of_Object 1 - 1 "include\CAPL\include\ModbusUdpClientCommon.cin" -32 -End_Of_Object NDebugger::VFile 9 -NDebugger::VFile 9 Begin_Of_Object -1 1 "include\CAPL\include\TcpUdpCommon.cin" 33 End_Of_Object NDebugger::VFile 9 NDebugger::VFile 9 Begin_Of_Object 1 - 1 "include\CAPL\include\UdpCommon.cin" -34 + 1 "include\CAPL\ModbusClient.can" +35 End_Of_Object NDebugger::VFile 9 NDebugger::VFile 9 Begin_Of_Object 1 - 1 "include\CAPL\ModbusClient.can" -35 + 1 "include\CAPL\include\EilCommon.cin" +36 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\ModbusEilClientCommon.cin" +37 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\ModbusTcpClientCommon.cin" +38 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\TcpCommon.cin" +39 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\ModbusUdpClientCommon.cin" +40 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\UdpCommon.cin" +41 End_Of_Object NDebugger::VFile 9 VNETStandaloneComponent 9 Begin_Of_Object 1 @@ -4901,7 +4918,7 @@ End_Of_Object VUniqueBox 11 1 -1 0 0 0 0 0 0 0 0 0 0 0 End_Of_Object VNETControlBox 10 -156 +144 APPDIR Vector.CANoe.Debugger.DLL Vector.CANoe.Debugger, Version=8.2.40.0, Culture=neutral, PublicKeyToken=null Vector.CANoe.Debugger.DebuggerComponent @@ -4943,7 +4960,7 @@ TypeRef:3 3 Int32 NrOfFiles -8 +6 Int32 FileID0 35 @@ -4976,21 +4993,9 @@ CurrentLine4 0 Int32 FileID5 -32 -Int32 -CurrentLine5 -0 -Int32 -FileID6 33 Int32 -CurrentLine6 -0 -Int32 -FileID7 -34 -Int32 -CurrentLine7 +CurrentLine5 0 Int32 SelectedFileID @@ -5082,7 +5087,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -1202903787 +2817205760 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -5115,7 +5120,7 @@ VBoxRoot 9 Begin_Of_Object 1 3 1 1 2 3 -1 -1 -8 -30 114 0 1146 491 -Ethernet Packet Builder + 1 MDI_DOCK_INFO_END @@ -5192,8 +5197,106 @@ EOF_MBSSDATA 1 0 0 - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5204,104 +5307,6 @@ EOF_MBSSDATA - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - End_Of_Object VSSPlugInConfiguration 6 NULL @@ -5337,7 +5342,7 @@ NULL End_Of_Object VDOLocalInfoStruct 3 0.000000 0 0 -1 1 0 59420 1 233 1 2882400001 323 556 331 782 2882400002 0 0 0 0 0 0 1 2882400001 1197 1197 333 333 2882400002 0 0 0 346407864 0 345757012 3 +1 1 0 59420 1 233 1 2882400001 323 556 331 782 2882400002 0 0 0 0 0 0 1 2882400001 1197 1197 333 333 2882400002 0 0 0 528494408 0 526135044 3 SS_BEGIN_COMMON_INFO 1 0 @@ -5349,7 +5354,7 @@ Ether1 11 1 1 -525967224 1 0 1 0 1 1 0 0 0 2000 1 +345965688 1 0 1 0 1 1 0 0 0 2000 1 SS_BEGIN_COMMON_INFO 1 3 @@ -5450,8 +5455,8 @@ End_Of_Object VControlAdapter 4 1 3 WListVer 2 - 1 "..\..\..\..\..\Public\Documents\Vector\CANwin\Public\Documents\Vector\CANwin 8.0.918\templates" - 0 1 1 1 1 0 + 1 "C:\Users\Jonny\Desktop\CANoe.log" + 1 1 1 1 1 1 False 147 90 0 End_Of_Serialized_Data 3 End_Of_Object VWriteControlAdapter 3 @@ -5460,7 +5465,7 @@ End_Of_Serialized_Data 2 End_Of_Object VWriteBox 2 VWinStore 2 Begin_Of_Object 1 -22 2 3 -1 -1 -1 -1 -10088 -10000 -9070 -9233 +22 2 3 -32088 -32000 -1 -1 0 0 930 767 End_Of_Child_List End_Of_Object VWinStore 2 VWinStore 2 Begin_Of_Object @@ -5751,14 +5756,14 @@ SymbSelHeaderMgrBegin SymbSelHeaderMgrEnd End Begin -3 0 -1 +3 0 18 3 Modbus modbus Systemvariablen - ( 0 ) + ( 1 ( 1 ( 0 ) 0 ) 0 ) SymbSelHeaderMgrBegin 1 4 0 1 200 0 0 diff --git a/Modbus/include/CAPL/ModbusClient.can b/Modbus/include/CAPL/ModbusClient.can index 4393a19..0b87453 100644 --- a/Modbus/include/CAPL/ModbusClient.can +++ b/Modbus/include/CAPL/ModbusClient.can @@ -2,7 +2,7 @@ includes { - #include "include\ModbusEilClientCommon.cin" + #include "include\ModbusUdpClientCommon.cin" #include "include\ModbusFunctions.cin" } @@ -17,6 +17,7 @@ on preStart { writeClear(0); setStartdelay(10); + OutputDebugLevel = Warning; } on start @@ -49,10 +50,8 @@ void OnModbusReadBitsFailed(enum ModbusRequestError error, enum ModbusException switch (error) { case Exception: - writeLineEx(0, 3, "<%NODE_NAME%> Error: Received Exception 0x%X while reading Bits", ex); break; case Timeout: - writeLineEx(0, 2, "<%NODE_NAME%> Warning: Reading Bits timed out! Retrying..."); break; case FinalTimeout: sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputBits"); @@ -70,10 +69,8 @@ void OnModbusReadRegistersFailed(enum ModbusRequestError error, enum ModbusExcep switch (error) { case Exception: - writeLineEx(0, 3, "<%NODE_NAME%> Error: Received Exception 0x%X while reading Registers", ex); break; case Timeout: - writeLineEx(0, 2, "<%NODE_NAME%> Warning: Reading Registers timed out! Retrying..."); break; case FinalTimeout: sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); @@ -104,17 +101,11 @@ void OnModbusWriteRegistersFailed(enum ModbusRequestError error, enum ModbusExce } -void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbr, byte bitStatus[], word numBits) +void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbres, byte bitStatus[], struct ModbusReqRead mbreq) { - struct ModbusReqRead mbrq; word i; - if (!gQueueAck.ContainsKey(mbr.Header.TxID)) - return; - - memcpy_n2h(mbrq, gQueueAck[mbr.Header.TxID].Buffer); - - switch(mbrq.Address) + switch(mbreq.Address) { case 0x200: // set output bits sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputBits"); @@ -131,36 +122,30 @@ void OnModbusReadBitsSuccess(struct ModbusResReceiveBits mbr, byte bitStatus[], } } -void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbr, word numRegs) +void OnModbusReadRegistersSuccess(struct ModbusResReceiveRegisters mbres, struct ModbusReqRead mbreq) { char str[20*5]; long fehler; byte i; - struct ModbusReqRead mbrq; - if (!gQueueAck.ContainsKey(mbr.Header.TxID)) - return; - - memcpy_n2h(mbrq, gQueueAck[mbr.Header.TxID].Buffer); - - switch (mbrq.Address) + switch (mbreq.Address) { case 0x200: // set output registers sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters"); for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputRegisters; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i] = mbr.Data[i]; + @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::OutputRegisters[i] = mbres.Data[i]; sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "OutputRegisters"); break; case 0x000: // set output registers sysBeginVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); for (i = 0; i < @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::InputRegisters; i++) - @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = mbr.Data[i]; + @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data::InputRegisters[i] = mbres.Data[i]; sysEndVariableStructUpdate("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Data", "InputRegisters"); break; default: // Not recognized - dbin_to_strhex(mbr.Data, str); - writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes at 0x%04X: %s", mbr.ByteCount, mbrq.Address, str); + dbin_to_strhex(mbres.Data, str); + writeLineEx(0, 1, "<%NODE_NAME%> OnModbusReceiveRegisters: Received %d bytes at 0x%04X: %s", mbres.ByteCount, mbreq.Address, str); break; } } @@ -181,6 +166,22 @@ void OnModbusWriteMasksSuccess(struct ModbusResConfirmMasks mbc) { } +void OnModbusClientPanics(enum FatalErrors reason) +{ + writeLineEx(0, 4, "<%NODE_NAME%> FATAL! %d", reason); + switch(reason) + { + case ParsingBuffer: + case ModbusPackageWasSplit: + case DeviceCodeUnknown: + case VendorIdUnknown: + runError(1001, reason); + break; + case ConnectionError: + gtRead.Cancel(); + break; + } +} // Key events ------------------------------------------------------------------------- on timer gtRead diff --git a/Modbus/include/CAPL/include/Common.cin b/Modbus/include/CAPL/include/Common.cin index d28df3d..9c6b7f1 100644 --- a/Modbus/include/CAPL/include/Common.cin +++ b/Modbus/include/CAPL/include/Common.cin @@ -1,5 +1,187 @@ /*@!Encoding:1252*/ +variables +{ + enum DebugLvl { + Debug = 0x00, + AlgoDebug = 0x02, + ConnDebug = 0x04, + MbDebug = 0x07, + + Info = 0x10, + AlgoInfo = 0x12, + ConnInfo = 0x14, + MbInfo = 0x17, + + Warning = 0x20, + AlgoWarning = 0x22, + ConnWarning = 0x24, + MbWarning = 0x27, + + Error = 0x30, + AlgoError = 0x32, + ConnError = 0x34, + MbError = 0x37 + }; + char DebugLvlStr[4][8] = {"Debug", "Info", "Warning", "Error"}; + enum DebugLvl OutputDebugLevel = Debug; +} + +/// +void writeDbgFormat(byte lVl, char msg[], char format[]) +{ + strncpy(msg, "<%NODE_NAME%> ", elCount(msg)); + strncat(msg, DebugLvlStr[lVl], elCount(msg)); + strncat(msg, ": ", elCount(msg)); + strncat(msg, format, elCount(msg)-strlen(msg)); +} +/// +void writeDbg(enum DebugLvl lvl, char format[]) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], char string[]) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, string); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], char string1[], char string2[]) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, string1, string2); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], long num, char string[]) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, num, string); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], char string[], long num) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, string, num); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], long num1) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, num1); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, char string[]) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, num1, num2, string); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, num1, num2); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, long num3) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, num1, num2, num3); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, long num3, long num4) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, num1, num2, num3, num4); +} +/// +void writeDbg(enum DebugLvl lvl, char format[], long num1, long num2, long num3, long num4, long num5, long num6) +{ + char msg[500]; + byte lVl; + + if (lvl < OutputDebugLevel) + return; + lVl = (byte)lvl >> 4; + + writeDbgFormat(lVl, msg, format); + writeLineEx(0, lVl, msg, num1, num2, num3, num4, num5, num6); +} + + + + void bin_to_strhex(byte bin[], char result[]) { char hex_str[17] = "0123456789ABCDEF"; diff --git a/Modbus/include/CAPL/include/EilCommon.cin b/Modbus/include/CAPL/include/EilCommon.cin index 847f736..02f970b 100644 --- a/Modbus/include/CAPL/include/EilCommon.cin +++ b/Modbus/include/CAPL/include/EilCommon.cin @@ -8,6 +8,7 @@ includes variables { long gPacket; + msTimer gtArp; byte gLocalMac[6]; byte gRemoteMac[6]; @@ -23,8 +24,8 @@ word EilConnectTo(char Remote_IP[], word remotePort) remoteIp = IpGetAddressAsNumber(Remote_IP); if (remoteIp == INVALID_IP) { - writeLineEx(0, 1, "<%NODE_NAME%> Error: invalid server Ip address!"); - + writeDbg(ConnError, "EilConnectTo: invalid server Ip address!"); + OnModbusClientPanics(ConnectionError); return ipGetLastError(); } @@ -40,7 +41,8 @@ word EilConnectTo(dword remoteIp, word remotePort) { gSocketState = ERROR; error = EthGetLastError(); - writeLineEx(0, 3, "<%NODE_NAME%> EthGetMacId Error: Could not get local MAC! %d", error); + writeDbg(ConnError, "EthGetMacId: Could not get local MAC! %d", error); + OnModbusClientPanics(ConnectionError); return error; } @@ -56,7 +58,8 @@ word EilConnectTo(dword remoteIp, word remotePort) { gSocketState = ERROR; error = EthGetLastError(); - writeLineEx(0, 3, "<%NODE_NAME%> EthInitPacket Error: Could not create ARP package! %d", error); + writeDbg(ConnError, "EthInitPacket: Could not create ARP package! %d", error); + OnModbusClientPanics(ConnectionError); return error; } @@ -78,6 +81,7 @@ word EilConnectTo(dword remoteIp, word remotePort) EthOutputPacket(gPacket); EthReleasePacket(gPacket); gSocketState = NULL; + gtArp.set(@sysvar::Config::Modbus::RequestTimeout); return 0; } @@ -87,7 +91,8 @@ void EilConnectTo2() if (gPacket == 0) { gSocketState = ERROR; - writeLineEx(0, 3, "<%NODE_NAME%> EthInitPacket Error: Could not create udp packet: %d", EthGetLastError()); + writeDbg(ConnError, "EthInitPacket: Could not create UDP packet: %d", EthGetLastError()); + OnModbusClientPanics(ConnectionError); return; } @@ -118,7 +123,7 @@ void EilRecv() byte EilSnd(byte buffer[], word length) { - //char str[20*3]; + char str[20*3]; switch (gSocketState) { @@ -126,18 +131,18 @@ byte EilSnd(byte buffer[], word length) EilConnectTo(gRemoteIP, gRemotePort); if (gSocketState != OK) { - writeLineEx(0, 2, "EilSnd: Reconnecting failed!"); + writeDbg(ConnWarning, "EilSnd: Reconnecting failed! Doing nothing."); return 1; } case OK: break; default: - writeLineEx(0, 2, "EilSnd: Socket status is not OK!"); + writeDbg(ConnWarning, "EilSnd: Socket status is not OK! Doing nothing."); return 1; } - //bin_to_strhex(buffer, str); - //writeLineEx(0, 1, "<%NODE_NAME%> EilSnd: %s (Länge: %d)", str, length); + bin_to_strhex(buffer, str); + writeDbg(ConnDebug, "EilSnd: %s (Länge: %d)", str, length); EthResizeToken(gPacket, "udp", "data" , length*8); EthSetTokenData(gPacket, "udp", "data" , length, buffer); @@ -152,4 +157,11 @@ long EilGetLastConnectionError(char string[]) { EthGetLastErrorText(elCount(string), string); return EthGetLastError(); +} + +on timer gtArp +{ + gSocketState = ERROR; + writeDbg(ConnError, "No (valid) ARP response detected. The host seems to be offline!"); + OnModbusClientPanics(ConnectionError); } \ No newline at end of file diff --git a/Modbus/include/CAPL/include/ModbusClientCommon.cin b/Modbus/include/CAPL/include/ModbusClientCommon.cin index b674a06..6d85baf 100644 --- a/Modbus/include/CAPL/include/ModbusClientCommon.cin +++ b/Modbus/include/CAPL/include/ModbusClientCommon.cin @@ -3,6 +3,7 @@ includes { #include "ModbusCommonStructs.cin" + #include "Common.cin" } variables @@ -23,6 +24,20 @@ variables struct QueueElement gQueuePending[long, 2]; struct QueueElement gQueueSent[long, 2]; struct QueueElement gQueueAck[long, 2]; + + char ModbusExceptions[11][72] = { + "Illegal func code (0x01). The function code is unknown by the server", + "Illegal data address (0x02). Please check your configuration", + "Illegal data value (0x03)", + "Server failure (0x04). The server failed during execution", + "Acknowledge (0x05). The server needs more time to generate the response", + "Server busy (0x06). The request could not be accepted", + "", + "", + "", + "Gateway problem (0x0A). Gateway paths not available", + "Gateway problem (0x0B). The targeted device failed to respond" + }; } void ModbusInit() @@ -30,6 +45,7 @@ void ModbusInit() char ip[16]; sysGetVariableString("%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config", "IP", ip, elCount(ip)); + writeDbg(MbInfo, "Connecting to %s:%d", ip, @sysvar::Config::Modbus::Port); ModbusConnectTo(ip, @sysvar::Config::Modbus::Port); } @@ -57,6 +73,8 @@ void ModbusReadBits(word address, word count) mbr.Header.FuncCode = funcCode; // [1] Function Code; 1: Read Coils (DI), 2: Read Discret Inputs (DIO), seems to be the same for WAGO 750-881 mbr.Address = address; // [2] Start address mbr.Count = count; // [2] Number of items; 1:max 2000=0x7D0 + + writeDbg(MbDebug, "Sending 'Read Bits' (0x01) command. Addr: 0x%04X, Count: %d", address, count); memcpy_h2n(buffer, mbr); ModbusSend(buffer, length, mbr.Header.TxID); @@ -65,29 +83,32 @@ void ModbusReadBits(word address, word count) /// void OnModbusReceiveBits(byte buffer[]) { - struct ModbusResReceiveBits mbr; + struct ModbusResReceiveBits mbres; + struct ModbusReqRead mbreq; byte bitStatus[1968]; word numBits; byte i, j; - memcpy_n2h(mbr, buffer); + memcpy_n2h(mbres, buffer); + memcpy_n2h(mbreq, gQueueAck[mbres.Header.TxID].Buffer); - numBits = (gQueueAck[mbr.Header.TxID].Buffer[10] << 8) + gQueueAck[mbr.Header.TxID].Buffer[11]; + writeDbg(MbDebug, "Received %d bits from 0x%04X", mbreq.Count, mbreq.Address); - for (i = 0; i < mbr.ByteCount; i++) + for (i = 0; i < mbres.ByteCount; i++) { for (j = 0; j < 8; j++) { - bitStatus[8*i+j] = (mbr.Data[i] >> j) & 0x01; + bitStatus[8*i+j] = (mbres.Data[i] >> j) & 0x01; } } - OnModbusReadBitsSuccess(mbr, bitStatus, numBits); + OnModbusReadBitsSuccess(mbres, bitStatus, mbreq); } /// void OnModbusReceiveBitsException(struct ModbusApHeader mbap, enum ModbusException ex) { + writeDbg(MbError, "Received an Exception while reading bits: %s", ModbusExceptions[ex-1]); OnModbusReadBitsFailed(Exception, ex, mbap); } @@ -109,7 +130,9 @@ void ModbusReadRegisters(word address, word count) // 16 bit mbr.Header.FuncCode = funcCode; // [1] Function Code; 3: Read Holding Registers (AI), 4: Read Input Registers (AIO), seems to be the same for WAGO 750-881 mbr.Address = address; // [2] Start address mbr.Count = count; // [2] Number of items; 1:max 125=0x7D - + + writeDbg(MbDebug, "Sending 'Read Registers' (0x03) command. Addr: 0x%04X, Count: %d", address, count); + memcpy_h2n(buffer, mbr); ModbusSend(buffer, length, mbr.Header.TxID); } @@ -117,19 +140,22 @@ void ModbusReadRegisters(word address, word count) // 16 bit /// void OnModbusReceiveRegisters(byte buffer[]) { - struct ModbusResReceiveRegisters mbr; - word numRegs; + struct ModbusResReceiveRegisters mbres; + struct ModbusReqRead mbreq; - memcpy_n2h(mbr, buffer); - numRegs = (gQueueAck[mbr.Header.TxID].Buffer[10] << 8) + gQueueAck[mbr.Header.TxID].Buffer[11]; + memcpy_n2h(mbres, buffer); + memcpy_n2h(mbreq, gQueueAck[mbres.Header.TxID].Buffer); - OnModbusReadRegistersSuccess(mbr, numRegs); + writeDbg(MbDebug, "Received %d registers from 0x%04X", mbreq.Count, mbreq.Address); + + OnModbusReadRegistersSuccess(mbres, mbreq); } /// void OnModbusReceiveRegistersException(struct ModbusApHeader mbap, enum ModbusException ex) { - OnModbusReadBitsFailed(Exception, ex, mbap); + writeDbg(MbError, "Received an Exception while reading registers: %s", ModbusExceptions[ex-1]); + OnModbusReadRegistersFailed(Exception, ex, mbap); } @@ -153,6 +179,8 @@ void ModbusWriteBit(word address, byte value) mbw.Header.FuncCode = funcCode; // [1] Function Code; 5: Write Single Coil (DO) mbw.Address = address; // [2] Output address mbw.Value = value << 8; // [2] Output value (0x0000: Off, 0xFF00: On) + + writeDbg(Debug, "Sending 'Write Bit' (0x05) command. Addr: 0x%04X, Value: 0x%02X", address, value); memcpy_h2n(buffer, mbw); ModbusSend(buffer, length, mbw.Header.TxID); @@ -165,13 +193,16 @@ void OnModbusConfirmBit(byte buffer[]) memcpy_n2h(mbc, buffer); + writeDbg(MbDebug, "Set bit at 0x%04X to %d", mbc.Address, mbc.Value); + OnModbusWriteBitSuccess(mbc); } /// void OnModbusConfirmBitException(struct ModbusApHeader mbap, enum ModbusException ex) { - OnModbusReadBitsFailed(Exception, ex, mbap); + writeDbg(MbError, "Received an Exception while writing bit: %s", ModbusExceptions[ex-1]); + OnModbusWriteBitFailed(Exception, ex, mbap); } @@ -192,7 +223,9 @@ void ModbusWriteRegister(word address, int value) mbw.Header.FuncCode = funcCode; // [1] Function Code; 5: Write Single Register (AO) mbw.Address = address; // [2] Output address mbw.Value = value; // [2] Output value - + + writeDbg(MbDebug, "Sending 'Write Register' (0x06) command. Addr: 0x%04X, Value: 0x%02X", address, value); + memcpy_h2n(buffer, mbw); ModbusSend(buffer, length, mbw.Header.TxID); } @@ -204,13 +237,16 @@ void OnModbusConfirmRegister(byte buffer[]) memcpy_n2h(mbc, buffer); + writeDbg(MbDebug, "Set register at 0x%04X to %d", mbc.Address, mbc.Value); + OnModbusWriteRegisterSuccess(mbc); } /// void OnModbusConfirmRegisterException(struct ModbusApHeader mbap, enum ModbusException ex) { - OnModbusReadBitsFailed(Exception, ex, mbap); + writeDbg(MbError, "Received an Exception while writing register: %s", ModbusExceptions[ex-1]); + OnModbusWriteRegisterFailed(Exception, ex, mbap); } @@ -241,6 +277,8 @@ void ModbusWriteBits(word address, word count, byte values[]) mbw.ByteCount = dataLength; // [1] Number of bytes; = ceil(count/8) memcpy(mbw.Data, values, dataLength); // this is 1 memcpy too much -.- + writeDbg(MbDebug, "Sending 'Write Bits' (0x0F) command. Addr: 0x%04X, Count: %d", address, count); + memcpy_h2n(buffer, mbw); ModbusSend(buffer, overallLength, mbw.Header.TxID); } @@ -253,10 +291,10 @@ void ModbusWriteBitsB(word address, word count, byte values[]) dword ellCount; dword i; dword j; - ///char str1[20*2], str2[20*3]; + char str1[20*2], str2[20*3]; length = (word)_ceil(count / 8.0); - ///writeLineEx(0, 3, "count: %d; length: %d", count, length); + writeDbg(AlgoDebug, "ModbusWriteBitsB: count: %d; length: %d", count, length); if (count % 8 != 0) length--; @@ -267,20 +305,20 @@ void ModbusWriteBitsB(word address, word count, byte values[]) for (j = 0; j < 8; j++) { buffer[i] |= (values[i*8 + j] & 0x01) << j; - ///writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, i*8 + j, values[i*8 + j], (0x01 << j)); + writeDbg(AlgoDebug, "ModbusWriteBitsB: j: %d; indx: %d; value: %d; mask: %X", j, i*8 + j, values[i*8 + j], (0x01 << j)); } - ///writeLineEx(0, 3, "%d: %X", i, buffer[i]); + writeDbg(AlgoDebug, "ModbusWriteBitsB: %d: %X", i, buffer[i]); } for (j = 0; j < count % 8; j++) // wont be executed if there is no remainder { - ///writeLineEx(0, 3, "j: %d; indx: %d; value: %d; mask: %X", j, (length-1)*8 + j, values[(length-1)*8 + j], (0x01 << j)); + writeDbg(AlgoDebug, "ModbusWriteBitsB: j: %d; indx: %d; value: %d; mask: %X", j, (length-1)*8 + j, values[(length-1)*8 + j], (0x01 << j)); buffer[length] |= (values[(length)*8 + j] & 0x01) << j; } - ///writeLineEx(0, 3, "%d: %X", length-1, buffer[length-1]); + writeDbg(AlgoDebug, "ModbusWriteBitsB: %d: %X", length-1, buffer[length-1]); - ///hbin_to_strhex(values, str1); - ///bin_to_strhex(buffer, str2); - ///writeLineEx(0, 1, "<%NODE_NAME%> ModbusWriteBitsB: Encoded %s to %s", str1, str2); + hbin_to_strhex(values, str1); + bin_to_strhex(buffer, str2); + writeDbg(AlgoDebug, "ModbusWriteBitsB: Encoded %s to %s", str1, str2); ModbusWriteBits(address, count, buffer); } @@ -291,13 +329,16 @@ void OnModbusConfirmBits(byte buffer[]) memcpy_n2h(mbc, buffer); + writeDbg(MbDebug, "Updated &d bits at 0x%04X", mbc.Count, mbc.Address); + OnModbusWriteBitsSuccess(mbc); } /// void OnModbusConfirmBitsException(struct ModbusApHeader mbap, enum ModbusException ex) { - OnModbusReadBitsFailed(Exception, ex, mbap); + writeDbg(MbError, "Received an Exception while writing bits: %s", ModbusExceptions[ex-1]); + OnModbusWriteBitsFailed(Exception, ex, mbap); } @@ -341,13 +382,16 @@ void OnModbusConfirmRegisters(byte buffer[]) memcpy_n2h(mbc, buffer); + writeDbg(MbDebug, "Updated &d registers at 0x%04X", mbc.Count, mbc.Address); + OnModbusWriteRegistersSuccess(mbc); } /// void OnModbusConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex) { - OnModbusReadBitsFailed(Exception, ex, mbap); + writeDbg(MbError, "Received an Exception while writing registers: %s", ModbusExceptions[ex-1]); + OnModbusWriteRegistersFailed(Exception, ex, mbap); } @@ -382,13 +426,16 @@ void OnModbusConfirmMasks(byte buffer[]) memcpy_n2h(mbc, buffer); + writeDbg(MbDebug, "Applied masks at 0x%04X", mbc.Address); + OnModbusWriteMasksSuccess(mbc); } /// void OnModbusConfirmMasksException(struct ModbusApHeader mbap, enum ModbusException ex) { - OnModbusReadBitsFailed(Exception, ex, mbap); + writeDbg(MbError, "Received an Exception while applying masks: %s", ModbusExceptions[ex-1]); + OnModbusWriteMasksFailed(Exception, ex, mbap); } @@ -429,19 +476,22 @@ void ModbusReadWriteRegisters(word readAddress, word readCount, word writeAddres /// void OnModbusReceiveConfirmRegisters(byte buffer[]) { - byte numRegs; - struct ModbusResReceiveRegisters mbr; - memcpy_n2h(mbr, buffer); + struct ModbusResReceiveRegisters mbres; + struct ModbusReqRead mbreq; - numRegs = (gQueueAck[mbr.Header.TxID].Buffer[10] << 8) + gQueueAck[mbr.Header.TxID].Buffer[11]; + memcpy_n2h(mbres, buffer); + memcpy_n2h(mbreq, gQueueAck[mbres.Header.TxID].Buffer); - OnModbusReadRegistersSuccess(mbr, numRegs); + writeDbg(MbDebug, "Wrote some registers and received %d registers from 0x%04X", mbreq.Count, mbreq.Address); + + OnModbusReadRegistersSuccess(mbres, mbreq); } /// void OnModbusReceiveConfirmRegistersException(struct ModbusApHeader mbap, enum ModbusException ex) { - OnModbusReadBitsFailed(Exception, ex, mbap); + writeDbg(MbError, "Received an Exception while reading and writing registers: %s", ModbusExceptions[ex-1]); + OnModbusWriteRegistersFailed(Exception, ex, mbap); } @@ -455,13 +505,13 @@ void OnModbusReceiveConfirmRegistersException(struct ModbusApHeader mbap, enum M /// <-OnModbusReceive> void OnModbusReceive(dword socket, long result, dword address, dword port, byte buffer[], dword size) { - //write("OnModbusReceive: size = %d", size); + writeDbg(ConnDebug, "OnModbusReceive: Received %d bytes", size); if (result == 0) { if (size == 0) { // Size of zero indicates that the socket was closed by the communication peer. - writeLineEx(0, 2, "<%NODE_NAME%> OnModbusReceive: Socket closed by peer"); + writeDbg(ConnWarning, "OnModbusReceive: Socket closed by peer"); ModbusDisconnect(); } else @@ -473,7 +523,7 @@ void OnModbusReceive(dword socket, long result, dword address, dword port, byte else { gIpLastErr = ModbusGetLastConnectionError(gIpLastErrStr); - writeLineEx(0, 2, "<%NODE_NAME%> OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr); + writeDbg(ConnError, "OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr); ModbusDisconnect(); } } @@ -489,24 +539,23 @@ void OnModbusReceive2(byte buffer[], dword size) return; offset = 0; - //write("OnModbusReceive2: size = %d", size); do { - //write("OnModbusReceive2: offset pre = %d", offset); + writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d", offset); memcpy_n2h(mbap, buffer, offset); OnModbusReceive2OnePacket(buffer, offset, mbap); offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length; - //write("OnModbusReceive2: offset post = %d. %d <= %d?", offset, offset, size-8); + writeDbg(ConnDebug, "OnModbusReceive2: offset post = %d. %d <= %d?", offset, offset, size-8); } while(offset <= size-8); // We need at least 8 bytes for a new packet - //write("OnModbusReceive2: yes. finished", offset); + writeDbg(ConnDebug, "OnModbusReceive2: yes. finished"); if (offset != size) // Can be removed. { bin_to_strhex(buffer, str); - writeLineEx(0, 3, "OnModbusReceive2: Error while going through receive buffer. Our final offset is %d, but the size of the buffer is %d! Buffer: %s", offset, size, str); - runError(1002, 1); + writeDbg(ConnError, "OnModbusReceive2: Error while going through receive buffer. Our final offset is %d, but the size of the buffer is %d! Buffer: %s", offset, size, str); + OnModbusClientPanics(ParsingBuffer); } } @@ -521,16 +570,16 @@ void OnModbusReceive2OnePacket(byte buffer[], int offset, struct ModbusApHeader length = __offset_of(struct ModbusApHeader, UnitID) + mbap.Length; // We cannot check this properly anymore. We have to trust the TCP/UDP stack and the sender... *sigh* - if (elCount(buffer) < offset + length) // TCP packet not as large enough - { - writeLineEx(0, 3, "<%NODE_NAME%> OnModbusReceive Error: Modbus packet did not fit into Buffer: buffer length = %d, packet length = %d, offset = %d", elCount(buffer), __offset_of(struct ModbusApHeader, UnitID) + mbap.Length, offset); - // I REALLY don't want to assemble the two package fragments. - runError(1001,1); - return; - } if (mbap.Protocol != 0) // Protocol is not Modbus (0x0000). Wayne. { - writeLineEx(0, 2, "<%NODE_NAME%> OnModbusReceive Error: Tcp packet is no Modbus packet: Protocol = %d", mbap.Protocol); + writeDbg(ConnDebug, "OnModbusReceive2OnePacket: packet is no Modbus packet: Protocol = %d", mbap.Protocol); + return; + } + if (elCount(buffer) < offset + length) // packet larger than the (rest of the) buffer + { + writeDbg(ConnError, "OnModbusReceive2OnePacket: packet did not fit into Buffer: buffer length = %d, packet length = %d, offset = %d", elCount(buffer), __offset_of(struct ModbusApHeader, UnitID) + mbap.Length, offset); + // I REALLY don't want to assemble the two package fragments. + OnModbusClientPanics(ModbusPackageWasSplit); return; } // MBAP Header is OK :) Go on @@ -585,7 +634,7 @@ void OnModbusReceive2OnePacket(byte buffer[], int offset, struct ModbusApHeader OnModbusReceiveConfirmRegisters(mbuffer); break; default: - writeLineEx(0, 3, "We received funcCode 0x%X?", mbap.FuncCode); + writeDbg(MbError, "OnModbusReceive2OnePacket: We received funcCode 0x%X!?", mbap.FuncCode); } gQueueAck.Remove(mbap.TxID); // Remove from acknowledge queue @@ -596,33 +645,6 @@ void OnModbusReceive2Exceptions(byte exCode, struct ModbusApHeader mbap) { enum ModbusException ex; ex = (enum ModbusException)exCode; - switch(exCode) // Let's have a look at the reason - { - case 0x01: // Illegal function code: Implementation failure! - writeLineEx(0, 3, "<%NODE_NAME%> Exception: Illegal function code (0x01). The function code %d is unknown by the server.", mbap.FuncCode & 0x0F); - break; - case 0x02: // Illegal data address: Configuration failure! - writeLineEx(0, 3, "<%NODE_NAME%> Exception: Illegal data address (0x02). Please check your configuration!"); - break; - case 0x03: // Illegal data value: Depends. - writeLineEx(0, 3, "<%NODE_NAME%> Exception: Illegal data value (0x03)."); - break; - case 0x04: // Server failure: We can't do anything about that, can we? - writeLineEx(0, 3, "<%NODE_NAME%> Exception: Server failure (0x04). The server failed during execution."); - break; - case 0x05: // Acknowledge: That's ok. - writeLineEx(0, 1, "<%NODE_NAME%> Exception: Acknowledge (0x05). The server simply needs more time to generate the response."); - break; - case 0x06: // Server busy: We should resend the request. - writeLineEx(0, 3, "<%NODE_NAME%> Exception: Server busy (0x06). The request could not be accepted."); - break; - case 0x0A: // Gateway problem: We don't have gateways :) - writeLineEx(0, 3, "<%NODE_NAME%> Exception: Gateway problem (0x0A). Gateway paths not available."); - break; - case 0x0B: // Gateway problem: We don't have gateways :) - writeLineEx(0, 3, "<%NODE_NAME%> Exception: Gateway problem (0x0B). The targeted device failed to respond."); - break; - } switch (mbap.FuncCode) { @@ -667,9 +689,16 @@ void ModbusSend(byte buffer[], word length, word TxID) memcpy(qe.Buffer, buffer, length); memcpy(gQueuePending[TxID], qe); + writeDbg(ConnDebug, "Appended packet 0x%04X to pending queue", TxID); - if (gQueuePending.Size() == 1 && gQueueSent.Size() == 0) // start timer at beginning - setTimerCyclic(gtRobin, 1); + if (gQueuePending.Size() == 1 && gQueueSent.Size() == 0 && gSocketState == OK) // start timer if connection established + ModbusStartQueue(); +} + +void ModbusStartQueue() +{ + writeDbg(ConnDebug, "Starting Timer gtRobin"); + setTimerCyclic(gtRobin, 1); } /// <-ModbusSend> @@ -678,7 +707,7 @@ on timer gtRobin struct ModbusApHeader mbap; enum ModbusRequestError reqError; - ///writeLineEx(0, 1, "Queue Sent: %d, Queue Pending: %d, Queue Ack: %d", gQueueSent.Size(), gQueuePending.Size(), gQueueAck.Size()); + writeDbg(ConnDebug, "gtRobin: Queue Sent: %d, Queue Pending: %d, Queue Ack: %d", gQueueSent.Size(), gQueuePending.Size(), gQueueAck.Size()); // First: check timeouts = packets that were sent in previous run and not removed by response for (long TxID : gQueueSent) @@ -688,6 +717,7 @@ on timer gtRobin // timed out! if (++gQueueSent[TxID].Timeouts < @sysvar::Config::Modbus::MaxTransmissionCount) // if we may resend it { + writeDbg(ConnInfo, "Packet 0x%04X timed out! Retrying...", TxID); gQueueSent[TxID].TimeoutTicks = 0; ModbusSnd(gQueueSent[TxID].Buffer, gQueueSent[TxID].Length); // resend it reqError = Timeout; @@ -695,11 +725,12 @@ on timer gtRobin } else // we will NOT resend it { + writeDbg(ConnWarning, "Packet 0x%04X timed out! Giving up", TxID); reqError = FinalTimeout; } memcpy_n2h(mbap, gQueueSent[TxID].Buffer); - switch(mbap.FuncCode) // throw an error in each case + switch(mbap.FuncCode) // throw an "error" in each case { case ReadBits1: case ReadBits2: @@ -739,15 +770,18 @@ on timer gtRobin if (gQueueSent.Size() > 4) // Wago 750-881 cannot handle more than 5 messages at a time :( continue; - - if (ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0) // if packet was sent + // if packet was sent or the socket is not currently being opened + if (ModbusSnd(gQueuePending[TxID].Buffer, gQueuePending[TxID].Length) == 0 || gSocketState != NULL) { - memcpy(gQueueSent[TxID], gQueuePending[TxID]); // move packet to sent queue + memcpy(gQueueSent[TxID], gQueuePending[TxID]); // move packet to sent queue gQueuePending.Remove(TxID); ModbusRecv(); } } - if (gQueueSent.Size() == 0) // Stop timer to reduce latency of first packet + if (gSocketState == ERROR || gQueueSent.Size() == 0 && gQueuePending.Size() == 0) // Stop timer to reduce latency of first packet + { + writeDbg(ConnDebug, "Stopping Timer gtRobin"); this.Cancel(); + } } \ No newline at end of file diff --git a/Modbus/include/CAPL/include/ModbusCommonStructs.cin b/Modbus/include/CAPL/include/ModbusCommonStructs.cin index 017af54..814eff7 100644 --- a/Modbus/include/CAPL/include/ModbusCommonStructs.cin +++ b/Modbus/include/CAPL/include/ModbusCommonStructs.cin @@ -133,4 +133,14 @@ variables MaskRegister = 0x16, ReadWriteRegisters = 0x17 }; + + + enum FatalErrors + { + ParsingBuffer = 0x00, + ModbusPackageWasSplit = 0x01, + DeviceCodeUnknown = 0x02, + VendorIdUnknown = 0x03, + ConnectionError = 0x04 + }; } \ No newline at end of file diff --git a/Modbus/include/CAPL/include/ModbusEilClientCommon.cin b/Modbus/include/CAPL/include/ModbusEilClientCommon.cin index 232b736..06c6ae3 100644 --- a/Modbus/include/CAPL/include/ModbusEilClientCommon.cin +++ b/Modbus/include/CAPL/include/ModbusEilClientCommon.cin @@ -48,12 +48,17 @@ void OnEthReceivePacket(long channel, long dir, long packet) { if (EthGetTokenData(packet, "arp", "hwSourceAddr", elCount(gRemoteMac), gRemoteMac) == 6) { - write("remote Mac: %02X:%02X:%02X:%02X:%02X:%02X", gRemoteMac[0], gRemoteMac[1], gRemoteMac[2], gRemoteMac[3], gRemoteMac[4], gRemoteMac[5]); + gtArp.Cancel(); + writeDbg(ConnDebug, "Remote Mac: %02X:%02X:%02X:%02X:%02X:%02X", gRemoteMac[0], gRemoteMac[1], gRemoteMac[2], gRemoteMac[3], gRemoteMac[4], gRemoteMac[5]); EilConnectTo2(); // create the UDP package + ModbusStartQueue(); } return; } + if (EthGetTokenInt(packet, "ipv4", "protocol") == 0x11 && EthGetTokenInt(packet, "ipv4", "source") == gRemoteIP) // if this is a UDP package from our server + { size = EthGetThisData(0, gMaxPacketLength, buffer); - OnModbusReceive(0, 0, EthGetTokenInt(packet, "ipv4", "source"), EthGetTokenInt(packet, "udp", "source"), buffer, size); + OnModbusReceive(0, 0, EthGetTokenInt(packet, "ipv4", "source"), gRemoteIP, buffer, size); + } } \ No newline at end of file diff --git a/Modbus/include/CAPL/include/ModbusFunctions.cin b/Modbus/include/CAPL/include/ModbusFunctions.cin index fcc7ed1..853a724 100644 --- a/Modbus/include/CAPL/include/ModbusFunctions.cin +++ b/Modbus/include/CAPL/include/ModbusFunctions.cin @@ -45,8 +45,8 @@ void ParseDeviceCode(word dev, enum Vendor vendor, struct deviceIOs dios) } else // blööd { - writeLineEx(0, 3, "<%NODE_NAME%> Device code 0x%X cannot be decoded", dev); - runError(1003, 1); + writeDbg(AlgoError, "ParseDeviceCode: Device code 0x%X cannot be decoded", dev); + OnModbusClientPanics(DeviceCodeUnknown); } } else @@ -60,7 +60,7 @@ void ParseDeviceCode(word dev, enum Vendor vendor, struct deviceIOs dios) numChannels = 2; break; default: // unknown device. Ouch! - writeLineEx(0, 2, "<%NODE_NAME%> Connected device: 750-%d", dev); + writeDbg(AlgoInfo, "Connected device: 750-%d", dev); return; } if (input) @@ -76,7 +76,8 @@ void ParseDeviceCode(word dev, enum Vendor vendor, struct deviceIOs dios) } break; // switch(vendor) default: - writeLineEx(0, 2, "<%NODE_NAME%> Unknown vendor id: %d", vendor); + writeDbg(AlgoError, "ParseDeviceCode: Unknown vendor id: %d", vendor); + OnModbusClientPanics(VendorIdUnknown); return; } diff --git a/Modbus/include/CAPL/include/TcpCommon.cin b/Modbus/include/CAPL/include/TcpCommon.cin index ae91df8..857d42b 100644 --- a/Modbus/include/CAPL/include/TcpCommon.cin +++ b/Modbus/include/CAPL/include/TcpCommon.cin @@ -13,35 +13,42 @@ variables word TcpOpenSocket() { - char Local_IP[16]; - dword localIp; - word localPort; - dword i = 0; + byte i; CHAR errorText[200]; + long error; + + if (EthGetAdapterStatus() != 2) // Not connected + { + writeDbg(ConnError, "TcpOpenSocket: Adapter status not ok: %d!", EthGetAdapterStatus()); + OnModbusClientPanics(ConnectionError); + return INVALID_IP; + } // Try to open socket + i = 0; do { gSocket = TcpSocket::Open(0, 0); - if (gSocket.GetLastSocketError() != 0) + error = gSocket.GetLastSocketError(); + if (error != 0) { gSocket.GetLastSocketErrorAsString(errorText, elcount(errorText)); - writeLineEx(0, 1, "<%NODE_NAME%> Error: could not open Tcp socket: %s (%d)!", errorText, gSocket.GetLastSocketError()); + writeDbg(ConnInfo, "TcpOpenSocket: could not open socket: (%d) %s", error, errorText); } } - while (gSocket.GetLastSocketError() != 0 && i++ < 9); + while (error != 0 && i++ < 9); - if (gSocket.GetLastSocketError() != 0) + if (error != 0) { - writeLineEx(0, 1, "<%NODE_NAME%> Error: could not open Tcp socket!"); - return gSocket.GetLastSocketError(); + writeDbg(ConnError, "TcpOpenSocket: could not open socket: (%d) %s", error, errorText); + OnModbusClientPanics(ConnectionError); + return error; } else { - writeLineEx(0, 1, "<%NODE_NAME%> Tcp socket opened."); + writeDbg(ConnInfo, "Tcp socket opened."); } return 0; - } word TcpConnectTo(char Remote_IP[], word remotePort) @@ -52,8 +59,8 @@ word TcpConnectTo(char Remote_IP[], word remotePort) remoteIp = IpGetAddressAsNumber(Remote_IP); if (remoteIp == INVALID_IP) { - writeLineEx(0, 1, "<%NODE_NAME%> Error: invalid server Ip address!"); - + writeDbg(ConnError, "TcpConnectTo: invalid server Ip address: %s", Remote_IP); + OnModbusClientPanics(ConnectionError); return 1; } @@ -83,15 +90,16 @@ word TcpConnectTo(dword remoteIp, word remotePort) if (fehler != WSAEWOULDBLOCK) // OnTcpConnect will be called otherwise { - write("<%NODE_NAME%> No Port-Connection: %d", fehler); + writeDbg(ConnError, "TcpConnectTo: No connection established: %d", fehler); gSocketState = ERROR; + OnModbusClientPanics(ConnectionError); return fehler; } return 0; } else { - writeLineEx(0, 1, "<%NODE_NAME%> Successfully connected to server"); + writeDbg(ConnInfo, "TcpConnectTo: Successfully connected to server"); gSocketState = OK; return 0; } @@ -102,14 +110,16 @@ void OnTcpConnect(dword socket, long result) if (result != 0) { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writeLineEx(0, 2, "<%NODE_NAME%> OnTcpConnect error (%d): %s", gSocket.GetLastSocketError(), gIpLastErrStr); + writeDbg(ConnError, "OnTcpConnect: (%d) %s", gSocket.GetLastSocketError(), gIpLastErrStr); gSocketState = ERROR; + OnModbusClientPanics(ConnectionError); return; } else { - writeLineEx(0, 1, "<%NODE_NAME%> Successfully connected to server"); + writeDbg(ConnInfo, "OnTcpConnect: Successfully connected to server"); gSocketState = OK; + ModbusStartQueue(); } } @@ -125,7 +135,8 @@ void TcpRecv() if (gSocketState != OK) { - writeLineEx(0, 2, "TcpRecv: Socket status is not OK!"); + writeDbg(ConnWarning, "TcpRecv: Socket status is not OK! Doing nothing."); + OnModbusClientPanics(ConnectionError); return; } @@ -138,9 +149,8 @@ void TcpRecv() if (gIpLastErr != WSA_IO_PENDING) // Calling OnTcpReceive otherwise { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writeLineEx(0, 2, "<%NODE_NAME%> TcpReceive error (%d): %s", gIpLastErr, gIpLastErrStr); - gSocket.Close(); - gSocketState = CLOSED; + writeDbg(ConnError, "TcpReceive: (%d) %s", gIpLastErr, gIpLastErrStr); + TcpDisconnect(); } } @@ -149,7 +159,7 @@ void TcpRecv() word TcpSnd(byte buffer[], word length) { - //char str[20*3]; + char str[20*3]; switch (gSocketState) { @@ -157,18 +167,20 @@ word TcpSnd(byte buffer[], word length) TcpConnectTo(gRemoteIP, gRemotePort); if (gSocketState != OK) { - writeLineEx(0, 2, "<%NODE_NAME%> TcpSnd: Reconnecting failed!"); + writeDbg(ConnError, "TcpSnd: Reconnecting failed!"); + OnModbusClientPanics(ConnectionError); return 1; } case OK: break; default: - writeLineEx(0, 2, "<%NODE_NAME%> TcpSnd: Socket status is not OK!"); + writeDbg(ConnError, "TcpSnd: Socket status is not OK! Doing nothing."); + OnModbusClientPanics(ConnectionError); return 1; } - //bin_to_strhex(buffer, str); - //writeLineEx(0, 1, "<%NODE_NAME%> TcpSnd: %s (Länge: %d)", str, length); + bin_to_strhex(buffer, str); + writeDbg(ConnDebug, "TcpSnd: %s (Länge: %d)", str, length); if (gSocket.Send(buffer, length) != 0) { @@ -177,7 +189,7 @@ word TcpSnd(byte buffer[], word length) if (gIpLastErr != WSA_IO_PENDING) { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writeLineEx(0, 2, "<%NODE_NAME%> TcpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); + writeDbg(ConnError, "TcpSnd: (%d) %s", gIpLastErr, gIpLastErrStr); TcpDisconnect(); return 1; } diff --git a/Modbus/include/CAPL/include/UdpCommon.cin b/Modbus/include/CAPL/include/UdpCommon.cin index 8b8f1e6..b691796 100644 --- a/Modbus/include/CAPL/include/UdpCommon.cin +++ b/Modbus/include/CAPL/include/UdpCommon.cin @@ -14,11 +14,13 @@ variables word UdpOpenSocket() { byte i; - CHAR errorText[200]; + char errorText[200]; + long error; if (EthGetAdapterStatus() != 2) // Not connected { - writeLineEx(0, 3, "<%NODE_NAME%> Error: Adapter status not ok: %d!", EthGetAdapterStatus()); + writeDbg(ConnError, "UdpOpenSocket: Adapter status not ok: %d!", EthGetAdapterStatus()); + OnModbusClientPanics(ConnectionError); return INVALID_IP; } @@ -26,26 +28,27 @@ word UdpOpenSocket() i = 0; do { - gSocket = UdpSocket::Open(0, 0); // Open socket on any IP and Port - if (gSocket.GetLastSocketError() != 0) + gSocket = UdpSocket::Open(0, 0); + error = gSocket.GetLastSocketError(); + if (error != 0) { gSocket.GetLastSocketErrorAsString(errorText, elcount(errorText)); - writeLineEx(0, 1, "<%NODE_NAME%> Error: could not open Udp socket: %s (%d)!", errorText, gSocket.GetLastSocketError()); + writeDbg(ConnInfo, "UdpOpenSocket: could not open socket: (%d) %s", error, errorText); } } - while (gSocket.GetLastSocketError() != 0 && i++ < 5); + while (error != 0 && i++ < 9); - if (gSocket.GetLastSocketError() != 0) + if (error != 0) { - writeLineEx(0, 1, "<%NODE_NAME%> Error: could not open Udp socket!"); - return gSocket.GetLastSocketError(); + writeDbg(ConnError, "UdpOpenSocket: could not open socket: (%d) %s", error, errorText); + OnModbusClientPanics(ConnectionError); + return error; } else { - writeLineEx(0, 1, "<%NODE_NAME%> Udp socket opened."); + writeDbg(ConnInfo, "Udp socket opened."); } return 0; - } word UdpConnectTo(char Remote_IP[], word remotePort) @@ -56,8 +59,8 @@ word UdpConnectTo(char Remote_IP[], word remotePort) remoteIp = IpGetAddressAsNumber(Remote_IP); if (remoteIp == INVALID_IP) { - writeLineEx(0, 1, "<%NODE_NAME%> Error: invalid server Ip address!"); - + writeDbg(ConnError, "UdpConnectTo: invalid server Ip address: %s", Remote_IP); + OnModbusClientPanics(ConnectionError); return 1; } @@ -94,7 +97,8 @@ void UdpRecv() if (gSocketState != OK) { - writeLineEx(0, 2, "<%NODE_NAME%> UdpRecv: Socket status is not OK!"); + writeDbg(ConnError, "UdpRecv: Socket status is not OK! Doing nothing."); + OnModbusClientPanics(ConnectionError); return; } @@ -107,18 +111,17 @@ void UdpRecv() if (gIpLastErr != WSA_IO_PENDING) // Calling OnUdpReceive otherwise { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elCount(gIpLastErrStr)); - writeLineEx(0, 2, "<%NODE_NAME%> UdpReceiveFrom Error (%d): %s", gIpLastErr, gIpLastErrStr); - gSocket.Close(); - gSocketState = CLOSED; + writeDbg(ConnError, "UdpReceiveFrom Error (%d): %s", gIpLastErr, gIpLastErrStr); + UdpDisconnect(); } } return; } -void UdpSnd(byte buffer[], word length) +byte UdpSnd(byte buffer[], word length) { - //char str[20*3]; + char str[20*3]; switch (gSocketState) { @@ -126,18 +129,20 @@ void UdpSnd(byte buffer[], word length) UdpConnectTo(gRemoteIP, gRemotePort); if (gSocketState != OK) { - writeLineEx(0, 2, "<%NODE_NAME%> UdpSnd: Reconnecting failed!"); + writeDbg(ConnError, "UdpSnd: Reconnecting failed!"); + OnModbusClientPanics(ConnectionError); return 1; } case OK: break; default: - writeLineEx(0, 2, "<%NODE_NAME%> UdpSnd: Socket status is not OK!"); + writeDbg(ConnError, "UdpSnd: Socket status is not OK! Doing nothing."); + OnModbusClientPanics(ConnectionError); return 1; } - //bin_to_strhex(buffer, str); - //writeLineEx(0, 1, "<%NODE_NAME%> UdpSnd: %s (Länge: %d)", str, length); + bin_to_strhex(buffer, str); + writeDbg(ConnDebug, "UdpSnd: %s (Länge: %d)", str, length); if (gSocket.SendTo(gRemoteIP, gRemotePort, buffer, length) != 0) { @@ -146,7 +151,7 @@ void UdpSnd(byte buffer[], word length) if (gIpLastErr != WSA_IO_PENDING) { gSocket.GetLastSocketErrorAsString(gIpLastErrStr, elcount(gIpLastErrStr)); - writeLineEx(0, 2, "<%NODE_NAME%> UdpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); + writeDbg(ConnError, "UdpSnd error (%d): %s", gIpLastErr, gIpLastErrStr); UdpDisconnect(); return 1; }