package com.serotonin.bacnet4j.npdu.mstp;
public class DataCRC {
public static final int CHECK_VALUE = 0xF0B8;
private int value = 0xffff;
public void reset() {
value = 0xffff;
}
public void accumulate(int data) {
value = calcDataCRC(data, value);
}
public void accumulate(byte data) {
accumulate(data & 0xFF);
}
public boolean isOk() {
return value == CHECK_VALUE;
}
public int getCrc(Frame frame) {
reset();
for (byte b : frame.getData())
accumulate(b);
return onesComplement(value);
}
private static int calcDataCRC(int dataValue, int crcValue) {
int crcLow = (crcValue & 0xff) ^ dataValue; /* XOR C7..C0 with D7..D0 */
/* Exclusive OR the terms in the table (top down) */
int crc = (crcValue >> 8) ^ (crcLow << 8) ^ (crcLow << 3) ^ (crcLow << 12) ^ (crcLow >> 4) ^ (crcLow & 0x0f)
^ ((crcLow & 0x0f) << 7);
return crc & 0xffff;
}
private static int onesComplement(int i) {
return (~i) & 0xffff;
}
public static void main(String[] args) {
// DataCRC crc = new DataCRC();
// crc.accumulate(0x01);
// crc.accumulate(0x22);
// crc.accumulate(0x33);
// System.out.println(Integer.toString(crc.close(), 16));
DataCRC crc = new DataCRC();
System.out.println(Integer.toString(crc.getCrc(new Frame(FrameType.bacnetDataNotExpectingReply, (byte) 0xff,
(byte) 8, new byte[] { 0x1, 0x20, (byte) 0xff, (byte) 0xfc, (byte) 0xfe, 0x20, (byte) 0xa0,
(byte) 0xe7, (byte) 0x91, (byte) 0xf0, 0x3, 0x22, 0x1, 0x15, 0x2b, (byte) 0xf9, (byte) 0xff,
0x55, (byte) 0xff, 0x0, 0x4 })), 16));
// crc.accumulate(0xb8);
// crc.accumulate(0x96);
System.out.println(Integer.toString(crc.value, 16));
// crc.accumulate(0x8);
// crc.accumulate(0x0);
// System.out.println(Integer.toString(crc.getValue(), 16));
//[55,ff,6,ff,8,0,15,da,1,20,ff,fc,fe,20,a0,e7,91,f0,3,22,1,15,2b,f9,ff,55,ff,0,4,8,0,0,14]
}
}