From 13c03dd8077efc78ee392958c97528db90287369 Mon Sep 17 00:00:00 2001 From: Jonny007-MKD Date: Mon, 2 Jun 2014 12:16:23 +0000 Subject: [PATCH] ModbusClientCommon.cin Changed timer to support EilDll ModbusStructs.cin Removed header from all structs ModbusProtocol.cpp Fixed data length issue (l. 353) More precise info in InspectProtocol() New getter: GetAddrNCount() --- Modbus-DLL/ModbusNet.cfg | 360 ++++++++++-------- Modbus-DLL/include/CAPL/ModbusClient.can | 11 +- Modbus-DLL/include/CAPL/ModbusClient.cbf | Bin 188272 -> 188303 bytes .../CAPL/include/ModbusClientCommon.cin | 70 ++-- .../include/CAPL/include/ModbusStructs.cin | 13 +- .../ModbusProtocolDLL/ModbusProtocol.cpp | 114 ++++-- .../ModbusProtocolDLL/ModbusProtocol.dll | Bin 75264 -> 75264 bytes .../ModbusProtocolDLL/ModbusProtocol.h | 11 +- .../ModbusProtocolDLL/ModbusProtocol.ilk | Bin 1134988 -> 1382636 bytes .../ModbusProtocolDLL/ModbusProtocolDLL.cpp | 2 +- Modbus-DLL/log.txt | 39 +- 11 files changed, 334 insertions(+), 286 deletions(-) diff --git a/Modbus-DLL/ModbusNet.cfg b/Modbus-DLL/ModbusNet.cfg index ae6f88a..5c8bf72 100644 --- a/Modbus-DLL/ModbusNet.cfg +++ b/Modbus-DLL/ModbusNet.cfg @@ -1,4 +1,4 @@ -;CANoe Version |4|7|1|38833 ModbusNet +;CANoe Version |4|7|1|38817 ModbusNet Version: 8.2.40 Build 40 32 PRO 10 @@ -67,25 +67,24 @@ DialogBegin 1 285 569 816 1103 SymbolExplorerDialogBegin - 1 HistoryBegin 1 0 HistoryEnd FiltersBegin Begin -3 0 -1 +3 0 2 5 Bus statistic signals ( 1 ( 1 ( 0 ) 0 ) 0 ) -Busstatistik Signale - ( 1 ( 1 ( 0 ) 0 ) 0 ) Modbus ( 2 ( 0 ) 0) TE0001 ( 2 ( 2 ( 0 ) 0 ) 0 ) TE0002 ( 2 ( 2 ( 0 ) 0 ) 0 ) +Busstatistik Signale + ( 1 ( 0 ) 0 ) SymbSelHeaderMgrBegin 1 6 0 1 278 0 0 @@ -214,7 +213,7 @@ Begin Modbus Systemvariablen - ( 1 ( 1 ( 0 ) 2 ( 0 ) 0 ) 3 ( 1 ( 2 ( 3 ( 0 ) 0 ) 0 ) 0 ) 0 ) + ( 1 ( 1 ( 0 ) 0 ) 0 ) SymbSelHeaderMgrBegin 1 4 0 1 200 0 0 @@ -333,7 +332,7 @@ SymbSelHeaderMgrEnd End FiltersEnd -1 12 +1 0 SymbolExplorerDialogEnd DialogEnd @@ -742,9 +741,9 @@ Begin_Of_Multi_Line_String Copyright (c) 2001-2006 Actipro Software LLC. All rights reserved. http://www.ActiproSoftware.com/Products/DotNet/ ---> 1 "ModbusTcpCommon.cin" @@ -4850,6 +4879,16 @@ NDebugger::VFile 9 Begin_Of_Object 1 "include\CAPL\include\ModbusStructs.cin" 42 End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\EilDllCommon.cin" +43 +End_Of_Object NDebugger::VFile 9 +NDebugger::VFile 9 Begin_Of_Object +1 + 1 "include\CAPL\include\ModbusEilDllClientCommon.cin" +44 +End_Of_Object NDebugger::VFile 9 VNETStandaloneComponent 9 Begin_Of_Object 1 VNETControlBox 10 Begin_Of_Object @@ -4859,23 +4898,24 @@ VUniqueBox 11 Begin_Of_Object VBoxRoot 12 Begin_Of_Object 1 3 -1 -1 2 3 -1 -1 -8 -30 171 76 688 306 -Debugger - Client_2 +1 -1 0 1 -1 -1 -1 -1 35 -12 567 364 +Debugger - Programm: Client_2 [Debugging ausgeschaltet] 1 MDI_DOCK_INFO_END 5 1 6 -2 3 -1 -1 -1 -1 171 76 688 306 -6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 +0 1 -1 -1 -1 -1 35 -12 567 364 +6 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 END_OF_DOCK_INFO 0 -1 +1 +0 1 -1 -1 -1 -1 6 66 542 446 0 -0 -0 -859 382 +1 +157 389 END_OF_DESKTOP_DATA 6 0 1 0 0 -1 -1 171 76 688 306 @@ -5089,7 +5129,7 @@ VSimulinkModelViewerConfiguration 7 Begin_Of_Object End_Of_Object VSimulinkModelViewerConfiguration 7 1 0 -657298843 +1716208489 0 NodeSignalPanelBustypeCount 0 End_Of_Object VSimulationNode 6 @@ -5122,7 +5162,7 @@ VBoxRoot 9 Begin_Of_Object 1 3 1 1 1 1 0 166 -8 -30 61 86 1093 577 - +Ethernet Packet Builder 1 MDI_DOCK_INFO_END @@ -5200,105 +5240,11 @@ EOF_MBSSDATA 1 0 1 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + @@ -5309,10 +5255,104 @@ EOF_MBSSDATA - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + End_Of_Object VSSPlugInConfiguration 6 NULL @@ -5348,7 +5388,7 @@ NULL End_Of_Object VDOLocalInfoStruct 3 0.000000 0 0 -1 1 0 59420 1 176 1 2882400001 639 815 319 694 2882400002 0 0 0 0 0 0 1 2882400001 1280 1280 321 321 2882400002 0 0 0 1437687448 0 0 3 +1 1 0 59420 1 176 1 2882400001 639 815 319 694 2882400002 0 0 0 0 0 0 1 2882400001 1280 1280 321 321 2882400002 0 0 0 0 0 0 3 SS_BEGIN_COMMON_INFO 1 0 @@ -5360,14 +5400,12 @@ Ether1 11 1 1 -504289040 1 0 1 0 1 1 0 81 42 2000 1 +492214664 1 0 1 0 1 1 0 0 0 2000 1 SS_BEGIN_COMMON_INFO 1 -3 +2 Channels 1 -Databases -1 Misc 1 SS_END_COMMON_INFO @@ -5471,7 +5509,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 -10088 -10000 -9070 -9233 End_Of_Child_List End_Of_Object VWinStore 2 VWinStore 2 Begin_Of_Object @@ -5792,6 +5830,7 @@ End FiltersEnd 1 1 + END_OF_WORKSPACE_MEMBER_DATA END_OF_WORKSPACE_MEMBER 1 @@ -6365,7 +6404,7 @@ VUniqueBox 4 Begin_Of_Object VBoxRoot 5 Begin_Of_Object 1 3 -1 1 1 1 160 166 -1 -1 172 63 788 501 +1 1 0 1 -1 -1 -1 -1 4 7 620 445 Startwerte 1 @@ -6373,15 +6412,16 @@ MDI_DOCK_INFO_END 5 1 6 -1 1 160 166 -1 -1 172 63 788 501 -6 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 +0 1 -1 -1 -1 -1 4 7 620 445 +6 3 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 -1 -1 32767 0 0 0 0 0 0 0 0 0 0 -1 -1 0 0 0 0 0 0 END_OF_DOCK_INFO 0 1 -0 +1 +0 1 -1 -1 -1 -1 242 174 862 616 0 1 -963 193 +95 389 END_OF_DESKTOP_DATA 6 0 1 0 0 -1 -1 199 118 815 556 diff --git a/Modbus-DLL/include/CAPL/ModbusClient.can b/Modbus-DLL/include/CAPL/ModbusClient.can index af2bfa7..5391fad 100644 --- a/Modbus-DLL/include/CAPL/ModbusClient.can +++ b/Modbus-DLL/include/CAPL/ModbusClient.can @@ -10,8 +10,8 @@ variables { msTimer gtRead; - message Client_2_RecBits rb; - message Client_2_Ex81 ex; + //message Client_2_RecBits rb; + //message Client_2_Ex81 ex; } // Get information of local network interface such like ip address @@ -20,14 +20,13 @@ on preStart { writeClear(0); setStartdelay(10); - OutputDebugLevel = Warning; + OutputDebugLevel = Debug; } on start { ModbusInit(); - // Read serial code, additional stuff is done in OnModbusReceiveRegisters // This has to be done by MakeConfig to properly size the arrays //ModbusReadRegisters(0x2011, 1); @@ -36,8 +35,8 @@ on start //ModbusReadRegisters(0x2031, 64); //ModbusReadRegisters(0x2032, 64); //ModbusReadRegisters(0x2033, 63); - if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits > 0) - ModbusReadBits(0x200, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits); + //if (@sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits > 0) + // ModbusReadBits(0x200, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Info::OutputBits); setTimerCyclic(gtRead, 1, @sysvar::%BUS_TYPE%%CHANNEL%::%NODE_NAME%::Config::Interval); } diff --git a/Modbus-DLL/include/CAPL/ModbusClient.cbf b/Modbus-DLL/include/CAPL/ModbusClient.cbf index bc161f47b9e6ecaee321ebe9153d995ccb89a11c..064c745d5a887850748a7dade8e137ad6b80d5d1 100644 GIT binary patch delta 15779 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 delta 15829 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 ZB(fEPQ{z)uLcw^z!2^(Z8V2AS@IT%`6j=ZO diff --git a/Modbus-DLL/include/CAPL/include/ModbusClientCommon.cin b/Modbus-DLL/include/CAPL/include/ModbusClientCommon.cin index a81aa5d..bc2df20 100644 --- a/Modbus-DLL/include/CAPL/include/ModbusClientCommon.cin +++ b/Modbus-DLL/include/CAPL/include/ModbusClientCommon.cin @@ -7,7 +7,7 @@ includes variables { - const word gMaxPacketLength = 259; //__size_of(struct ModbusReqWriteRegisters); + const word gMaxPacketLength = __size_of(struct ModbusReqWriteRegisters); msTimer gtRobin; // Timer that sends the packets and watches for timeouts word gTxID = 0x0000; // Transaction Identifier for Modbus. Used as index for gQueue @@ -15,6 +15,7 @@ variables // Global storage for pending and sent requests, associated by TxID struct QueueElement { + byte FuncCode; word TimeoutTicks; byte Timeouts; word Length; @@ -48,32 +49,23 @@ void ModbusInit() ModbusConnectTo(ip, @sysvar::Config::Modbus::Port); } -void ModbusMakeHeader(struct ModbusApHeader mbap, word length) -{ - EthSetTokenInt(gPacket, "modbus", "TxId", gTxID++); -} - // REGION: ModbusReadBits ------------------------------------------------------------- /// void ModbusReadBits(word address, word count) { - const byte length = 12; //__size_of(struct ModbusReqRead); + const byte length = __size_of(struct ModbusReqRead); const byte funcCode = 0x01; - byte buffer[4] = {0x0B, 0x22, 0x00, 0x02}; struct ModbusReqRead mbr; - ModbusMakeHeader(mbr.Header, length); - // Payload - EthSetTokenInt(gPacket, "modbus", "FuncCode", funcCode); - EthResizeToken(gPacket, "modbus", "data" , 4*8); - EthSetTokenData(gPacket, "modbus", "data" , 4, buffer); + mbr.Address = address; + mbr.Count = count; writeDbg(MbDebug, "Sending 'Read Bits' (0x01) command. Addr: 0x%04X, Count: %d", address, count); - - EthCompletePacket(gPacket); - EthOutputPacket(gPacket); + + memcpy_h2n(buffer, mbr); + ModbusSend(buffer, length, funcCode); } /// @@ -120,17 +112,14 @@ void ModbusReadRegisters(word address, word count) // 16 bit const byte funcCode = 0x03; byte buffer[length]; struct ModbusReqRead mbr; - - ModbusMakeHeader(mbr.Header, length); - // Payload - 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); + ModbusSend(buffer, length, funcCode); } /// @@ -170,16 +159,13 @@ void ModbusWriteBit(word address, byte value) if (value >= 1) value = 0xFF; - ModbusMakeHeader(mbw.Header, length); - // Payload - 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); + ModbusSend(buffer, length, funcCode); } /// @@ -214,16 +200,13 @@ void ModbusWriteRegister(word address, int value) byte buffer[length]; struct ModbusReqWriteSingle mbw; - ModbusMakeHeader(mbw.Header, length); - // Payload - 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); + ModbusSend(buffer, length, funcCode); } /// @@ -265,9 +248,7 @@ void ModbusWriteBits(word address, word count, byte values[]) dataLength = _ceil(count / 8.0); overallLength = maxLength - 1968/8 + dataLength; - ModbusMakeHeader(mbw.Header, overallLength); - // Payload - mbw.Header.FuncCode = funcCode; // [1] Function Code; 15: Write Multiple Bits (DOs) + mbw.Address = address; // [2] Output address mbw.Count = count; // [2] Number of items; 1:max 1968=0x7B0 mbw.ByteCount = dataLength; // [1] Number of bytes; = ceil(count/8) @@ -276,7 +257,7 @@ void ModbusWriteBits(word address, word count, byte values[]) writeDbg(MbDebug, "Sending 'Write Bits' (0x0F) command. Addr: 0x%04X, Count: %d", address, count); memcpy_h2n(buffer, mbw); - ModbusSend(buffer, overallLength, mbw.Header.TxID); + ModbusSend(buffer, overallLength, funcCode); } /// @@ -357,9 +338,6 @@ void ModbusWriteRegisters(word address, word count, word values[]) dataLength = 2 * count; overallLength = maxLength - 2*123 + dataLength; - ModbusMakeHeader(mbw.Header, overallLength); - // Payload - mbw.Header.FuncCode = funcCode; // [1] Function Code; 16: Write Multiple Registers (AOs) mbw.Address = address; // [2] Output address mbw.Count = count; // [2] Number of items; 1:max 123=0x7B mbw.ByteCount = dataLength; // [1] Number of bytes; = 2 * count @@ -368,7 +346,7 @@ void ModbusWriteRegisters(word address, word count, word values[]) mbw.Data[i] = values[i]; memcpy_h2n(buffer, mbw); - ModbusSend(buffer, overallLength, mbw.Header.TxID); + ModbusSend(buffer, overallLength, funcCode); } /// @@ -404,15 +382,12 @@ void ModbusWriteMasks(word address, word and, word or) byte buffer[length]; struct ModbusReqWriteMasks mbw; - ModbusMakeHeader(mbw.Header, length); - // Payload - mbw.Header.FuncCode = funcCode; // [1] Function Code; 22: Mask Write Registers (AO) mbw.Address = address; // [2] Output address mbw.And = and; // [2] AND mask mbw.Or = or; // [2] OR mask memcpy_h2n(buffer, mbw); - ModbusSend(buffer, length, mbw.Header.TxID); + ModbusSend(buffer, length, funcCode); } /// @@ -453,9 +428,6 @@ void ModbusReadWriteRegisters(word readAddress, word readCount, word writeAddres dataLength = 2 * writeCount; overallLength = maxLength - 2*121 + dataLength; - ModbusMakeHeader(mbw.Header, overallLength); - // Payload - mbw.Header.FuncCode = funcCode; // [1] Function Code; 16: Write Multiple Registers (AOs) mbw.ReadAddress = readAddress; // [2] Input address mbw.ReadCount = readCount; // [2] Number of items; 1:max 125=0x7D mbw.WriteAddress = writeAddress;// [2] Output address @@ -466,7 +438,7 @@ void ModbusReadWriteRegisters(word readAddress, word readCount, word writeAddres mbw.Data[i] = values[i]; memcpy_h2n(buffer, mbw); - ModbusSend(buffer, overallLength, mbw.Header.TxID); + ModbusSend(buffer, overallLength, funcCode); } /// @@ -677,10 +649,14 @@ void OnModbusReceive2Exceptions(byte exCode, struct ModbusApHeader mbap) // ------------------------------------------------------------------------------------ // REGION: ModbusSend ----------------------------------------------------------------- /// <-ModbusSend> -void ModbusSend(byte buffer[], word length, word TxID) +void ModbusSend(byte buffer[], word length, byte funcCode) { struct QueueElement qe; + word TxID; + TxID = gTxID++; + + qe.FuncCode = funcCode; qe.Length = length; memcpy(qe.Buffer, buffer, length); @@ -715,6 +691,8 @@ on timer gtRobin { writeDbg(ConnInfo, "Packet 0x%04X timed out! Retrying...", TxID); gQueueSent[TxID].TimeoutTicks = 0; + EthSetTokenInt(gPacket, "modbus", "TxId", TxID); + EthSetTokenInt(gPacket, "modbus", "FuncCode", gQueueSent[TxID].FuncCode); ModbusSnd(gQueueSent[TxID].Buffer, gQueueSent[TxID].Length); // resend it reqError = Timeout; ModbusRecv(); diff --git a/Modbus-DLL/include/CAPL/include/ModbusStructs.cin b/Modbus-DLL/include/CAPL/include/ModbusStructs.cin index 814eff7..1d8224a 100644 --- a/Modbus-DLL/include/CAPL/include/ModbusStructs.cin +++ b/Modbus-DLL/include/CAPL/include/ModbusStructs.cin @@ -13,21 +13,18 @@ variables // Read Data from the host. We only need the start address and the number of bits/registers we want to read _align(1) struct ModbusReqRead { - struct ModbusApHeader Header; word Address; word Count; }; // Write a single value to a bit/register _align(1) struct ModbusReqWriteSingle { - struct ModbusApHeader Header; word Address; word Value; }; // Write several values to a bit/register starting with Address _align(1) struct ModbusReqWriteBits { - struct ModbusApHeader Header; word Address; word Count; byte ByteCount; @@ -36,7 +33,6 @@ variables // Write several values to bits starting with Address _align(1) struct ModbusReqWriteRegisters { - struct ModbusApHeader Header; word Address; word Count; byte ByteCount; @@ -45,7 +41,6 @@ variables // Write AND and OR masks to a holding register _align(1) struct ModbusReqWriteMasks { - struct ModbusApHeader Header; word Address; word And; word Or; @@ -53,7 +48,6 @@ variables // Read and write multiple registers _align(1) struct ModbusReqReadWriteRegisters { - struct ModbusApHeader Header; word ReadAddress; word ReadCount; word WriteAddress; @@ -66,35 +60,30 @@ variables // Receive several bit values _align(1) struct ModbusResReceiveBits { - struct ModbusApHeader Header; byte ByteCount; byte Data[250]; // Max length: 2000 bits }; // Receive several register values _align(1) struct ModbusResReceiveRegisters { - struct ModbusApHeader Header; byte ByteCount; word Data[125]; // Max length: 125 registers }; // Confirm the write of a single bit/register _align(1) struct ModbusResConfirmSingle { - struct ModbusApHeader Header; word Address; - int Value; + word Value; }; // Confirm the write of several bits/registers _align(1) struct ModbusResConfirmMultiple { - struct ModbusApHeader Header; word Address; word Count; }; // Confirm the write of AND and OR mask _align(1) struct ModbusResConfirmMasks { - struct ModbusApHeader Header; word Address; word And; word Or; diff --git a/Modbus-DLL/include/ModbusProtocolDLL/ModbusProtocol.cpp b/Modbus-DLL/include/ModbusProtocolDLL/ModbusProtocol.cpp index 49bb0ab..559d90d 100644 --- a/Modbus-DLL/include/ModbusProtocolDLL/ModbusProtocol.cpp +++ b/Modbus-DLL/include/ModbusProtocolDLL/ModbusProtocol.cpp @@ -350,7 +350,7 @@ VDEF ModbusProtocol::GetToken( const NIPB::VProtocolToken /*in*/ *protocolToken, else if (tokenId == mFuncCode) return MakeHeaderToken( protocolToken, mFuncCode, 56, 8, token ); else if (tokenId == NIPB::kData) - return this->MakePayloadToken( protocolToken, NIPB::kData, this->kHeaderBitLength, protocolToken->bitLength, token ); + return this->MakePayloadToken( protocolToken, NIPB::kData, 0, protocolToken->bitLength, token ); else if (tokenId == NIPB::kHeader) return this->MakeHeaderToken( protocolToken, NIPB::kHeader, 0, this->kHeaderBitLength, token ); else @@ -385,7 +385,7 @@ VDEF ModbusProtocol::InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protoc return NIPB::kError; NIPB::IFormatter *formatter = 0; - ULONG val; + ULONG valA, valB; // TODO: Make InspectProtocol nice and smooth switch(type) @@ -396,21 +396,21 @@ VDEF ModbusProtocol::InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protoc { formatter->FormatString( "MB: [" ); - val = GetTxId( packetData, packetLength, *protocolToken ); - formatter->FormatUnsigned(val, 2, 10); + valA = GetTxId( packetData, packetLength, *protocolToken ); + formatter->FormatUnsigned(valA, 2, 10); formatter->FormatString( "] " ); - val = GetFuncCode( packetData, packetLength, *protocolToken ); - if (val > 0x80) + valA = GetFuncCode( packetData, packetLength, *protocolToken ); + valB = GetFirstDataByte( packetData, packetLength, *protocolToken ); // Exception Code OR number of bytes + if (valA > 0x80) { formatter->FormatString( "(0x" ); - formatter->FormatUnsigned( val & 0x0F, 1, 16 ); + formatter->FormatUnsigned( valA & 0x0F, 1, 16 ); - val = GetExCode( packetData, packetLength, *protocolToken ); - formatter->FormatString( ") Ex 0x" ); - formatter->FormatUnsigned( val, 1, 16); - switch (val) // exCode + formatter->FormatString( ") Ex" ); + formatter->FormatUnsigned( valB, 1, 10); + switch (valB) // exCode { case 0x01: formatter->FormatString( ": Illegal func code!" ); @@ -442,21 +442,56 @@ VDEF ModbusProtocol::InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protoc } else { - switch (val) // funcCode + switch (valA) // funcCode { case 0x01: case 0x02: - formatter->FormatString( "Read bits" ); + if (protocolToken->bitLength == BY2BI(valB+1)) // if the first byte gives the count of following bytes --> response + { + formatter->FormatString( "Read bits response" ); + } + else + { + formatter->FormatString( "Read " ); + valB = GetAddrNCount( packetData, packetLength, *protocolToken ); + formatter->FormatUnsigned( valB & 0xFFFF, 2, 10 ); + formatter->FormatString( " bits from 0x" ); + formatter->FormatUnsigned( valB >> 16, 2, 16 ); + } break; case 0x03: case 0x04: - formatter->FormatString( "Read regs" ); + if (protocolToken->bitLength == BY2BI(valB+1)) // if the first byte gives the count of following bytes --> response + { + formatter->FormatString( "Read regs response" ); + } + else + { + formatter->FormatString( "Read " ); + valB = GetAddrNCount( packetData, packetLength, *protocolToken ); + formatter->FormatUnsigned( valB & 0xFFFF, 2, 10 ); + formatter->FormatString( " regs from 0x" ); + formatter->FormatUnsigned( valB >> 16, 2, 16 ); + } break; case 0x05: - formatter->FormatString( "Write bit" ); + formatter->FormatString( "Set bit 0x" ); + formatter->FormatUnsigned( valB >> 16, 2, 16 ); + + valB = GetAddrNCount( packetData, packetLength, *protocolToken ); + formatter->FormatString( " to " ); + if (valB & 0xFFFF > 0xFF00) + formatter->FormatString( "1" ); + else + formatter->FormatString( "0" ); break; case 0x06: - formatter->FormatString( "Write reg" ); + formatter->FormatString( "Set reg 0x" ); + formatter->FormatUnsigned( valB >> 16, 2, 16 ); + + valB = GetAddrNCount( packetData, packetLength, *protocolToken ); + formatter->FormatString( " to " ); + formatter->FormatUnsigned( valB & 0xFFFF, 2, 10 ); break; case 0x0F: formatter->FormatString( "Write bits" ); @@ -472,7 +507,7 @@ VDEF ModbusProtocol::InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protoc break; default: formatter->FormatString( "[0x" ); - formatter->FormatUnsigned(val, 1, 16); + formatter->FormatUnsigned(valA, 1, 16); formatter->FormatString( "]" ); break; } @@ -486,8 +521,8 @@ VDEF ModbusProtocol::InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protoc if (inspector->SelectField( NIPB::kFieldLabel, &formatter ) == NIPB::kOK) formatter->FormatString( "ModbusDetail" ); - val = GetContentId( packetData, packetLength, *protocolToken ); - FormatUnsigned( inspector, "TxIDDetail", mTxId, val, 2 ); + valB = GetContentId( packetData, packetLength, *protocolToken ); + FormatUnsigned( inspector, "TxIDDetail", mTxId, valB, 2 ); break; } @@ -504,7 +539,7 @@ VDEF ModbusProtocol::InspectProtocol ( const NIPB::VProtocolToken /*in*/ *protoc //! Returns the content ID /*! */ -ULONG ModbusProtocol::GetContentId( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) +ULONG ModbusProtocol::GetContentId( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) { ULONG ip = GetIp( packetData, packetLength, protocol ); BYTE funcCode = GetFuncCode( packetData, packetLength, protocol ); @@ -516,7 +551,7 @@ ULONG ModbusProtocol::GetContentId( const BYTE *packetData, ULONG packetLength, //! Returns the TxID /*! */ -WORD ModbusProtocol::GetTxId( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) +WORD ModbusProtocol::GetTxId( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) { ULONG offset = BI2BY(protocol.headerBitOffset); @@ -530,11 +565,11 @@ WORD ModbusProtocol::GetTxId( const BYTE *packetData, ULONG packetLength, const //! Returns the FuncCode /*! */ -BYTE ModbusProtocol::GetFuncCode( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) +BYTE ModbusProtocol::GetFuncCode( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) { ULONG offset = BI2BY(protocol.headerBitOffset) + 7; - if (offset+1 < packetLength) + if (offset < packetLength) { return packetData[offset]; } @@ -548,7 +583,7 @@ BYTE ModbusProtocol::GetFuncCode( const BYTE *packetData, ULONG packetLength, co //! Returns the DestinationIP /*! */ -ULONG ModbusProtocol::GetIp( const BYTE * /*packetData*/, ULONG /*packetLength*/, const NIPB::VProtocolToken &/*protocol*/ ) +ULONG ModbusProtocol::GetIp( const BYTE * /*packetData*/, ULONG /*packetLength*/, const NIPB::VProtocolToken &/*protocol*/ ) { // TODO: GetDestIp /*NIPB::VToken *ipv4DestIp; @@ -569,11 +604,15 @@ ULONG ModbusProtocol::GetIp( const BYTE * /*packetData*/, ULONG /*packetLength*/ return 0xC0A80102; } -BYTE ModbusProtocol::GetExCode( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) +/*--------------------------------------------------------------------*/ +//! Returns the first byte of the payload +/*! +*/ +BYTE ModbusProtocol::GetFirstDataByte( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) { ULONG offset = BI2BY(protocol.bitOffset); - if (offset+1 < packetLength) + if (offset < packetLength) { return packetData[offset]; } @@ -583,6 +622,29 @@ BYTE ModbusProtocol::GetExCode( const BYTE *packetData, ULONG packetLength, cons } } +/*--------------------------------------------------------------------*/ +//! Returns the first two words of the payload +/*! +*/ +ULONG ModbusProtocol::GetAddrNCount( const BYTE *packetData, ULONG packetLength, const NIPB::VProtocolToken &protocol ) +{ + ULONG offset = BI2BY(protocol.bitOffset); + ULONG value; + + if (offset+3 < packetLength) + { + value = packetData[offset] << 8 | packetData[offset+1]; // LE/BE + value <<= 16; + offset += 2; + value |= packetData[offset] << 8 | packetData[offset+1]; // LE/BE + return value; + } + else + { + return 0; + } +} + /*--------------------------------------------------------------------*/ //! Fill a VToken structure. /*! diff --git a/Modbus-DLL/include/ModbusProtocolDLL/ModbusProtocol.dll b/Modbus-DLL/include/ModbusProtocolDLL/ModbusProtocol.dll index b8182f56e13f3899e71707a39b7a182774145061..600da5c422cc8770553c7d565a2845fc7071b743 100644 GIT binary patch delta 1421 zcmZuwe@q)y9DjGc(hJnI#7+por5f~)Z92Gn#5s!DCYNoHCQy3(Fiz<<@MO~wC<&1? zKu*N&jb!d=G81Mnq9cw(woV`sBOnG`NQ5~JiH(#6-F59qW4g&7BxNq<6H^5 zUQJo^Q8v>{-EcgR=|%IBwXhPx4`jkt=A~-dZua?VI-Itj^;FS#+B1A~zu~{{3E3=n zxNFwB!wjOn%90oI)PNPWrjH#qTTpa~Lx@OLwT<62&4Eb`I5xk>;d@5XXt;7Wr>Oyr zW_X``%utY@Cz2L@jiZI$yu5v>uq1*-BzsU=Q3ETC-v&Etd-qEdKrwSP;LTxr=tb{d zKHiw#$PzhDfASXXiUWjl;$E*H@|uUZdF}73x^5ep2ug{rK)e&Kw7pl(Af$}bIyuW1 zS8v-qL`o8#$Vm@5n5)k#6ZepvxRWFk?B%4?p)WuIhRBI6fyA8%x+6r6sCStl?14zS zt>;DxbVSeV?mLO>%B)d^elLGh(+@=fWKa$hDXeNt5cWX$30qH@;c$m-BOk;eL(ltY z77ijMdaXb3#$~eg#Zr6g4&~KV!@P;qq0h&fm8Mm?>~%hyHLUCK!i`2Gx^C+_LR-)( zZL8ELKVAr(N=)9hZ}CPKp_KBzQR0!8M<)#XhxGTVtd9O|0HWs&@6fiaSi3T28092k z;l2t|?$B?>8kFg6H^eHG`R(a0C9*BOG0P4^km4}h&C%rQ3(5*5)q5C?j#WQZ%nWU` zfra)#98W5EkFu63>L}N=E4r>uJBZt1jMf38<@E)i9r@$flpUR?*){num!3fO;~?*V zTmZQYG7ho;@+SyF48xlEhl?|(lr+oSe-`bi$;mzkwSv+b&=+u6fs8zmF{ugkYRy^t zQti|9SZz`2{AyPkb?!{>knH4$buwxSy4QfY>XfNSwzj~Kc$2hd8{sFHfuOue2K^9| zF&lKR1IH(q?S^86vq2e({eN(Vd))|=)?-|Z6(@}6TG0kznZ(sVHfptmeyn}NOb^uU zU~*|yU9(wv0IZ}p>hRvF0i$btZ*PsR>l*o7*GaF}P+$2>*JrwqfLa2-|3iNlea@FH zwm*_n0y#6?B@hT~`8QC4Y?3k>csLYl_Z{`auZ`%;FP}J_&Gju!XWnk92O8J=PCCKv zJpQJ?#o5q&<}GJ_Td4lmcIMjRbraJN`uew?LmhsI=*wTq7Ykl5_@dxS!My@j$P)Gl z2Zbu(l<=uAD10Z}5^}^c@r2keQgKlHR=g?R5$(7b`*9!c#{+l}58+{a9gpF0Jb|b2 uES|&j_!eHoVI09LSi`4WKf9J(_g$`H)P&GJXwhlmf-ohFj*jkRB+EaBE?qnT delta 1136 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 D;+w`7 delta 25906 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�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 S?Q>0v*QPIbpD0xRegisterProtocol( "modbus", mbpao, "udp", ModbusProtocol::kServerPort, 0xFFFFFFFF ) != NIPB::kOK) + if (registrar->RegisterProtocol( "modbus", mbpao, "udp", ModbusProtocol::kServerPort, ModbusProtocol::kClientPort ) != NIPB::kOK) { log << "Could not register UDP 502 -> 50002\n"; log.close(); diff --git a/Modbus-DLL/log.txt b/Modbus-DLL/log.txt index 323b995..1942e0d 100644 --- a/Modbus-DLL/log.txt +++ b/Modbus-DLL/log.txt @@ -3,43 +3,22 @@ Initializing Defining fields MyProtocolId = 4896. InitProtocol. CompleteProtocol: Modbus->bitLength = 32, --> Length = 6. ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 12 - Data = 00 01 00 00 00 06 ff 01 00 00 00 00 + Data = 00 01 00 00 00 06 ff 01 00 00 00 02 --> byteOffset = 50, byteLength = 4 --> ContentId = 1020001. -ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 9 - Data = 00 01 00 00 00 03 ff 81 03 - --> byteOffset = 50, byteLength = 1 - --> ContentId = 1020081. +ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 10 + Data = 00 01 00 00 00 04 ff 01 01 00 + --> byteOffset = 50, byteLength = 2 + --> ContentId = 1020001. ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 12 - Data = 00 01 00 00 00 06 ff 01 00 00 00 00 + Data = 00 01 00 00 00 06 ff 01 00 00 00 02 --> byteOffset = 50, byteLength = 4 --> ContentId = 1020001. -ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 9 - Data = 00 01 00 00 00 03 ff 81 03 - --> byteOffset = 50, byteLength = 1 - --> ContentId = 1020081. - -CompleteProtocol: Modbus->bitLength = 32, --> Length = 6. -ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 12 - Data = 00 02 00 00 00 06 ff 01 00 00 00 00 - --> byteOffset = 50, byteLength = 4 +ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 10 + Data = 00 01 00 00 00 04 ff 01 01 00 + --> byteOffset = 50, byteLength = 2 --> ContentId = 1020001. -ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 9 - Data = 00 02 00 00 00 03 ff 81 03 - --> byteOffset = 50, byteLength = 1 - --> ContentId = 1020081. - -ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 12 - Data = 00 02 00 00 00 06 ff 01 00 00 00 00 - --> byteOffset = 50, byteLength = 4 - --> ContentId = 1020001. - -ParsePacket topProtocolToken->tokenId = 352 byteOffset = 42, byteLength = 9 - Data = 00 02 00 00 00 03 ff 81 03 - --> byteOffset = 50, byteLength = 1 - --> ContentId = 1020081. -