Skip to content
Snippets Groups Projects
Commit c4d868e4 authored by Volker Richert's avatar Volker Richert
Browse files

chnage messages

parent a5806364
No related branches found
No related tags found
No related merge requests found
Showing
with 267 additions and 149 deletions
package info.nightscout.android.medtronic.message;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by lgoedhart on 26/03/2016.
*/
public class ChannelNegotiateMessage extends MedtronicMessage {
public class ChannelNegotiateMessage extends MedtronicRequestMessage {
public ChannelNegotiateMessage(MedtronicCnlSession pumpSession) throws ChecksumException {
super(CommandType.SEND_MESSAGE, CommandAction.CHANNEL_NEGOTIATE, pumpSession, buildPayload(pumpSession));
}
......
package info.nightscout.android.medtronic.message;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by volker on 10.12.2016.
*/
public class CloseConnectionRequestMessage extends ContourNextLinkBinaryRequestMessage {
public CloseConnectionRequestMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(CommandType.CLOSE_CONNECTION, pumpSession, payload);
}
public OpenConnectionResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
sendMessage(mDevice);
OpenConnectionResponseMessage response = new OpenConnectionResponseMessage(mPumpSession, readMessage(mDevice));
// FIXME - We need to care what the response message is - wrong MAC and all that
return response;
}
}
package info.nightscout.android.medtronic.message;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by lgoedhart on 10/05/2016.
*/
public class CloseConnectionResponseMessage extends MedtronicResponseMessage {
protected CloseConnectionResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException, EncryptionException {
super(pumpSession, payload);
}
}
\ No newline at end of file
package info.nightscout.android.medtronic.message;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Locale;
import java.util.concurrent.TimeoutException;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by lgoedhart on 26/03/2016.
*/
public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage {
public class ContourNextLinkBinaryRequestMessage extends ContourNextLinkRequestMessage {
private final static int ENVELOPE_SIZE = 33;
//protected ByteBuffer mBayerEnvelope;
//protected ByteBuffer mBayerPayload;
protected CommandType mCommandType = CommandType.NO_TYPE;
protected MedtronicCnlSession mPumpSession;
private final static int ENVELOPE_SIZE = 33;
public ContourNextLinkBinaryRequestMessage(CommandType commandType, MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(buildPayload(commandType, pumpSession, payload));
public ContourNextLinkBinaryMessage(CommandType commandType, MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(pumpSession, buildPayload(commandType, pumpSession, payload));
mCommandType = commandType;
mPumpSession = pumpSession;
this.mPumpSession = pumpSession;
this.mCommandType = commandType;
// Validate checksum
byte messageChecksum = this.mPayload.get(32);
......@@ -33,14 +35,6 @@ public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage {
}
}
public static ContourNextLinkMessage fromBytes(byte[] bytes) throws ChecksumException {
ContourNextLinkMessage message = new ContourNextLinkMessage(bytes);
message.validate();
return message;
}
/**
* Handle incrementing sequence number
*
......@@ -81,14 +75,4 @@ public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage {
return payloadBuffer.array();
}
protected void validate(ContourNextLinkMessage message) throws ChecksumException {
// Validate checksum
byte messageChecksum = message.mPayload.get(32);
byte calculatedChecksum = (byte) (MessageUtils.oneByteSum(message.mPayload.array()) - messageChecksum);
if (messageChecksum != calculatedChecksum) {
throw new ChecksumException(String.format(Locale.getDefault(), "Expected to get %d. Got %d", (int) calculatedChecksum, (int) messageChecksum));
}
}
}
package info.nightscout.android.medtronic.message;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.TimeoutException;
/**
* Created by lgoedhart on 26/03/2016.
*/
public class ContourNextLinkBinaryResponseMessage extends ContourNextLinkResponseMessage {
public ContourNextLinkBinaryResponseMessage(byte[] payload) throws ChecksumException {
super(payload);
}
}
......@@ -4,13 +4,14 @@ import java.io.IOException;
import java.util.concurrent.TimeoutException;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by lgoedhart on 26/03/2016.
*/
public class ContourNextLinkCommandMessage extends ContourNextLinkMessage {
public class ContourNextLinkCommandMessage extends ContourNextLinkRequestMessage {
public ContourNextLinkCommandMessage(ASCII command) {
super(new byte[]{command.value});
super(new byte[]{command.getValue()});
}
public ContourNextLinkCommandMessage(byte command) {
......@@ -21,11 +22,13 @@ public class ContourNextLinkCommandMessage extends ContourNextLinkMessage {
super(command.getBytes());
}
public ContourNextLinkCommandResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException, UnexpectedMessageException {
public ContourNextLinkCommandResponse send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
sendMessage(mDevice);
ContourNextLinkCommandResponseMessage response = new ContourNextLinkCommandResponseMessage(mPumpSession, readMessage(mDevice));;
ContourNextLinkCommandResponse response = new ContourNextLinkCommandResponse(readMessage(mDevice));
// FIXME - We need to care what the response message is - wrong MAC and all that
return response;
}
}
......@@ -5,9 +5,9 @@ import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by volker on 10.12.2016.
*/
public class ContourNextLinkCommandResponseMessage extends ContourNextLinkBinaryMessage {
public class ContourNextLinkCommandResponse extends ContourNextLinkBinaryResponseMessage {
public ContourNextLinkCommandResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(CommandType.NO_TYPE, pumpSession, payload);
public ContourNextLinkCommandResponse(byte[] payload) throws ChecksumException {
super(payload);
}
}
......@@ -25,15 +25,6 @@ public class ContourNextLinkMessage {
private static final String BAYER_USB_HEADER = "ABC";
protected ByteBuffer mPayload;
protected MedtronicCnlSession mPumpSession;
protected void checkControlMessage(byte[] msg, ASCII controlCharacter) throws IOException, TimeoutException, UnexpectedMessageException {
if (msg.length != 1 || msg[0] != controlCharacter.value) {
throw new UnexpectedMessageException(String.format(Locale.getDefault(), "Expected to get control character '%d' Got '%d'.",
(int) controlCharacter.value, (int) msg[0]));
}
}
public enum CommandAction {
NO_TYPE(0x0),
......@@ -47,15 +38,16 @@ public class ContourNextLinkMessage {
value = (byte) commandAction;
}
public final byte getValue() {
public byte getValue() {
return value;
}
public final boolean equals(byte value) {
public boolean equals(byte value) {
return this.value == value;
}
}
public enum CommandType {
NO_TYPE(0x0),
OPEN_CONNECTION(0x10),
......@@ -74,17 +66,16 @@ public class ContourNextLinkMessage {
value = (byte) commandType;
}
public final byte getValue() {
public byte getValue() {
return value;
}
public final boolean equals(byte value) {
public boolean equals(byte value) {
return this.value == value;
}
}
protected ContourNextLinkMessage(MedtronicCnlSession pumpSession, byte[] bytes) {
this.mPumpSession = pumpSession;
protected ContourNextLinkMessage(byte[] bytes) {
setPayload(bytes);
}
......@@ -106,10 +97,6 @@ public class ContourNextLinkMessage {
}
}
public void checkControlMessage(ASCII controlCharacter) throws IOException, TimeoutException, UnexpectedMessageException {
checkControlMessage(mPayload.array(), controlCharacter);
}
protected void sendMessage(UsbHidDriver mDevice) throws IOException {
int pos = 0;
byte[] message = this.encode();
......@@ -162,9 +149,6 @@ public class ContourNextLinkMessage {
return responseMessage.toByteArray();
}
protected void validate() {};
public enum ASCII {
STX(0x02),
EOT(0x04),
......@@ -178,6 +162,10 @@ public class ContourNextLinkMessage {
this.value = (byte) code;
}
public byte getValue() {
return value;
}
public boolean equals(byte value) {
return this.value == value;
}
......
package info.nightscout.android.medtronic.message;
import java.io.IOException;
import java.util.Locale;
import java.util.concurrent.TimeoutException;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import info.nightscout.android.medtronic.message.ContourNextLinkMessage;
import info.nightscout.android.medtronic.message.UnexpectedMessageException;
/**
* Created by volker on 12.12.2016.
*/
public class ContourNextLinkRequestMessage extends ContourNextLinkMessage {
protected ContourNextLinkRequestMessage(byte[] bytes) {
super(bytes);
}
}
......@@ -8,16 +8,28 @@ import java.util.concurrent.TimeoutException;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import info.nightscout.android.medtronic.message.ChecksumException;
import info.nightscout.android.medtronic.message.ContourNextLinkMessage;
import info.nightscout.android.medtronic.message.UnexpectedMessageException;
/**
* Created by lgoedhart on 26/03/2016.
*/
public class ContourNextLinkResponseMessage extends ContourNextLinkMessage {
public ContourNextLinkResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(pumpSession, payload);
mPumpSession = pumpSession;
public ContourNextLinkResponseMessage(byte[] payload) throws ChecksumException {
super(payload);
}
public void checkControlMessage(ASCII controlCharacter) throws IOException, TimeoutException, UnexpectedMessageException {
checkControlMessage(mPayload.array(), controlCharacter);
}
public void checkControlMessage(byte[] msg, ASCII controlCharacter) throws IOException, TimeoutException, UnexpectedMessageException {
if (msg.length != 1 || !controlCharacter.equals(msg[0])) {
throw new UnexpectedMessageException(String.format(Locale.getDefault(), "Expected to get control character '%d' Got '%d'.",
(int) controlCharacter.getValue(), (int) msg[0]));
}
}
}
......@@ -6,6 +6,10 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import info.nightscout.android.medtronic.message.ChecksumException;
import info.nightscout.android.medtronic.message.EncryptionException;
import info.nightscout.android.medtronic.message.MedtronicResponseMessage;
import info.nightscout.android.medtronic.message.UnexpectedMessageException;
/**
* Created by lgoedhart on 10/05/2016.
......
package info.nightscout.android.medtronic.message;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
/**
* Created by lgoedhart on 26/03/2016.
*/
public class MedtronicMessage extends ContourNextLinkBinaryMessage {
static int ENVELOPE_SIZE = 2;
static int CRC_SIZE = 2;
protected MedtronicMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(commandType, pumpSession, buildPayload(commandAction, payload));
}
/**
* MedtronicMessage:
* +---------------+-------------------+----------------------+--------------------+
* | CommandAction | byte Payload Size | byte[] Payload bytes | LE short CCITT CRC |
* +---------------+-------------------+----------------------+--------------------+
*/
protected static byte[] buildPayload(CommandAction commandAction, byte[] payload) {
byte payloadLength = (byte) (payload == null ? 0 : payload.length);
ByteBuffer payloadBuffer = ByteBuffer.allocate(ENVELOPE_SIZE + payloadLength + CRC_SIZE);
payloadBuffer.order(ByteOrder.LITTLE_ENDIAN);
payloadBuffer.put(commandAction.getValue());
payloadBuffer.put((byte) (ENVELOPE_SIZE + payloadLength));
if (payloadLength != 0) {
payloadBuffer.put(payload != null ? payload : new byte[0]);
}
payloadBuffer.putShort((short) MessageUtils.CRC16CCITT(payloadBuffer.array(), 0xffff, 0x1021, ENVELOPE_SIZE + payloadLength));
return payloadBuffer.array();
}
public static ContourNextLinkMessage fromBytes(byte[] bytes) throws ChecksumException {
ContourNextLinkMessage message = ContourNextLinkBinaryMessage.fromBytes(bytes);
// TODO - Validate the CCITT
return message;
}
// TODO - maybe move the SecretKeySpec, IvParameterSpec and Cipher construction into the PumpSession?
protected static byte[] encrypt(byte[] key, byte[] iv, byte[] clear) throws EncryptionException {
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
byte[] encrypted = new byte[0];
try {
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
encrypted = cipher.doFinal(clear);
} catch (Exception e) {
throw new EncryptionException( "Could not encrypt Medtronic Message" );
}
return encrypted;
}
protected void sendMessage(UsbHidDriver mDevice) throws IOException {
super.sendMessage(mDevice);
mPumpSession.incrMedtronicSequenceNumber();
}
}
package info.nightscout.android.medtronic.message;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by volker on 15.12.2016.
*/
public class MedtronicPumpMessage extends ContourNextLinkMessage {
protected MedtronicPumpMessage(MedtronicCnlSession pumpSession, byte[] bytes) {
super(bytes);
}
}
package info.nightscout.android.medtronic.message;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by lgoedhart on 26/03/2016.
*/
public class MedtronicRequestMessage extends MedtronicMessage {
public class MedtronicRequestMessage extends ContourNextLinkBinaryRequestMessage {
static int ENVELOPE_SIZE = 11;
static int ENCRYPTED_ENVELOPE_SIZE = 3;
static int CRC_SIZE = 2;
protected MedtronicRequestMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(commandType, pumpSession, buildPayload(commandAction, payload));
}
protected MedtronicRequestMessage(SendMessageType sendMessageType, MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
this(CommandType.SEND_MESSAGE, CommandAction.PUMP_REQUEST, pumpSession, buildPayload(sendMessageType, pumpSession, payload));
}
public enum SendMessageType {
NO_TYPE(0x0),
BEGIN_EHSM_SESSION(0x412),
......@@ -28,19 +40,47 @@ public class MedtronicRequestMessage extends MedtronicMessage {
SendMessageType(int messageType) {
value = (short) messageType;
}
public short getValue() {
return value;
}
public boolean equals(short value) {
return this.value == value;
}
}
protected MedtronicRequestMessage(SendMessageType sendMessageType, MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
super(CommandType.SEND_MESSAGE, CommandAction.PUMP_REQUEST, pumpSession, buildPayload(sendMessageType, pumpSession, payload));
/**
* MedtronicMessage:
* +---------------+-------------------+----------------------+--------------------+
* | CommandAction | byte Payload Size | byte[] Payload bytes | LE short CCITT CRC |
* +---------------+-------------------+----------------------+--------------------+
*/
protected static byte[] buildPayload(CommandAction commandAction, byte[] payload) {
byte payloadLength = (byte) (payload == null ? 0 : payload.length);
ByteBuffer payloadBuffer = ByteBuffer.allocate(ENVELOPE_SIZE + payloadLength + CRC_SIZE);
payloadBuffer.order(ByteOrder.LITTLE_ENDIAN);
payloadBuffer.put(commandAction.getValue());
payloadBuffer.put((byte) (ENVELOPE_SIZE + payloadLength));
if (payloadLength != 0) {
payloadBuffer.put(payload != null ? payload : new byte[0]);
}
payloadBuffer.putShort((short) MessageUtils.CRC16CCITT(payloadBuffer.array(), 0xffff, 0x1021, ENVELOPE_SIZE + payloadLength));
return payloadBuffer.array();
}
/**
* MedtronicRequestMessage:
* MedtronicSendMessage:
* +-----------------+------------------------------+--------------+-------------------+--------------------------------+
* | LE long pumpMAC | byte medtronicSequenceNumber | byte unknown | byte Payload size | byte[] Encrypted Payload bytes |
* +-----------------+------------------------------+--------------+-------------------+--------------------------------+
* <p/>
* MedtronicRequestMessage (decrypted payload):
* MedtronicSendMessage (decrypted payload):
* +-------------------------+----------------------+----------------------+--------------------+
* | byte sendSequenceNumber | BE short sendMessageType | byte[] Payload bytes | BE short CCITT CRC |
* +-------------------------+----------------------+----------------------+--------------------+
......@@ -71,6 +111,27 @@ public class MedtronicRequestMessage extends MedtronicMessage {
return payloadBuffer.array();
}
// TODO - maybe move the SecretKeySpec, IvParameterSpec and Cipher construction into the PumpSession?
protected static byte[] encrypt(byte[] key, byte[] iv, byte[] clear) throws EncryptionException {
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
IvParameterSpec ivSpec = new IvParameterSpec(iv);
byte[] encrypted = new byte[0];
try {
Cipher cipher = Cipher.getInstance("AES/CFB/NoPadding");
cipher.init(Cipher.ENCRYPT_MODE, secretKeySpec, ivSpec);
encrypted = cipher.doFinal(clear);
} catch (Exception e) {
throw new EncryptionException( "Could not encrypt Medtronic Message" );
}
return encrypted;
}
protected void sendMessage(UsbHidDriver mDevice) throws IOException {
super.sendMessage(mDevice);
mPumpSession.incrMedtronicSequenceNumber();
}
protected static byte sendSequenceNumber(SendMessageType sendMessageType) {
switch (sendMessageType) {
case BEGIN_EHSM_SESSION:
......
......@@ -17,7 +17,7 @@ public class MedtronicResponseMessage extends ContourNextLinkResponseMessage {
static int CRC_SIZE = 2;
protected MedtronicResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
super(pumpSession, payload);
super(payload);
// TODO - Validate the message, inner CCITT, serial numbers, etc
// If there's not 57 bytes, then we got back a bad message. Not sure how to process these yet.
......
package info.nightscout.android.medtronic.message;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by volker on 10.12.2016.
*/
public class OpenConnectionRequestMessage extends ContourNextLinkBinaryRequestMessage {
public OpenConnectionRequestMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
super(CommandType.OPEN_CONNECTION, pumpSession, payload);
}
public OpenConnectionResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
sendMessage(mDevice);
OpenConnectionResponseMessage response = new OpenConnectionResponseMessage(mPumpSession, readMessage(mDevice));
// FIXME - We need to care what the response message is - wrong MAC and all that
return response;
}
}
package info.nightscout.android.medtronic.message;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import info.nightscout.android.medtronic.MedtronicCnlSession;
/**
* Created by lgoedhart on 10/05/2016.
*/
public class OpenConnectionResponseMessage extends MedtronicResponseMessage {
protected OpenConnectionResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException, EncryptionException {
super(pumpSession, payload);
}
}
\ No newline at end of file
......@@ -5,17 +5,15 @@ import java.io.IOException;
import info.nightscout.android.USB.UsbHidDriver;
import info.nightscout.android.medtronic.MedtronicCnlSession;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.concurrent.TimeoutException;
/**
* Created by volker on 10.12.2016.
*/
public class ReadInfoRequestMessage extends ContourNextLinkBinaryMessage {
public class ReadInfoRequestMessage extends ContourNextLinkBinaryRequestMessage {
public ReadInfoRequestMessage(MedtronicCnlSession pumpSession) throws ChecksumException {
super(ContourNextLinkBinaryMessage.CommandType.READ_INFO, pumpSession, null);
super(ContourNextLinkBinaryRequestMessage.CommandType.READ_INFO, pumpSession, null);
}
public ReadInfoResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
......
......@@ -10,7 +10,7 @@ import info.nightscout.android.medtronic.MedtronicCnlSession;
* Created by volker on 10.12.2016.
*/
public class RequestLinkKeyRequestMessage extends ContourNextLinkBinaryMessage {
public class RequestLinkKeyRequestMessage extends ContourNextLinkBinaryRequestMessage {
public RequestLinkKeyRequestMessage(MedtronicCnlSession pumpSession) throws ChecksumException {
super(CommandType.REQUEST_LINK_KEY, pumpSession, null);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment