Skip to content

Commit a978cb4

Browse files
committed
Allow verifyCrc16 to be overridden by subclasses
This allows a subclass the opportunity to ignore CRC mismatches or even implement an alternative verification algorithm if necessary.
1 parent ea259a1 commit a978cb4

File tree

1 file changed

+30
-16
lines changed

1 file changed

+30
-16
lines changed

modbus/src/main/java/com/digitalpetri/modbus/client/ModbusRtuClient.java

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ public CompletionStage<ModbusResponsePdu> sendAsync(int unitId, ModbusRequestPdu
8181
// The frame parser needs to be reset!
8282
// It could be "stuck" in Accumulating or ParseError states if the timeout was caused by
8383
// an incomplete or invalid response rather than no response.
84-
transport.resetFrameParser();
84+
resetFrameParser();
8585

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

170170
if (!verifyCrc16(frame)) {
171-
transport.resetFrameParser();
171+
resetFrameParser();
172172

173173
promise.future.completeExceptionally(new ModbusCrcException(frame));
174174
return;
@@ -230,13 +230,40 @@ private void onFrameReceived(ModbusRtuFrame frame) {
230230
}
231231
}
232232

233+
/**
234+
* Reset the transport's frame parser.
235+
*/
236+
protected void resetFrameParser() {
237+
transport.resetFrameParser();
238+
}
239+
240+
/**
241+
* Calculate the CRC-16 for the given frame (unit ID and PDU).
242+
*
243+
* @param unitId the unit ID.
244+
* @param pdu the PDU.
245+
* @return a {@link ByteBuffer} containing the calculated CRC-16.
246+
*/
247+
protected ByteBuffer calculateCrc16(int unitId, ByteBuffer pdu) {
248+
var crc16 = new Crc16();
249+
crc16.update(unitId);
250+
crc16.update(pdu);
251+
252+
ByteBuffer crc = ByteBuffer.allocate(2);
253+
// write crc in little-endian order
254+
crc.put((byte) (crc16.getValue() & 0xFF));
255+
crc.put((byte) ((crc16.getValue() >> 8) & 0xFF));
256+
257+
return crc.flip();
258+
}
259+
233260
/**
234261
* Verify the reported CRC-16 matches the calculated CRC-16.
235262
*
236263
* @param frame the frame to verify.
237264
* @return {@code true} if the CRC-16 matches, {@code false} otherwise.
238265
*/
239-
private static boolean verifyCrc16(ModbusRtuFrame frame) {
266+
protected boolean verifyCrc16(ModbusRtuFrame frame) {
240267
var crc16 = new Crc16();
241268
crc16.update(frame.unitId());
242269
crc16.update(frame.pdu());
@@ -250,19 +277,6 @@ private static boolean verifyCrc16(ModbusRtuFrame frame) {
250277
return expected == reported;
251278
}
252279

253-
private ByteBuffer calculateCrc16(int unitId, ByteBuffer pdu) {
254-
var crc16 = new Crc16();
255-
crc16.update(unitId);
256-
crc16.update(pdu);
257-
258-
ByteBuffer crc = ByteBuffer.allocate(2);
259-
// write crc in little-endian order
260-
crc.put((byte) (crc16.getValue() & 0xFF));
261-
crc.put((byte) ((crc16.getValue() >> 8) & 0xFF));
262-
263-
return crc.flip();
264-
}
265-
266280
/**
267281
* Create a new {@link ModbusRtuClient} using the given {@link ModbusRtuClientTransport} and a
268282
* {@link ModbusClientConfig} with the default values.

0 commit comments

Comments
 (0)