Cloud-Automation / node-modbus

Modbus TCP Client/Server implementation for Node.JS
456 stars 169 forks source link

CRC mismatch for exception responses #279

Closed hansmaad closed 3 years ago

hansmaad commented 3 years ago

Version: 4.0.5

I think that the CRC calculation is wrong for exception responses, here:

https://github.com/Cloud-Automation/node-modbus/blob/886669b5a7a496922f7667859065511196653286/src/rtu-client-request-handler.ts#L65-L68

In combintation with createPayload() for exception response here

https://github.com/Cloud-Automation/node-modbus/blob/886669b5a7a496922f7667859065511196653286/src/response/exception.ts#L65-L71

and this:

https://github.com/Cloud-Automation/node-modbus/blob/886669b5a7a496922f7667859065511196653286/src/response/exception.ts#L39-L40

In my example I get response [1, 131, 2, 192, 241] fc = 131 = exception fc 3 The crc is compared to calculated crc on [1, 3, 2], not [1, 131, 2]

This could be fixed with for example:

public createPayload () {
    const payload = Buffer.alloc(2)
    payload.writeUInt8(this._fc + 0x80, 0)  // add 0x80 to fc to get the original value
    payload.writeUInt8(this._code, 1)
    return payload
  }
stefanpoeter commented 3 years ago

hey @hansmaad

thanks for the note, I'll look into it when i am back in office.

stefanpoeter commented 3 years ago

Sorry @hansmaad

it took me some really long time to get back to the office :-)

I see, so we extract the 0x80 offset in the fromBuffer method and we are not adding it in the createPayload method, hence the crc is wrong for exceptions. Am I seeing this right?

hansmaad commented 3 years ago

Yes, I think it was like this (the topic is completely offloaded from my brain, but I remember that it was not too hard to understand).

murat-dogan commented 3 years ago

Hi,

I hit to the same error. I was creating a merge request when I saw this issue. Here is the log;

serialport/bindings loading LinuxBinding +0ms
  serialport/stream opening path: /dev/tty0 +0ms
  serialport/binding-abstract open +0ms
  serialport/stream _read queueing _read for after open +21ms
  serialport/bindings/poller Creating poller +0ms
  serialport/stream opened path: /dev/tty0 +10ms
Connection OK
  serialport/stream _read reading { start: 0, toRead: 65536 } +8ms
  serialport/binding-abstract read +50ms
  serialport/bindings/unixRead Starting read +0ms
  serialport/bindings/unixRead read error [Error: EAGAIN: resource temporarily unavailable, read] {
  errno: -11,
  code: 'EAGAIN',
  syscall: 'read'
} +3ms
  serialport/bindings/unixRead waiting for readable because of code: EAGAIN +6ms
  serialport/bindings/poller Polling for "readable" +40ms
  modbus-client issuing new read holding registers request +0ms
  rtu-client-request-handler registrating new request +0ms
  user-request creating new user request with timeout 5000 +0ms
  client-request-handler flushing +0ms
  client-request-handler flushing new request <Buffer 01 03 0f a6 00 01 67 3d> +9ms
  serialport/stream _write 8 bytes of data +3s
  serialport/binding-abstract write 8 bytes +3s
  serialport/bindings/unixWrite Starting write 8 bytes offset 0 bytesToWrite 8 +0ms
  serialport/bindings/unixWrite write returned: wrote 8 bytes +4ms
  serialport/bindings/unixWrite Finished writing 8 bytes +1ms
  serialport/stream binding.write write finished +11ms
  client-request-handler request fully flushed, ( error: undefined ) +18ms
  serialport/bindings/poller received "readable" +3s
  serialport/bindings/unixRead Starting read +3s
  serialport/bindings/unixRead Finished read 5 bytes +2ms
  serialport/stream binding.read finished { bytesRead: 5 } +19ms
  modbus-client received data +70ms
  rtu-response-handler receiving new data +0ms
  rtu-response-handler buffer <Buffer 01 83 02 c0 f1> +1ms
  rtu-response address 1 buffer <Buffer 01 83 02 c0 f1> +0ms
  response-factory fc 131 payload <Buffer 83 02 c0 f1> +0ms
  rtu-response-handler crc 61888 +8ms
  rtu-response-handler reset buffer from 5 to 0 +1ms
  rtu-response-handler not enough data available to parse +0ms
  rtu-client-request-handler new response coming in +79ms
  rtu-client-request-handler create crc from response <Buffer 01 03 02> +2ms
  rtu-client-request-handler CRC does not match 61888 !== 12705 +1ms
UserRequestError {
  err: 'crcMismatch',
  message: 'the response payload does not match the crc',
  response: undefined
}
  serialport/stream _read reading { start: 5, toRead: 65531 } +29ms
  serialport/binding-abstract read +60ms
  serialport/bindings/unixRead Starting read +33ms
  serialport/bindings/unixRead read error [Error: EAGAIN: resource temporarily unavailable, read] {
  errno: -11,
  code: 'EAGAIN',
  syscall: 'read'
} +1ms
  serialport/bindings/unixRead waiting for readable because of code: EAGAIN +1ms
  serialport/bindings/poller Polling for "readable" +39ms
  modbus-client issuing new read holding registers request +3s
  rtu-client-request-handler registrating new request +3s
  user-request creating new user request with timeout 5000 +3s
  client-request-handler flushing +3s
  client-request-handler flushing new request <Buffer 01 03 0f a6 00 01 67 3d> +1ms
  serialport/stream _write 8 bytes of data +3s
  serialport/binding-abstract write 8 bytes +3s
  serialport/bindings/unixWrite Starting write 8 bytes offset 0 bytesToWrite 8 +3s
  serialport/bindings/unixWrite write returned: wrote 8 bytes +2ms
  serialport/bindings/unixWrite Finished writing 8 bytes +0ms
  serialport/stream binding.write write finished +4ms
  client-request-handler request fully flushed, ( error: undefined ) +5ms
  serialport/bindings/poller received "readable" +3s
  serialport/bindings/unixRead Starting read +3s
  serialport/bindings/unixRead Finished read 5 bytes +1ms
  serialport/stream binding.read finished { bytesRead: 5 } +24ms
  modbus-client received data +33ms
  rtu-response-handler receiving new data +3s
  rtu-response-handler buffer <Buffer 01 83 02 c0 f1> +1ms
  rtu-response address 1 buffer <Buffer 01 83 02 c0 f1> +3s
  response-factory fc 131 payload <Buffer 83 02 c0 f1> +3s
  rtu-response-handler crc 61888 +1ms
  rtu-response-handler reset buffer from 5 to 0 +1ms
  rtu-response-handler not enough data available to parse +0ms
  rtu-client-request-handler new response coming in +37ms
  rtu-client-request-handler create crc from response <Buffer 01 03 02> +0ms
  rtu-client-request-handler CRC does not match 61888 !== 12705 +1ms
UserRequestError {
  err: 'crcMismatch',
  message: 'the response payload does not match the crc',
  response: undefined
}
  serialport/stream _read reading { start: 10, toRead: 65526 } +9ms

Normally payload is <Buffer 83 02 c0 f1> but crc check is using <Buffer 03 02 c0 f1>

stefanpoeter commented 3 years ago

Update to Version 4.0.6. There is a patch thanks to @murat-dogan