6
6
7
7
use ModbusTcpClient \Network \IOException ;
8
8
use ModbusTcpClient \Packet \ErrorResponse ;
9
+ use ModbusTcpClient \Packet \ModbusPacket ;
9
10
10
11
final class Packet
11
12
{
@@ -39,8 +40,8 @@ public static function isCompleteLength(string|null $binaryData): bool
39
40
}
40
41
41
42
/**
42
- * isCompleteLengthRTU checks if binary string is complete modbus RTU packet
43
- * NB: this function works only for MODBUS RTU packets
43
+ * isCompleteLengthRTU checks if binary string is complete modbus RTU response packet
44
+ * NB: this function works only for MODBUS RTU response packets
44
45
*
45
46
* @param string|null $binaryData binary string to be checked
46
47
* @return bool true if data is actual error packet
@@ -52,17 +53,36 @@ public static function isCompleteLengthRTU(string|null $binaryData): bool
52
53
if ($ length < 5 ) {
53
54
return false ;
54
55
}
55
- if ((ord ($ binaryData [1 ]) & ErrorResponse::EXCEPTION_BITMASK ) > 0 ) { // seems to be error response
56
+ $ functionCode = ord ($ binaryData [1 ]);
57
+ if (($ functionCode & ErrorResponse::EXCEPTION_BITMASK ) > 0 ) { // seems to be error response
56
58
return true ;
57
59
}
58
- // if it is not error response then 3rd byte contains data length in bytes
60
+ switch ($ functionCode ) {
61
+ case ModbusPacket::READ_COILS : //
62
+ case ModbusPacket::READ_INPUT_DISCRETES : //
63
+ case ModbusPacket::READ_HOLDING_REGISTERS : //
64
+ case ModbusPacket::READ_INPUT_REGISTERS : //
65
+ case ModbusPacket::READ_WRITE_MULTIPLE_REGISTERS : //
66
+ // if it is not error response then 3rd byte contains data length in bytes
59
67
60
- // trailing 3 bytes are = unit id + function code + data length in bytes
61
- // next is N bytes of data that should match 3rd byte value
62
- // and 2 bytes for CRC
63
- // so adding these number is what complete packet would be
64
- $ expectedLength = 3 + ord ($ binaryData [2 ]) + 2 ;
68
+ // trailing 3 bytes are = unit id (1) + function code (1) + data length in bytes (1) + (N)
69
+ // next is N bytes of data that should match 3rd byte value
70
+ $ responseBytesLen = 3 + ord ($ binaryData [2 ]);
71
+ break ;
72
+ case ModbusPacket::WRITE_SINGLE_COIL : // unit id (1) + function code (1) + start address (2) + coil data (2)
73
+ case ModbusPacket::WRITE_SINGLE_REGISTER : // unit id (1) + function code (1) + start address (2) + register data (2)
74
+ case ModbusPacket::WRITE_MULTIPLE_COILS : // unit id (1) + function code (1) + start address (2) + count of coils written (2)
75
+ case ModbusPacket::WRITE_MULTIPLE_REGISTERS : // unit id (1) + function code (1) + start address (2) + count of registers written (2)
76
+ $ responseBytesLen = 6 ;
77
+ break ;
78
+ case ModbusPacket::MASK_WRITE_REGISTER :
79
+ $ responseBytesLen = 8 ; // unit id (1) + function code (1) + start address (2) + AND mask (2) + OR mask (2)
80
+ break ;
81
+ default :
82
+ throw new IOException ('can not determine complete length for unsupported modbus function code ' );
83
+ }
65
84
85
+ $ expectedLength = $ responseBytesLen + 2 ; // and 2 bytes for CRC
66
86
if ($ length > $ expectedLength ) {
67
87
throw new IOException ('packet length more bytes than expected ' );
68
88
}
0 commit comments