package com.nightscout.core.dexcom.records; import com.nightscout.core.dexcom.CRC16; import com.nightscout.core.dexcom.CRCFailError; import com.nightscout.core.dexcom.Constants; import com.nightscout.core.dexcom.InvalidRecordLengthException; import com.nightscout.core.dexcom.RecordType; import com.nightscout.core.dexcom.Utils; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; public class PageHeader { public static final int HEADER_SIZE = 28; protected final int FIRSTRECORDINDEX_OFFSET = 0; protected final int NUMRECS_OFFSET = 4; protected final int RECTYPE_OFFSET = 8; protected final int REV_OFFSET = 9; protected final int PAGENUMBER_OFFSET = 10; protected final int RESERVED2_OFFSET = 14; protected final int RESERVED3_OFFSET = 18; protected final int RESERVED4_OFFSET = 22; protected int firstRecordIndex; protected int numOfRecords; protected RecordType recordType; protected byte revision; protected int pageNumber; protected int reserved2; protected int reserved3; protected int reserved4; protected byte[] crc = new byte[2]; public PageHeader(byte[] packet) { if (packet.length < HEADER_SIZE) { throw new InvalidRecordLengthException("Unexpected record size: " + packet.length + ". Expected size: " + HEADER_SIZE + ". Unparsed record: " + Utils.bytesToHex(packet)); } firstRecordIndex = ByteBuffer.wrap(packet).order(ByteOrder.LITTLE_ENDIAN) .getInt(FIRSTRECORDINDEX_OFFSET); numOfRecords = ByteBuffer.wrap(packet).order(ByteOrder.LITTLE_ENDIAN).getInt(NUMRECS_OFFSET); recordType = RecordType.values()[packet[RECTYPE_OFFSET]]; revision = packet[REV_OFFSET]; pageNumber = ByteBuffer.wrap(packet).order(ByteOrder.LITTLE_ENDIAN) .getInt(PAGENUMBER_OFFSET); reserved2 = ByteBuffer.wrap(packet).order(ByteOrder.LITTLE_ENDIAN).getInt(RESERVED2_OFFSET); reserved3 = ByteBuffer.wrap(packet).order(ByteOrder.LITTLE_ENDIAN).getInt(RESERVED3_OFFSET); reserved4 = ByteBuffer.wrap(packet).order(ByteOrder.LITTLE_ENDIAN).getInt(RESERVED4_OFFSET); System.arraycopy(packet, HEADER_SIZE - Constants.CRC_LEN, crc, 0, Constants.CRC_LEN); byte[] crc_calc = CRC16.calculate(packet, 0, HEADER_SIZE - Constants.CRC_LEN); if (!Arrays.equals(this.crc, crc_calc)) { throw new CRCFailError("CRC check failed. Was:" + Utils.bytesToHex(this.crc) + " Expected: " + Utils.bytesToHex(crc_calc)); } } public byte getRevision() { return revision; } public RecordType getRecordType() { return recordType; } public int getFirstRecordIndex() { return firstRecordIndex; } public int getNumOfRecords() { return numOfRecords; } public int getPageNumber() { return pageNumber; } public int getReserved2() { return reserved2; } public int getReserved3() { return reserved3; } public int getReserved4() { return reserved4; } }