package info.nightscout.androidaps.plugins.DanaR.comm; import android.annotation.TargetApi; import android.os.Build; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import java.nio.charset.StandardCharsets; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.GregorianCalendar; import info.nightscout.androidaps.Config; import info.nightscout.utils.CRC; /* * 00 01 02 03 04 05 06 * * 7E 7E len F1 CMD SUB data CRC CRC 2E 2E */ public class MessageBase { private static Logger log = LoggerFactory.getLogger(MessageBase.class); private byte[] buffer = new byte[512]; private int position = 6; public boolean received = false; public boolean failed = false; public void SetCommand(int cmd) { this.buffer[4] = (byte) (cmd >> 8 & 0xFF); this.buffer[5] = (byte) (cmd & 0xFF); } public void AddParamByte(byte data) { this.buffer[this.position++] = data; } public void AddParamInt(int data) { this.buffer[this.position++] = (byte) (data >> 8 & 0xFF); this.buffer[this.position++] = (byte) (data & 0xFF); } public void AddParamDate(GregorianCalendar date) { AddParamByte((byte) (date.get(Calendar.YEAR) - 1900 - 100)); AddParamByte((byte) (date.get(Calendar.MONTH) + 1)); AddParamByte((byte) (date.get(Calendar.DAY_OF_MONTH))); AddParamByte((byte) (date.get(Calendar.HOUR))); AddParamByte((byte) (date.get(Calendar.MINUTE))); } public void AddParamDateTime(Date date) { AddParamByte((byte) (date.getSeconds())); AddParamByte((byte) (date.getMinutes())); AddParamByte((byte) (date.getHours())); AddParamByte((byte) (date.getDate())); AddParamByte((byte) (date.getMonth() + 1)); AddParamByte((byte) (date.getYear() - 100)); } public byte[] getRawMessageBytes() { this.buffer[0] = (byte) 0x7E; this.buffer[1] = (byte) 0x7E; int length = this.position - 3; this.buffer[2] = (byte) length; this.buffer[3] = (byte) 0xF1; this.AddParamInt(CRC.getCrc16(this.buffer, 3, length)); this.buffer[length + 5] = (byte) 0x2E; this.buffer[length + 6] = (byte) 0x2E; return Arrays.copyOf(buffer, length + 7); } public String getMessageName() { return MessageOriginalNames.getName(getCommand()); } public void handleMessage(byte[] bytes) { if (Config.logDanaMessageDetail) { if (bytes.length > 6) { int command = (bytes[5] & 0xFF) | ((bytes[4] << 8) & 0xFF00); log.debug("UNPROCESSED MSG: " + getMessageName() + " Command: " + String.format("%04X", command) + " Data: " + toHexString(bytes)); } else { log.debug("MISFORMATTED MSG: " + toHexString(bytes)); } } } public int getCommand() { int command = byteFromRawBuff(buffer, 5) | (byteFromRawBuff(buffer, 4) << 8); return command; } public static int byteFromRawBuff(byte[] buff, int offset) { return buff[offset] & 0xFF; } public static int intFromBuff(byte[] buff, int offset, int length) { offset += 6; switch (length) { case 1: return byteFromRawBuff(buff, offset); case 2: return (byteFromRawBuff(buff, offset) << 8) + byteFromRawBuff(buff, offset + 1); case 3: return (byteFromRawBuff(buff, offset + 2) << 16) + (byteFromRawBuff(buff, offset + 1) << 8) + byteFromRawBuff(buff, offset); case 4: return (byteFromRawBuff(buff, offset + 3) << 24) + (byteFromRawBuff(buff, offset + 2) << 16) + (byteFromRawBuff(buff, offset + 1) << 8) + byteFromRawBuff(buff, offset); } return 0; } public static Date dateTimeFromBuff(byte[] buff, int offset) { Date date = new Date( 100 + intFromBuff(buff, offset, 1), intFromBuff(buff, offset + 1, 1) - 1, intFromBuff(buff, offset + 2, 1), intFromBuff(buff, offset + 3, 1), intFromBuff(buff, offset + 4, 1), 0 ); return date; } public static Date dateTimeSecFromBuff(byte[] buff, int offset) { Date date = new Date( 100 + intFromBuff(buff, offset, 1), intFromBuff(buff, offset + 1, 1) - 1, intFromBuff(buff, offset + 2, 1), intFromBuff(buff, offset + 3, 1), intFromBuff(buff, offset + 4, 1), intFromBuff(buff, offset + 5, 1) ); return date; } public static Date dateFromBuff(byte[] buff, int offset) { Date date = new Date( 100 + intFromBuff(buff, offset, 1), intFromBuff(buff, offset + 1, 1) - 1, intFromBuff(buff, offset + 2, 1) ); return date; } @TargetApi(Build.VERSION_CODES.KITKAT) public static String stringFromBuff(byte[] buff, int offset, int length) { byte[] strbuff = new byte[length]; System.arraycopy(buff, offset + 6, strbuff, 0, length); return new String(strbuff, StandardCharsets.UTF_8); } @TargetApi(Build.VERSION_CODES.KITKAT) public static String asciiStringFromBuff(byte[] buff, int offset, int length) { byte[] strbuff = new byte[length]; System.arraycopy(buff, offset + 6, strbuff, 0, length); for (int pos = 0; pos < length; pos++) strbuff[pos] += 65; // "A" return new String(strbuff, StandardCharsets.UTF_8); } public static String toHexString(byte[] buff) { StringBuffer sb = new StringBuffer(); int count = 0; for (byte element : buff) { sb.append(String.format("%02x ", element)); if (++count % 4 == 0) sb.append(" "); } return sb.toString(); } }