From c4d868e4d4d5edebdf03431a1fa27d546c441e4e Mon Sep 17 00:00:00 2001
From: Volker Richert <v.richert@addmore.de>
Date: Thu, 15 Dec 2016 20:01:22 +0100
Subject: [PATCH] chnage messages

---
 .../message/ChannelNegotiateMessage.java      |  6 +-
 .../CloseConnectionRequestMessage.java        | 26 +++++++
 .../CloseConnectionResponseMessage.java       | 13 ++++
 ... ContourNextLinkBinaryRequestMessage.java} | 38 +++------
 .../ContourNextLinkBinaryResponseMessage.java | 15 ++++
 .../ContourNextLinkCommandMessage.java        | 11 ++-
 .../ContourNextLinkCommandResponse.java       | 13 ++++
 ...ContourNextLinkCommandResponseMessage.java | 13 ----
 .../message/ContourNextLinkMessage.java       | 32 +++-----
 .../ContourNextLinkRequestMessage.java        | 20 +++++
 .../ContourNextLinkResponseMessage.java       | 18 ++++-
 .../DeviceInfoResponseCommandMessage.java     |  4 +
 .../medtronic/message/MedtronicMessage.java   | 76 ------------------
 .../message/MedtronicPumpMessage.java         | 15 ++++
 .../message/MedtronicRequestMessage.java      | 77 +++++++++++++++++--
 .../message/MedtronicResponseMessage.java     |  2 +-
 .../message/OpenConnectionRequestMessage.java | 26 +++++++
 .../OpenConnectionResponseMessage.java        | 16 ++++
 .../message/ReadInfoRequestMessage.java       |  6 +-
 .../message/RequestLinkKeyRequestMessage.java |  2 +-
 20 files changed, 267 insertions(+), 162 deletions(-)
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionRequestMessage.java
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionResponseMessage.java
 rename app/src/main/java/info/nightscout/android/medtronic/message/{ContourNextLinkBinaryMessage.java => ContourNextLinkBinaryRequestMessage.java} (69%)
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryResponseMessage.java
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponse.java
 delete mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponseMessage.java
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkRequestMessage.java
 delete mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/MedtronicMessage.java
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/MedtronicPumpMessage.java
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionRequestMessage.java
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionResponseMessage.java

diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateMessage.java
index db32bac..544caaf 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateMessage.java
@@ -1,14 +1,14 @@
 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));
     }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionRequestMessage.java
new file mode 100644
index 0000000..a822ce7
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionRequestMessage.java
@@ -0,0 +1,26 @@
+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;
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionResponseMessage.java
new file mode 100644
index 0000000..03a9eb7
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionResponseMessage.java
@@ -0,0 +1,13 @@
+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
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryRequestMessage.java
similarity index 69%
rename from app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryMessage.java
rename to app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryRequestMessage.java
index b31d451..24238af 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryRequestMessage.java
@@ -1,28 +1,30 @@
 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));
-        }
-    }
-
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryResponseMessage.java
new file mode 100644
index 0000000..549ee88
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryResponseMessage.java
@@ -0,0 +1,15 @@
+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);
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandMessage.java
index 151fe48..9839f75 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandMessage.java
@@ -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;
     }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponse.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponse.java
new file mode 100644
index 0000000..12f9b95
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponse.java
@@ -0,0 +1,13 @@
+package info.nightscout.android.medtronic.message;
+
+import info.nightscout.android.medtronic.MedtronicCnlSession;
+
+/**
+ * Created by volker on 10.12.2016.
+ */
+public class ContourNextLinkCommandResponse extends ContourNextLinkBinaryResponseMessage {
+
+    public ContourNextLinkCommandResponse(byte[] payload) throws ChecksumException {
+        super(payload);
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponseMessage.java
deleted file mode 100644
index f5bde36..0000000
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkCommandResponseMessage.java
+++ /dev/null
@@ -1,13 +0,0 @@
-package info.nightscout.android.medtronic.message;
-
-import info.nightscout.android.medtronic.MedtronicCnlSession;
-
-/**
- * Created by volker on 10.12.2016.
- */
-public class ContourNextLinkCommandResponseMessage extends ContourNextLinkBinaryMessage {
-
-    public ContourNextLinkCommandResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
-        super(CommandType.NO_TYPE, pumpSession, payload);
-    }
-}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkMessage.java
index 168e931..36d39a4 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkMessage.java
@@ -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;
         }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkRequestMessage.java
new file mode 100644
index 0000000..390380d
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkRequestMessage.java
@@ -0,0 +1,20 @@
+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);
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkResponseMessage.java
index a2f913d..24d6aa8 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkResponseMessage.java
@@ -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]));
+        }
+    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoResponseCommandMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoResponseCommandMessage.java
index fec7c00..1400a26 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoResponseCommandMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoResponseCommandMessage.java
@@ -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.
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicMessage.java
deleted file mode 100644
index 86eef79..0000000
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicMessage.java
+++ /dev/null
@@ -1,76 +0,0 @@
-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();
-    }
-}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicPumpMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicPumpMessage.java
new file mode 100644
index 0000000..87c6db3
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicPumpMessage.java
@@ -0,0 +1,15 @@
+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);
+
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicRequestMessage.java
index fb7adb1..ff0185a 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicRequestMessage.java
@@ -1,20 +1,32 @@
 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:
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
index c7d51ff..8557561 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
@@ -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.
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionRequestMessage.java
new file mode 100644
index 0000000..3a5ea5f
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionRequestMessage.java
@@ -0,0 +1,26 @@
+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;
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionResponseMessage.java
new file mode 100644
index 0000000..38f4ffb
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionResponseMessage.java
@@ -0,0 +1,16 @@
+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
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoRequestMessage.java
index 770a6d2..dc2a97b 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoRequestMessage.java
@@ -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 {
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyRequestMessage.java
index fd4e16e..ea4a446 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyRequestMessage.java
@@ -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);
     }
-- 
GitLab