diff --git a/Modbus-CAPL/include/CAPL/include/ModbusClient.cin b/Modbus-CAPL/include/CAPL/include/ModbusClient.cin index 6aacc30..05d9e17 100644 --- a/Modbus-CAPL/include/CAPL/include/ModbusClient.cin +++ b/Modbus-CAPL/include/CAPL/include/ModbusClient.cin @@ -814,7 +814,8 @@ void _OnModbusReceive(dword socket, long result, dword address, dword port, byte // Size of zero indicates that the socket was closed by the communication peer. writeDbg(ConnWarning, "OnModbusReceive: Socket closed by peer"); _ModbusDisconnect(); - + + // Now we have to move the already sent telegrams back to the pending queue to send them again for (long TxID : gQueueSent) { writeDbg(ConnWarning, "OnModbusReceive: Moving 0x%04X back to pending queue", TxID); @@ -826,7 +827,7 @@ void _OnModbusReceive(dword socket, long result, dword address, dword port, byte } else { - // Sucessfully received some bytes over the TCP/IP connection. + // Sucessfully received some bytes over the connection. _OnModbusReceive2(buffer, size); } } @@ -836,7 +837,7 @@ void _OnModbusReceive(dword socket, long result, dword address, dword port, byte writeDbg(ConnError, "OnModbusReceive error (%d): %s", gIpLastErr, gIpLastErrStr); _ModbusDisconnect(); } - _ModbusRecv(); + _ModbusRecv(); // Continue receiving } /// <-OnModbusReceive> @@ -848,24 +849,24 @@ void _OnModbusReceive2(byte buffer[], dword size) long offset; char str[3*20]; - if (size < 8) // No complete Modbus Application Header + if (size < __size_of(struct ModbusApHeader)) // No complete Modbus Application Header fits into this data return; offset = 0; do { - memcpy_n2h(mbap, buffer, offset); + memcpy_n2h(mbap, buffer, offset); // Copy the data into the Modbus Header writeDbg(ConnDebug, "OnModbusReceive2: Offset pre = %d. TxID = %d", offset, mbap.TxID); - _OnModbusReceive2OnePacket(buffer, offset, mbap); - - offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length; + _OnModbusReceive2OnePacket(buffer, offset, mbap); // Parse the resulting telegram + + offset += __offset_of(struct ModbusApHeader, UnitID) + mbap.Length; // Move to the next telegram 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 + while (offset <= size-8); // We need at least 8 bytes for a new packet writeDbg(ConnDebug, "OnModbusReceive2: yes. finished"); - if (offset != size) // Can be removed. - { + if (offset != size) // If the offset is not pointing at the end of the data + { // This is a indicator that the length field in the Modbus Header was incorrect (attempt to spam the connection?) bin_to_strhex(buffer, str); 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); @@ -878,28 +879,29 @@ void _OnModbusReceive2(byte buffer[], dword size) // It gets called by _OnModbusReceive2() void _OnModbusReceive2OnePacket(byte buffer[], int offset, struct ModbusApHeader mbap) { - // Test transaction identifier? - // Test unit/device identifier? + // Should we test the transaction identifier? + // Should we test the unit/device identifier? word i; // counter word length; // length of current packet - 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* + length = __offset_of(struct ModbusApHeader, UnitID) + mbap.Length; // the length of the complete telegram + if (mbap.Protocol != 0) // Protocol is not Modbus (0x0000). Wayne. { - writeDbg(ConnDebug, "OnModbusReceive2OnePacket: 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); + // either the length field is incorrect or the package is fragmented in the buffer // I REALLY don't want to assemble the two package fragments. OnModbusClientPanics(ModbusPackageWasSplit); return; } // MBAP Header is OK :) Go on - if (!gQueueSent.ContainsKey(mbap.TxID)) // We don't wait for this message!? + if (!gQueueSent.ContainsKey(mbap.TxID)) // We don't wait for this message!? Skip it. return; //write("Received TxID: %d", mbap.TxID); @@ -1006,7 +1008,7 @@ void _OnModbusReceive2Success(byte buffer[], struct ModbusApHeader mbap, int off // ------------------------------------------------------------------------------------ // REGION: ModbusSend ----------------------------------------------------------------- /// <-ModbusSend> -// This method will enqueue the data in gQueuePending and start gtModbusRobin if appropriate +// This method will enqueue the data into gQueuePending and start gtModbusRobin if appropriate // It will get called by the Modbus request functions void _ModbusSend(byte buffer[], word length, word TxID) {