Skip to content

Commit

Permalink
Allow verifyCrc16 to be overridden by subclasses
Browse files Browse the repository at this point in the history
This allows a subclass the opportunity to ignore CRC mismatches or even implement an alternative verification algorithm if necessary.
  • Loading branch information
kevinherron committed Nov 14, 2024
1 parent 4efdff9 commit c191965
Showing 1 changed file with 30 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public CompletionStage<ModbusResponsePdu> sendAsync(int unitId, ModbusRequestPdu
// The frame parser needs to be reset!
// It could be "stuck" in Accumulating or ParseError states if the timeout was caused by
// an incomplete or invalid response rather than no response.
transport.resetFrameParser();
resetFrameParser();

promise.future.completeExceptionally(
new TimeoutException("request timed out after %sms".formatted(timeoutMillis))
Expand Down Expand Up @@ -168,7 +168,7 @@ private void onFrameReceived(ModbusRtuFrame frame) {
}

if (!verifyCrc16(frame)) {
transport.resetFrameParser();
resetFrameParser();

promise.future.completeExceptionally(new ModbusCrcException(frame));
return;
Expand Down Expand Up @@ -230,13 +230,40 @@ private void onFrameReceived(ModbusRtuFrame frame) {
}
}

/**
* Reset the transport's frame parser.
*/
protected void resetFrameParser() {
transport.resetFrameParser();
}

/**
* Calculate the CRC-16 for the given frame (unit ID and PDU).
*
* @param unitId the unit ID.
* @param pdu the PDU.
* @return a {@link ByteBuffer} containing the calculated CRC-16.
*/
protected ByteBuffer calculateCrc16(int unitId, ByteBuffer pdu) {
var crc16 = new Crc16();
crc16.update(unitId);
crc16.update(pdu);

ByteBuffer crc = ByteBuffer.allocate(2);
// write crc in little-endian order
crc.put((byte) (crc16.getValue() & 0xFF));
crc.put((byte) ((crc16.getValue() >> 8) & 0xFF));

return crc.flip();
}

/**
* Verify the reported CRC-16 matches the calculated CRC-16.
*
* @param frame the frame to verify.
* @return {@code true} if the CRC-16 matches, {@code false} otherwise.
*/
private static boolean verifyCrc16(ModbusRtuFrame frame) {
protected boolean verifyCrc16(ModbusRtuFrame frame) {
var crc16 = new Crc16();
crc16.update(frame.unitId());
crc16.update(frame.pdu());
Expand All @@ -250,19 +277,6 @@ private static boolean verifyCrc16(ModbusRtuFrame frame) {
return expected == reported;
}

private ByteBuffer calculateCrc16(int unitId, ByteBuffer pdu) {
var crc16 = new Crc16();
crc16.update(unitId);
crc16.update(pdu);

ByteBuffer crc = ByteBuffer.allocate(2);
// write crc in little-endian order
crc.put((byte) (crc16.getValue() & 0xFF));
crc.put((byte) ((crc16.getValue() >> 8) & 0xFF));

return crc.flip();
}

/**
* Create a new {@link ModbusRtuClient} using the given {@link ModbusRtuClientTransport} and a
* {@link ModbusClientConfig} with the default values.
Expand Down

0 comments on commit c191965

Please sign in to comment.