diff --git a/640gAndroidUploader.iml b/640gAndroidUploader.iml
index dd11c422309587fbfb2c40dcfbc1c5c64bb0d573..21ad486e1dacdc31dfcf484957078ef9fbc29307 100644
--- a/640gAndroidUploader.iml
+++ b/640gAndroidUploader.iml
@@ -13,7 +13,7 @@
     <content url="file://$MODULE_DIR$">
       <excludeFolder url="file://$MODULE_DIR$/.gradle" />
     </content>
-    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
+    <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
 </module>
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java b/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
index 6dd908f0dd3f57b8d8c585d51690eaee4b82df5b..24b2c9b5793e2adc55cebc48b0ce999a008dd55e 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
@@ -32,6 +32,7 @@ import info.nightscout.android.medtronic.message.MedtronicMessage;
 import info.nightscout.android.medtronic.message.MessageUtils;
 import info.nightscout.android.medtronic.message.PumpBasalPatternRequestMessage;
 import info.nightscout.android.medtronic.message.PumpBasalPatternResponseMessage;
+import info.nightscout.android.medtronic.message.ReadInfoRequestMessage;
 import info.nightscout.android.medtronic.message.PumpStatusRequestMessage;
 import info.nightscout.android.medtronic.message.PumpStatusResponseMessage;
 import info.nightscout.android.medtronic.message.PumpTimeRequestMessage;
@@ -240,7 +241,7 @@ public class MedtronicCnlReader implements ContourNextLinkMessageHandler {
         Log.d(TAG, "Finished enterPasshtroughMode");
     }
 
-    public void openConnection() throws IOException, TimeoutException, NoSuchAlgorithmException {
+    public void openConnection() throws IOException, TimeoutException, NoSuchAlgorithmException, ChecksumException {
         Log.d(TAG, "Begin openConnection");
         new ContourNextLinkBinaryMessage(ContourNextLinkBinaryMessage.CommandType.OPEN_CONNECTION, mPumpSession, mPumpSession.getHMAC()).send(this);
         // FIXME - We need to care what the response message is - wrong MAC and all that
@@ -250,16 +251,11 @@ public class MedtronicCnlReader implements ContourNextLinkMessageHandler {
 
     public void requestReadInfo() throws IOException, TimeoutException, EncryptionException, ChecksumException {
         Log.d(TAG, "Begin requestReadInfo");
-        new ContourNextLinkBinaryMessage(ContourNextLinkBinaryMessage.CommandType.READ_INFO, mPumpSession, null).send(this);
 
-        ContourNextLinkMessage response = ReadInfoResponseMessage.fromBytes(mPumpSession, readMessage());
+        ReadInfoResponseMessage response = new ReadInfoRequestMessage(mPumpSession).send(mDevice);
 
-        // FIXME - this needs to go into ReadInfoResponseMessage
-        ByteBuffer infoBuffer = ByteBuffer.allocate(16);
-        infoBuffer.order(ByteOrder.BIG_ENDIAN);
-        infoBuffer.put(response.encode(), 0x21, 16);
-        long linkMAC = infoBuffer.getLong(0);
-        long pumpMAC = infoBuffer.getLong(8);
+        long linkMAC = response.getLinkMAC();
+        long pumpMAC = response.getPumpMAC();
 
         this.getPumpSession().setLinkMAC(linkMAC);
         this.getPumpSession().setPumpMAC(pumpMAC);
@@ -327,7 +323,7 @@ public class MedtronicCnlReader implements ContourNextLinkMessageHandler {
         return mPumpSession.getRadioChannel();
     }
 
-    public void beginEHSMSession() throws EncryptionException, IOException, TimeoutException {
+    public void beginEHSMSession() throws EncryptionException, IOException, TimeoutException, ChecksumException {
         Log.d(TAG, "Begin beginEHSMSession");
         new BeginEHSMMessage(mPumpSession).send(this);
         // The Begin EHSM Session only has an 0x81 response
@@ -492,7 +488,7 @@ public class MedtronicCnlReader implements ContourNextLinkMessageHandler {
         Log.d(TAG, "Finished getBasalPatterns");
     }
 
-    public void endEHSMSession() throws EncryptionException, IOException, TimeoutException {
+    public void endEHSMSession() throws EncryptionException, IOException, TimeoutException, ChecksumException {
         Log.d(TAG, "Begin endEHSMSession");
         new EndEHSMMessage(mPumpSession).send(this);
         // The End EHSM Session only has an 0x81 response
@@ -500,7 +496,7 @@ public class MedtronicCnlReader implements ContourNextLinkMessageHandler {
         Log.d(TAG, "Finished endEHSMSession");
     }
 
-    public void closeConnection() throws IOException, TimeoutException {
+    public void closeConnection() throws IOException, TimeoutException, ChecksumException {
         Log.d(TAG, "Begin closeConnection");
         new ContourNextLinkBinaryMessage(ContourNextLinkBinaryMessage.CommandType.CLOSE_CONNECTION, mPumpSession, null).send(this);
         // FIXME - We need to care what the response message is - wrong MAC and all that
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/BeginEHSMMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/BeginEHSMMessage.java
index e2ee643a1a0d9f7de0a0c566c6d2d147ad6e3e19..804ce6d2d75b17522bd6ef046229e33397104d65 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/BeginEHSMMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/BeginEHSMMessage.java
@@ -1,12 +1,15 @@
 package info.nightscout.android.medtronic.message;
 
+import java.io.IOException;
+
+import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class BeginEHSMMessage extends MedtronicSendMessage {
-    public BeginEHSMMessage(MedtronicCnlSession pumpSession) throws EncryptionException {
+public class BeginEHSMMessage extends MedtronicRequestMessage {
+    public BeginEHSMMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.BEGIN_EHSM_SESSION, pumpSession, buildPayload());
     }
 
@@ -14,4 +17,9 @@ public class BeginEHSMMessage extends MedtronicSendMessage {
         // Not sure what the payload of a null byte means, but it's the same every time.
         return new byte[] { 0x00 };
     }
+
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        super.sendMessage(mDevice);
+        mPumpSession.incrMedtronicSequenceNumber();
+    }
 }
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 eda3ce6f6f514f3045396216dc658b65e825e5fc..db32bac435844e3cb586cee8d192c8ee824f335e 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
@@ -9,7 +9,7 @@ import java.nio.ByteOrder;
  * Created by lgoedhart on 26/03/2016.
  */
 public class ChannelNegotiateMessage extends MedtronicMessage {
-    public ChannelNegotiateMessage(MedtronicCnlSession pumpSession) {
+    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/ContourNextLinkBinaryMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryMessage.java
index 95e94baa56ef73718e3db0d2d13e272f8b48a058..4a3f94bd07cacac066df13a416f51f06b4e6e3d3 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryMessage.java
@@ -1,7 +1,9 @@
 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;
@@ -9,11 +11,11 @@ import java.util.Locale;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage{
+public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage {
     //protected ByteBuffer mBayerEnvelope;
     //protected ByteBuffer mBayerPayload;
-    //protected MedtronicCNLSession mPumpSession;
-    //protected CommandType mCommandType = CommandType.NO_TYPE;
+    protected MedtronicCnlSession mPumpSession;
+    protected CommandType mCommandType = CommandType.NO_TYPE;
 
     static int ENVELOPE_SIZE = 33;
 
@@ -40,8 +42,29 @@ public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage{
         }
     }
 
-    public ContourNextLinkBinaryMessage(CommandType commandType, MedtronicCnlSession pumpSession, byte[] payload) {
+    public ContourNextLinkBinaryMessage(CommandType commandType, MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
         super(buildPayload(commandType, pumpSession, payload));
+        mCommandType = commandType;
+        mPumpSession = pumpSession;
+
+        // Validate checksum
+        byte messageChecksum = this.mPayload.get(32);
+        byte calculatedChecksum = (byte) (MessageUtils.oneByteSum(this.mPayload.array()) - messageChecksum);
+
+        if (messageChecksum != calculatedChecksum) {
+            throw new ChecksumException(String.format(Locale.getDefault(), "Expected to get %d. Got %d", (int) calculatedChecksum, (int) messageChecksum));
+        }
+    }
+
+    /**
+     * Handle incrementing sequence number
+     *
+     * @param mDevice
+     * @throws IOException
+     */
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        super.sendMessage(mDevice);
+        mPumpSession.incrBayerSequenceNumber();
     }
 
     protected static byte[] buildPayload(CommandType commandType, MedtronicCnlSession pumpSession, byte[] payload) {
@@ -75,7 +98,12 @@ public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage{
 
     public static ContourNextLinkMessage fromBytes(byte[] bytes) throws ChecksumException {
         ContourNextLinkMessage message = new ContourNextLinkMessage(bytes);
+        message.validate();
+
+        return message;
+    }
 
+    protected void validate(ContourNextLinkMessage message)  throws ChecksumException {
         // Validate checksum
         byte messageChecksum = message.mPayload.get(32);
         byte calculatedChecksum = (byte) (MessageUtils.oneByteSum(message.mPayload.array()) - messageChecksum);
@@ -84,6 +112,6 @@ public class ContourNextLinkBinaryMessage extends ContourNextLinkMessage{
             throw new ChecksumException(String.format(Locale.getDefault(), "Expected to get %d. Got %d", (int) calculatedChecksum, (int) messageChecksum));
         }
 
-        return message;
+
     }
 }
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 2a44cfdeede51c0ec2d21d6b6128aa17a04cbd10..2639e76c56591663bd69c1745892e11de2603ec9 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
@@ -1,32 +1,102 @@
 package info.nightscout.android.medtronic.message;
 
+import android.util.Log;
+
+import java.io.ByteArrayOutputStream;
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.util.concurrent.TimeoutException;
+
+import info.nightscout.android.USB.UsbHidDriver;
+import info.nightscout.android.utils.HexDump;
+
+import static android.R.id.message;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
 public class ContourNextLinkMessage {
+    private static final String TAG = ContourNextLinkMessage.class.getSimpleName();
+
+    private static final int USB_BLOCKSIZE = 64;
+    private static final int READ_TIMEOUT_MS = 5000;
+    private static final String BAYER_USB_HEADER = "ABC";
+
     protected ByteBuffer mPayload;
 
-    public ContourNextLinkMessage(byte[] bytes) {
-        if (bytes != null) {
-            this.mPayload = ByteBuffer.allocate(bytes.length);
-            this.mPayload.put(bytes);
-        }
+    protected ContourNextLinkMessage(byte[] bytes) {
+        setPayload(bytes);
     }
 
     public byte[] encode() {
         return mPayload.array();
     }
 
+    // TODO refactor
     public void send(ContourNextLinkMessageHandler handler) throws IOException {
         handler.sendMessage(this);
     }
 
+
     // FIXME - get rid of this - make a Builder instead
     protected void setPayload(byte[] payload) {
-        mPayload = ByteBuffer.allocate(payload.length);
-        mPayload.put(payload);
+        if (payload != null) {
+            mPayload = ByteBuffer.allocate(payload.length);
+            mPayload.put(payload);
+        }
+    }
+
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        int pos = 0;
+        byte[] message = this.encode();
+
+        while (message.length > pos) {
+            ByteBuffer outputBuffer = ByteBuffer.allocate(USB_BLOCKSIZE);
+            int sendLength = (pos + 60 > message.length) ? message.length - pos : 60;
+            outputBuffer.put(BAYER_USB_HEADER.getBytes());
+            outputBuffer.put((byte) sendLength);
+            outputBuffer.put(message, pos, sendLength);
+
+            mDevice.write(outputBuffer.array(), 200);
+            pos += sendLength;
+
+            String outputString = HexDump.dumpHexString(outputBuffer.array());
+            Log.d(TAG, "WRITE: " + outputString);
+        }
     }
+
+    protected byte[] readMessage(UsbHidDriver mDevice) throws IOException, TimeoutException {
+        ByteArrayOutputStream responseMessage = new ByteArrayOutputStream();
+
+        byte[] responseBuffer = new byte[USB_BLOCKSIZE];
+        int bytesRead;
+        int messageSize = 0;
+
+        do {
+            bytesRead = mDevice.read(responseBuffer, READ_TIMEOUT_MS);
+
+            if (bytesRead == -1) {
+                throw new TimeoutException("Timeout waiting for response from pump");
+            } else if (bytesRead > 0) {
+                // Validate the header
+                ByteBuffer header = ByteBuffer.allocate(3);
+                header.put(responseBuffer, 0, 3);
+                String headerString = new String(header.array());
+                if (!headerString.equals(BAYER_USB_HEADER)) {
+                    throw new IOException("Unexpected header received");
+                }
+                messageSize = responseBuffer[3];
+                responseMessage.write(responseBuffer, 4, messageSize);
+            } else {
+                Log.w(TAG, "readMessage: got a zero-sized response.");
+            }
+        } while (bytesRead > 0 && messageSize == 60);
+
+        String responseString = HexDump.dumpHexString(responseMessage.toByteArray());
+        Log.d(TAG, "READ: " + responseString);
+
+        return responseMessage.toByteArray();
+    }
+
+    protected void validate() {};
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/EndEHSMMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/EndEHSMMessage.java
index 0364110375aec3d9c5f6b9c940f500d363758e4f..fc7c4dd6f46e9a8a5788e79c7628027ccde16951 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/EndEHSMMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/EndEHSMMessage.java
@@ -1,12 +1,15 @@
 package info.nightscout.android.medtronic.message;
 
+import java.io.IOException;
+
+import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class EndEHSMMessage extends MedtronicSendMessage {
-    public EndEHSMMessage(MedtronicCnlSession pumpSession) throws EncryptionException {
+public class EndEHSMMessage extends MedtronicRequestMessage {
+    public EndEHSMMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.END_EHSM_SESSION, pumpSession, buildPayload());
     }
 
@@ -14,4 +17,9 @@ public class EndEHSMMessage extends MedtronicSendMessage {
         // Not sure what the payload byte means, but it's the same every time.
         return new byte[] { 0x01 };
     }
+
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        super.sendMessage(mDevice);
+        mPumpSession.incrMedtronicSequenceNumber();
+    }
 }
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
index 25588505ab2e817307d0428108a0e2bb98ef4eb7..f0386d7553f5dd1bbf1451f4657de5af4b4cfb43 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicMessage.java
@@ -1,7 +1,9 @@
 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;
 
@@ -29,7 +31,7 @@ public class MedtronicMessage extends ContourNextLinkBinaryMessage {
         }
     }
 
-    protected MedtronicMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) {
+    protected MedtronicMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
         super(commandType, pumpSession, buildPayload(commandAction, payload));
     }
 
@@ -93,4 +95,9 @@ public class MedtronicMessage extends ContourNextLinkBinaryMessage {
         }
         return decrypted;
     }
+
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        super.sendMessage(mDevice);
+        mPumpSession.incrMedtronicSequenceNumber();
+    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicSendMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicRequestMessage.java
similarity index 89%
rename from app/src/main/java/info/nightscout/android/medtronic/message/MedtronicSendMessage.java
rename to app/src/main/java/info/nightscout/android/medtronic/message/MedtronicRequestMessage.java
index 7bba4ded16da96428fd056f5b985ce821ee9e63e..fb7adb104e540d748aecfaaf5674c286afae6aec 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicSendMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicRequestMessage.java
@@ -1,14 +1,16 @@
 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;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class MedtronicSendMessage extends MedtronicMessage {
+public class MedtronicRequestMessage extends MedtronicMessage {
     static int ENVELOPE_SIZE = 11;
     static int ENCRYPTED_ENVELOPE_SIZE = 3;
     static int CRC_SIZE = 2;
@@ -28,17 +30,17 @@ public class MedtronicSendMessage extends MedtronicMessage {
         }
     }
 
-    protected MedtronicSendMessage(SendMessageType sendMessageType, MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException {
+    protected MedtronicRequestMessage(SendMessageType sendMessageType, MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
         super(CommandType.SEND_MESSAGE, CommandAction.PUMP_REQUEST, pumpSession, buildPayload(sendMessageType, pumpSession, payload));
     }
 
     /**
-     * MedtronicSendMessage:
+     * MedtronicRequestMessage:
      * +-----------------+------------------------------+--------------+-------------------+--------------------------------+
      * | LE long pumpMAC | byte medtronicSequenceNumber | byte unknown | byte Payload size | byte[] Encrypted Payload bytes |
      * +-----------------+------------------------------+--------------+-------------------+--------------------------------+
      * <p/>
-     * MedtronicSendMessage (decrypted payload):
+     * MedtronicRequestMessage (decrypted payload):
      * +-------------------------+----------------------+----------------------+--------------------+
      * | byte sendSequenceNumber | BE short sendMessageType | byte[] Payload bytes | BE short CCITT CRC |
      * +-------------------------+----------------------+----------------------+--------------------+
@@ -81,4 +83,5 @@ public class MedtronicSendMessage extends MedtronicMessage {
                 return 0x00;
         }
     }
+
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicReceiveMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
similarity index 62%
rename from app/src/main/java/info/nightscout/android/medtronic/message/MedtronicReceiveMessage.java
rename to app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
index c2f4a7d58cf10d70925e3d2ab15e3358a4ff3a3f..f70b27c9404089ce5968ecfda756aeabc5752d98 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicReceiveMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicResponseMessage.java
@@ -7,13 +7,33 @@ import java.nio.ByteBuffer;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class MedtronicReceiveMessage extends MedtronicMessage {
+public class MedtronicResponseMessage extends MedtronicMessage {
     static int ENVELOPE_SIZE = 22;
     static int ENCRYPTED_ENVELOPE_SIZE = 3;
     static int CRC_SIZE = 2;
 
-    protected MedtronicReceiveMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) {
-        super(commandType, commandAction, pumpSession, payload);
+    protected MedtronicResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
+        super(CommandType.NO_TYPE, CommandAction.NO_TYPE, pumpSession, 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.
+        // Also, READ_INFO and REQUEST_LINK_KEY are not encrypted
+        if (payload.length >= 57 &&
+                (payload[18] != CommandType.READ_INFO.getValue()) &&
+                (payload[18] != CommandType.REQUEST_LINK_KEY_RESPONSE.getValue())) {
+            // Replace the encrypted bytes by their decrypted equivalent (same block size)
+            byte encryptedPayloadSize = payload[56];
+
+            ByteBuffer encryptedPayload = ByteBuffer.allocate(encryptedPayloadSize);
+            encryptedPayload.put(payload, 57, encryptedPayloadSize);
+            byte[] decryptedPayload = decrypt(pumpSession.getKey(), pumpSession.getIV(), encryptedPayload.array());
+
+            // Now that we have the decrypted payload, rewind the mPayload, and overwrite the bytes
+            // TODO - because this messes up the existing CCITT, do we want to have a separate buffer for the decrypted payload?
+            // Should be fine provided we check the CCITT first...
+            this.mPayload.position(57);
+            this.mPayload.put(decryptedPayload);
+        }
     }
 
     public enum ReceiveMessageType {
@@ -28,20 +48,24 @@ public class MedtronicReceiveMessage extends MedtronicMessage {
     }
 
     /**
-     * MedtronicReceiveMessage:
+     * MedtronicResponseMessage:
      * +------------------+-----------------+-----------------+---------------------------------+-------------------+--------------------------------+
      * | LE short unknown | LE long pumpMAC | LE long linkMAC | byte[3] responseSequenceNumber? | byte Payload size | byte[] Encrypted Payload bytes |
      * +------------------+-----------------+-----------------+---------------------------------+-------------------+--------------------------------+
      * <p/>
-     * MedtronicReceiveMessage (decrypted payload):
+     * MedtronicResponseMessage (decrypted payload):
      * +----------------------------+-----------------------------+----------------------+--------------------+
      * | byte receiveSequenceNumber | BE short receiveMessageType | byte[] Payload bytes | BE short CCITT CRC |
      * +----------------------------+-----------------------------+----------------------+--------------------+
      */
     public static ContourNextLinkMessage fromBytes(MedtronicCnlSession pumpSession, byte[] bytes) throws ChecksumException, EncryptionException {
         // TODO - turn this into a factory
+
+        return new MedtronicResponseMessage(pumpSession, bytes);
+        /*
         ContourNextLinkMessage message = MedtronicMessage.fromBytes(bytes);
 
+
         // 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.
@@ -62,6 +86,7 @@ public class MedtronicReceiveMessage extends MedtronicMessage {
             message.mPayload.position(57);
             message.mPayload.put(decryptedPayload);
         }
-        return message;
+        return message;*/
     }
+
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternRequestMessage.java
index d31eb36a229654efedd6b9849fac749c1b748254..a00715319d580be7e5ab90d8cb00af3ccc2ba802 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternRequestMessage.java
@@ -1,12 +1,20 @@
 package info.nightscout.android.medtronic.message;
 
+import java.io.IOException;
+
+import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class PumpBasalPatternRequestMessage extends MedtronicSendMessage {
-    public PumpBasalPatternRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException {
+public class PumpBasalPatternRequestMessage extends MedtronicRequestMessage {
+    public PumpBasalPatternRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.READ_BASAL_PATTERN_REQUEST, pumpSession, null);
     }
+
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        super.sendMessage(mDevice);
+        mPumpSession.incrMedtronicSequenceNumber();
+    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternResponseMessage.java
index d4b4ef97d55422a5d5be2a5179879569a59cfcad..43132b661edfbcb0e2e3f2d66c5b39147cdb5646 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpBasalPatternResponseMessage.java
@@ -5,14 +5,14 @@ import info.nightscout.android.medtronic.MedtronicCnlSession;
 /**
  * Created by lgoedhart on 27/03/2016.
  */
-public class PumpBasalPatternResponseMessage extends MedtronicReceiveMessage {
-    protected PumpBasalPatternResponseMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) {
-        super(commandType, commandAction, pumpSession, payload);
+public class PumpBasalPatternResponseMessage extends MedtronicResponseMessage {
+    protected PumpBasalPatternResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
+        super(pumpSession, payload);
     }
 
     public static ContourNextLinkMessage fromBytes(MedtronicCnlSession pumpSession, byte[] bytes) throws ChecksumException, EncryptionException {
         // TODO - turn this into a factory
-        ContourNextLinkMessage message = MedtronicReceiveMessage.fromBytes(pumpSession, bytes);
+        ContourNextLinkMessage message = MedtronicResponseMessage.fromBytes(pumpSession, bytes);
 
         // TODO - Validate the MessageType
 
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusRequestMessage.java
index 1162bfe139ca65e06fe1eb95571f1ff67520f78c..0c507a6ae06e91133a3188896ed8e41aa46be7fd 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusRequestMessage.java
@@ -1,12 +1,20 @@
 package info.nightscout.android.medtronic.message;
 
+import java.io.IOException;
+
+import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class PumpStatusRequestMessage extends MedtronicSendMessage {
-    public PumpStatusRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException {
+public class PumpStatusRequestMessage extends MedtronicRequestMessage {
+    public PumpStatusRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.READ_PUMP_STATUS_REQUEST, pumpSession, null);
     }
+
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        super.sendMessage(mDevice);
+        mPumpSession.incrMedtronicSequenceNumber();
+    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
index 06e9a0f3357d2456f64a5eb7c84ac3218d1e35ee..151348e08ba528e1a0fcbe751db5bbcf81d8e39e 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpStatusResponseMessage.java
@@ -5,14 +5,14 @@ import info.nightscout.android.medtronic.MedtronicCnlSession;
 /**
  * Created by lgoedhart on 27/03/2016.
  */
-public class PumpStatusResponseMessage extends MedtronicReceiveMessage {
-    protected PumpStatusResponseMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) {
-        super(commandType, commandAction, pumpSession, payload);
+public class PumpStatusResponseMessage extends MedtronicResponseMessage {
+    protected PumpStatusResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
+        super(pumpSession, payload);
     }
 
     public static ContourNextLinkMessage fromBytes(MedtronicCnlSession pumpSession, byte[] bytes) throws ChecksumException, EncryptionException {
         // TODO - turn this into a factory
-        ContourNextLinkMessage message = MedtronicReceiveMessage.fromBytes(pumpSession, bytes);
+        ContourNextLinkMessage message = MedtronicResponseMessage.fromBytes(pumpSession, bytes);
 
         // TODO - Validate the MessageType
 
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeRequestMessage.java
index 89305b0a9b3873d3ec4079eeacebf8d740443ffe..c773fa1034cacad0cd1fc3ff355f5969a0e88aae 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeRequestMessage.java
@@ -1,12 +1,20 @@
 package info.nightscout.android.medtronic.message;
 
+import java.io.IOException;
+
+import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class PumpTimeRequestMessage extends MedtronicSendMessage {
-    public PumpTimeRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException {
+public class PumpTimeRequestMessage extends MedtronicRequestMessage {
+    public PumpTimeRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.TIME_REQUEST, pumpSession, null);
     }
+
+    protected void sendMessage(UsbHidDriver mDevice) throws IOException {
+        super.sendMessage(mDevice);
+        mPumpSession.incrMedtronicSequenceNumber();
+    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java
index 3437dd69c65e9adfe188966ea14cbc1a6f8afb18..6f1ca90a46d23986267e29670a2d805bc7dd981e 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/PumpTimeResponseMessage.java
@@ -5,14 +5,14 @@ import info.nightscout.android.medtronic.MedtronicCnlSession;
 /**
  * Created by lgoedhart on 27/03/2016.
  */
-public class PumpTimeResponseMessage extends MedtronicReceiveMessage {
-    protected PumpTimeResponseMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) {
-        super(commandType, commandAction, pumpSession, payload);
+public class PumpTimeResponseMessage extends MedtronicResponseMessage {
+    protected PumpTimeResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
+        super(pumpSession, payload);
     }
 
     public static ContourNextLinkMessage fromBytes(MedtronicCnlSession pumpSession, byte[] bytes) throws ChecksumException, EncryptionException {
         // TODO - turn this into a factory
-        ContourNextLinkMessage message = MedtronicReceiveMessage.fromBytes(pumpSession, bytes);
+        ContourNextLinkMessage message = MedtronicResponseMessage.fromBytes(pumpSession, bytes);
 
         // TODO - Validate the MessageType
 
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
new file mode 100644
index 0000000000000000000000000000000000000000..770a6d2ce0bb37599619c61d424995e29ae08361
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoRequestMessage.java
@@ -0,0 +1,28 @@
+package info.nightscout.android.medtronic.message;
+
+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 ReadInfoRequestMessage(MedtronicCnlSession pumpSession) throws ChecksumException {
+        super(ContourNextLinkBinaryMessage.CommandType.READ_INFO, pumpSession, null);
+    }
+
+    public ReadInfoResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
+        sendMessage(mDevice);
+
+        ReadInfoResponseMessage response = new ReadInfoResponseMessage(mPumpSession, readMessage(mDevice));
+
+        return response;
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoResponseMessage.java
index 68aab2df7977d4235e1c445b4b8ac0692d16e88b..87eaf9f20fd82c03383a8f7408a03fa794d7bfb2 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ReadInfoResponseMessage.java
@@ -1,21 +1,36 @@
 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 ReadInfoResponseMessage extends MedtronicReceiveMessage {
-    protected ReadInfoResponseMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) {
-        super(commandType, commandAction, pumpSession, payload);
+public class ReadInfoResponseMessage extends MedtronicResponseMessage {
+    private long linkMAC;
+    private long pumpMAC;
+
+    protected ReadInfoResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException, EncryptionException {
+        super(pumpSession, payload);
+
+        ByteBuffer infoBuffer = ByteBuffer.allocate(16);
+        infoBuffer.order(ByteOrder.BIG_ENDIAN);
+        infoBuffer.put(this.encode(), 0x21, 16);
+        linkMAC = infoBuffer.getLong(0);
+        pumpMAC = infoBuffer.getLong(8);
     }
 
     public static ContourNextLinkMessage fromBytes(MedtronicCnlSession pumpSession, byte[] bytes) throws ChecksumException, EncryptionException {
-        // TODO - turn this into a factory
-        ContourNextLinkMessage message = MedtronicReceiveMessage.fromBytes(pumpSession, bytes);
+        return new ReadInfoResponseMessage(pumpSession, bytes);
+    }
 
-        // TODO - Validate the MessageType
+    public long getLinkMAC() {
+        return linkMAC;
+    }
 
-        return message;
+    public long getPumpMAC() {
+        return pumpMAC;
     }
 }
\ No newline at end of file
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyResponseMessage.java
index 423e40fb8ab61296fc9c26995837a56932715a7e..08aa3a33826648fb99675162891b520b898802a5 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyResponseMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/RequestLinkKeyResponseMessage.java
@@ -5,14 +5,14 @@ import info.nightscout.android.medtronic.MedtronicCnlSession;
 /**
  * Created by lgoedhart on 10/05/2016.
  */
-public class RequestLinkKeyResponseMessage extends MedtronicReceiveMessage {
-    protected RequestLinkKeyResponseMessage(CommandType commandType, CommandAction commandAction, MedtronicCnlSession pumpSession, byte[] payload) {
-        super(commandType, commandAction, pumpSession, payload);
+public class RequestLinkKeyResponseMessage extends MedtronicResponseMessage {
+    protected RequestLinkKeyResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
+        super(pumpSession, payload);
     }
 
     public static ContourNextLinkMessage fromBytes(MedtronicCnlSession pumpSession, byte[] bytes) throws ChecksumException, EncryptionException {
         // TODO - turn this into a factory
-        ContourNextLinkMessage message = MedtronicReceiveMessage.fromBytes(pumpSession, bytes);
+        ContourNextLinkMessage message = MedtronicResponseMessage.fromBytes(pumpSession, bytes);
 
         // TODO - Validate the MessageType