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 f8d7221cd559f19a863aa9195b10cbd2cdfbcc35..a94a0769d7150ea7431431589c0620abad6f3c47 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
@@ -82,9 +82,9 @@ public class MedtronicCnlReader {
             doRetry = false;
             try {
                 new ContourNextLinkCommandMessage(ContourNextLinkCommandMessage.ASCII.NAK)
-                        .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.EOT);
+                        .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.EOT);
                 new ContourNextLinkCommandMessage(ContourNextLinkCommandMessage.ASCII.ENQ)
-                        .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
+                        .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
             } catch (UnexpectedMessageException e2) {
                 try {
                     new ContourNextLinkCommandMessage(ContourNextLinkCommandMessage.ASCII.EOT).send(mDevice);
@@ -99,21 +99,21 @@ public class MedtronicCnlReader {
     public void enterPassthroughMode() throws IOException, TimeoutException, UnexpectedMessageException, ChecksumException, EncryptionException {
         Log.d(TAG, "Begin enterPasshtroughMode");
         new ContourNextLinkCommandMessage("W|")
-                .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
+                .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
         new ContourNextLinkCommandMessage("Q|")
-                .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
+                .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
         new ContourNextLinkCommandMessage("1|")
-                .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
+                .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
         Log.d(TAG, "Finished enterPasshtroughMode");
     }
 
-    public void openConnection() throws IOException, TimeoutException, NoSuchAlgorithmException, ChecksumException, EncryptionException {
+    public void openConnection() throws IOException, TimeoutException, NoSuchAlgorithmException, ChecksumException, EncryptionException, UnexpectedMessageException {
         Log.d(TAG, "Begin openConnection");
         new OpenConnectionRequestMessage(mPumpSession, mPumpSession.getHMAC()).send(mDevice);
         Log.d(TAG, "Finished openConnection");
     }
 
-    public void requestReadInfo() throws IOException, TimeoutException, EncryptionException, ChecksumException {
+    public void requestReadInfo() throws IOException, TimeoutException, EncryptionException, ChecksumException, UnexpectedMessageException {
         Log.d(TAG, "Begin requestReadInfo");
         ReadInfoResponseMessage response = new ReadInfoRequestMessage(mPumpSession).send(mDevice);
 
@@ -125,7 +125,7 @@ public class MedtronicCnlReader {
         Log.d(TAG, String.format("Finished requestReadInfo. linkMAC = '%d', pumpMAC = '%d", linkMAC, pumpMAC));
     }
 
-    public void requestLinkKey() throws IOException, TimeoutException, EncryptionException, ChecksumException {
+    public void requestLinkKey() throws IOException, TimeoutException, EncryptionException, ChecksumException, UnexpectedMessageException {
         Log.d(TAG, "Begin requestLinkKey");
 
         RequestLinkKeyResponseMessage response = new RequestLinkKeyRequestMessage(mPumpSession).send(mDevice);
@@ -169,7 +169,7 @@ public class MedtronicCnlReader {
         Log.d(TAG, "Finished beginEHSMSession");
     }
 
-    public Date getPumpTime() throws EncryptionException, IOException, ChecksumException, TimeoutException {
+    public Date getPumpTime() throws EncryptionException, IOException, ChecksumException, TimeoutException, UnexpectedMessageException {
         Log.d(TAG, "Begin getPumpTime");
         // FIXME - throw if not in EHSM mode (add a state machine)
 
@@ -191,7 +191,7 @@ public class MedtronicCnlReader {
         return pumpRecord;
     }
 
-    public void getBasalPatterns() throws EncryptionException, IOException, ChecksumException, TimeoutException {
+    public void getBasalPatterns() throws EncryptionException, IOException, ChecksumException, TimeoutException, UnexpectedMessageException {
         Log.d(TAG, "Begin getBasalPatterns");
         // FIXME - throw if not in EHSM mode (add a state machine)
 
@@ -216,7 +216,7 @@ public class MedtronicCnlReader {
         Log.d(TAG, "Finished endEHSMSession");
     }
 
-    public void closeConnection() throws IOException, TimeoutException, ChecksumException, EncryptionException, NoSuchAlgorithmException {
+    public void closeConnection() throws IOException, TimeoutException, ChecksumException, EncryptionException, NoSuchAlgorithmException, UnexpectedMessageException {
         Log.d(TAG, "Begin closeConnection");
         new CloseConnectionRequestMessage(mPumpSession, mPumpSession.getHMAC()).send(mDevice);
         Log.d(TAG, "Finished closeConnection");
@@ -225,18 +225,18 @@ public class MedtronicCnlReader {
     public void endPassthroughMode() throws IOException, TimeoutException, UnexpectedMessageException, ChecksumException, EncryptionException {
         Log.d(TAG, "Begin endPassthroughMode");
         new ContourNextLinkCommandMessage("W|")
-                .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
+                .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
         new ContourNextLinkCommandMessage("Q|")
-                .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
+                .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
         new ContourNextLinkCommandMessage("0|")
-                .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
+                .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ACK);
         Log.d(TAG, "Finished endPassthroughMode");
     }
 
     public void endControlMode() throws IOException, TimeoutException, UnexpectedMessageException, ChecksumException, EncryptionException {
         Log.d(TAG, "Begin endControlMode");
         new ContourNextLinkCommandMessage(ContourNextLinkCommandMessage.ASCII.EOT)
-                .send(mDevice).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ENQ);
+                .send(mDevice, 500).checkControlMessage(ContourNextLinkCommandMessage.ASCII.ENQ);
         Log.d(TAG, "Finished endControlMode");
     }
 }
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 dce2a91254a28f3ebcd1bd5b89e001b16b409cf1..3902beb03e6e87cdb322871d28fddb1ab80f3a85 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
@@ -11,7 +11,7 @@ import info.nightscout.android.medtronic.exception.EncryptionException;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class BeginEHSMMessage extends MedtronicSendMessageRequestMessage {
+public class BeginEHSMMessage extends EHSMMessage {
     public BeginEHSMMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.BEGIN_EHSM_SESSION, pumpSession, buildPayload());
     }
@@ -20,11 +20,4 @@ public class BeginEHSMMessage extends MedtronicSendMessageRequestMessage {
         // Not sure what the payload of a null byte means, but it's the same every time.
         return new byte[] { 0x00 };
     }
-
-    public void send(UsbHidDriver mDevice) throws IOException, TimeoutException {
-        sendMessage(mDevice);
-
-        // The Begin EHSM Session only has an 0x81 response
-        readMessage(mDevice);
-    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateRequestMessage.java
index 7fc63bb0fa17ceb2e8dfe6581ea098a4103617f4..84dc029782c0306a1f86e70c19b467fc3e7bea11 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ChannelNegotiateRequestMessage.java
@@ -15,13 +15,14 @@ import info.nightscout.android.medtronic.exception.EncryptionException;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class ChannelNegotiateRequestMessage extends MedtronicRequestMessage {
+public class ChannelNegotiateRequestMessage extends MedtronicRequestMessage<ChannelNegotiateResponseMessage> {
     private static final String TAG = ChannelNegotiateRequestMessage.class.getSimpleName();
 
     public ChannelNegotiateRequestMessage(MedtronicCnlSession pumpSession) throws ChecksumException {
         super(CommandType.SEND_MESSAGE, CommandAction.CHANNEL_NEGOTIATE, pumpSession, buildPayload(pumpSession));
     }
 
+    @Override
     public ChannelNegotiateResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, ChecksumException, EncryptionException {
         sendMessage(mDevice);
 
@@ -30,11 +31,16 @@ public class ChannelNegotiateRequestMessage extends MedtronicRequestMessage {
         readMessage(mDevice);
         // The 0x80 message
         Log.d(TAG, "negotiateChannel: Reading 0x80 message");
-        ChannelNegotiateResponseMessage response = new ChannelNegotiateResponseMessage(mPumpSession, readMessage(mDevice));
+        ChannelNegotiateResponseMessage response = this.getResponse(readMessage(mDevice));
 
         return response;
     }
 
+    @Override
+    protected ChannelNegotiateResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException {
+        return new ChannelNegotiateResponseMessage(mPumpSession, payload);
+    }
+
     protected static byte[] buildPayload( MedtronicCnlSession pumpSession ) {
         ByteBuffer payload = ByteBuffer.allocate(26);
         payload.order(ByteOrder.LITTLE_ENDIAN);
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
index c7a47bf7ff4e2568cb5938b3ce24a62d8bb33698..bc656cbd18a4b0c3177e339567f0d5c42d94d74a 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/CloseConnectionRequestMessage.java
@@ -12,17 +12,13 @@ import info.nightscout.android.medtronic.exception.EncryptionException;
  * Created by volker on 10.12.2016.
  */
 
-public class CloseConnectionRequestMessage extends ContourNextLinkBinaryRequestMessage {
+public class CloseConnectionRequestMessage extends ContourNextLinkBinaryRequestMessage<CloseConnectionResponseMessage> {
     public CloseConnectionRequestMessage(MedtronicCnlSession pumpSession, byte[] payload) throws ChecksumException {
         super(CommandType.CLOSE_CONNECTION, pumpSession, payload);
     }
 
-    public CloseConnectionResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
-        sendMessage(mDevice);
-
-        CloseConnectionResponseMessage response = new CloseConnectionResponseMessage(readMessage(mDevice));
-
-        // FIXME - We need to care what the response message is - wrong MAC and all that
-        return response;
+    @Override
+    protected CloseConnectionResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException {
+        return new CloseConnectionResponseMessage(payload);
     }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryRequestMessage.java
index 80b4270038f896794b8b0595a6811e7c83eea534..c56ef020740bc1ee0f9ea71e77e9807814e08cb0 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkBinaryRequestMessage.java
@@ -12,7 +12,7 @@ import info.nightscout.android.medtronic.exception.ChecksumException;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class ContourNextLinkBinaryRequestMessage extends ContourNextLinkRequestMessage {
+public abstract class ContourNextLinkBinaryRequestMessage<T> extends ContourNextLinkRequestMessage<T> {
     private final static int ENVELOPE_SIZE = 33;
 
     //protected ByteBuffer mBayerEnvelope;
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 fe571cb2f763c3f4dfa8119ddd969f30afb9491d..36b7530d61104c8c87bd63a8f604c8a6718874fd 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
@@ -6,11 +6,12 @@ import java.util.concurrent.TimeoutException;
 import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class ContourNextLinkCommandMessage extends ContourNextLinkRequestMessage {
+public class ContourNextLinkCommandMessage extends ContourNextLinkRequestMessage<ContourNextLinkCommandResponse> {
     public ContourNextLinkCommandMessage(ASCII command) {
         super(new byte[]{command.getValue()});
     }
@@ -23,13 +24,9 @@ public class ContourNextLinkCommandMessage extends ContourNextLinkRequestMessage
         super(command.getBytes());
     }
 
-
-    public ContourNextLinkCommandResponse send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
-        sendMessage(mDevice);
-
-        ContourNextLinkCommandResponse response = new ContourNextLinkCommandResponse(readMessage(mDevice));
-
-        // FIXME - We need to care what the response message is - wrong MAC and all that
-        return response;
+    @Override
+    protected ContourNextLinkCommandResponse getResponse(byte[] payload) throws ChecksumException {
+        return new ContourNextLinkCommandResponse(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 7ade34455c1c3b75a6a985505cee70f14ab80abe..891611b9061bb4677ab96500f0ead571533fe1d6 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
@@ -8,12 +8,15 @@ import java.nio.ByteBuffer;
 import java.util.concurrent.TimeoutException;
 
 import info.nightscout.android.USB.UsbHidDriver;
+import info.nightscout.android.medtronic.exception.ChecksumException;
+import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 import info.nightscout.android.utils.HexDump;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class ContourNextLinkMessage {
+public abstract class ContourNextLinkMessage {
     private static final String TAG = ContourNextLinkMessage.class.getSimpleName();
 
     private static final int USB_BLOCKSIZE = 64;
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
index 036c185f290caa5a8e0fbbe7ca37a51b83d92f5e..782c174530bf759ddfb5400a7fdb34a5449189bb 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ContourNextLinkRequestMessage.java
@@ -1,12 +1,42 @@
 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.exception.ChecksumException;
+import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
+
 /**
  * Created by volker on 12.12.2016.
  */
 
-public class ContourNextLinkRequestMessage extends ContourNextLinkMessage {
+public abstract class ContourNextLinkRequestMessage<T> extends ContourNextLinkMessage {
     protected ContourNextLinkRequestMessage(byte[] bytes) {
         super(bytes);
     }
+
+    public T send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException, UnexpectedMessageException {
+        return send(mDevice, 0);
+    }
+
+    public T send(UsbHidDriver mDevice, int millis) throws UnexpectedMessageException, EncryptionException, TimeoutException, ChecksumException, IOException {
+        sendMessage(mDevice);
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
+
+        T response = this.getResponse(readMessage(mDevice)); //new ContourNextLinkCommandResponse();
+
+        // FIXME - We need to care what the response message is - wrong MAC and all that
+        return response;
+    }
+
+    protected abstract <T> T getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException, TimeoutException;
+
 }
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 6c06030cf44b48278cf6cacb535e11c9a3ed35e0..dda70d1050ae9462942d13098a248a7552a3354b 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
@@ -10,7 +10,7 @@ import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class ContourNextLinkResponseMessage extends ContourNextLinkMessage {
+public abstract class ContourNextLinkResponseMessage extends ContourNextLinkMessage {
 
     public ContourNextLinkResponseMessage(byte[] payload) throws ChecksumException {
         super(payload);
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoRequestCommandMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoRequestCommandMessage.java
index 11515625c7def0f42c0594bd3d591e314701ca98..5c2f7d6fc3afa408897a3f69cefa4e11e13e97d4 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoRequestCommandMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/DeviceInfoRequestCommandMessage.java
@@ -12,15 +12,28 @@ import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
  * Created by volker on 10.12.2016.
  */
 
-public class DeviceInfoRequestCommandMessage extends ContourNextLinkRequestMessage {
+public class DeviceInfoRequestCommandMessage extends ContourNextLinkRequestMessage<DeviceInfoResponseCommandMessage> {
     public DeviceInfoRequestCommandMessage() {
         super("X".getBytes());
     }
 
-    public DeviceInfoResponseCommandMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException, UnexpectedMessageException {
+    @Override
+    public DeviceInfoResponseCommandMessage send(UsbHidDriver mDevice, int millis) throws IOException, TimeoutException, EncryptionException, ChecksumException, UnexpectedMessageException {
         sendMessage(mDevice);
 
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
         byte[] response1 = readMessage(mDevice);
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
         byte[] response2 = readMessage(mDevice);
 
         boolean doRetry = false;
@@ -30,12 +43,12 @@ public class DeviceInfoRequestCommandMessage extends ContourNextLinkRequestMessa
             try {
                 if (ASCII.EOT.equals(response1[0])) {
                     // response 1 is the ASTM message
-                    response = new DeviceInfoResponseCommandMessage(response1);
+                    response = this.getResponse(response1);
                     // ugly....
                     response.checkControlMessage(response2, ASCII.ENQ);
                 } else {
                     // response 2 is the ASTM message
-                    response = new DeviceInfoResponseCommandMessage(response1);
+                    response = this.getResponse(response1);
                     // ugly, too....
                     response.checkControlMessage(response1, ASCII.ENQ);
                 }
@@ -46,4 +59,9 @@ public class DeviceInfoRequestCommandMessage extends ContourNextLinkRequestMessa
 
         return response;
     }
+
+    @Override
+    protected DeviceInfoResponseCommandMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException, TimeoutException {
+        return new DeviceInfoResponseCommandMessage(payload);
+    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/EHSMMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/EHSMMessage.java
new file mode 100644
index 0000000000000000000000000000000000000000..1242361bdeb0a44c08ec7507912904926e4a45a6
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/EHSMMessage.java
@@ -0,0 +1,33 @@
+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;
+import info.nightscout.android.medtronic.exception.ChecksumException;
+import info.nightscout.android.medtronic.exception.EncryptionException;
+
+/**
+ * Created by volker on 22.12.2016.
+ */
+
+public class EHSMMessage extends  MedtronicSendMessageRequestMessage<ContourNextLinkResponseMessage>{
+    protected EHSMMessage(SendMessageType sendMessageType, MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
+        super(sendMessageType, pumpSession, payload);
+    }
+
+    @Override
+    public ContourNextLinkResponseMessage send(UsbHidDriver mDevice, int millis) throws IOException, TimeoutException {
+        sendMessage(mDevice);
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
+        // The End EHSM Session only has an 0x81 response
+        readMessage(mDevice);
+        return null;
+    }
+}
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 6058fc5bc48ea3b8332b55773c7afa3a5115afd0..5335d4cf3b5b48fef9231bc060f011026f5f1f8c 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
@@ -7,11 +7,12 @@ import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class EndEHSMMessage extends MedtronicSendMessageRequestMessage {
+public class EndEHSMMessage extends EHSMMessage {
     public EndEHSMMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.END_EHSM_SESSION, pumpSession, buildPayload());
     }
@@ -21,10 +22,4 @@ public class EndEHSMMessage extends MedtronicSendMessageRequestMessage {
         return new byte[] { 0x01 };
     }
 
-    public void send(UsbHidDriver mDevice) throws IOException, TimeoutException {
-        sendMessage(mDevice);
-
-        // The End EHSM Session only has an 0x81 response
-        readMessage(mDevice);
-    }
 }
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 27a96f29879708785a3806dd518c22b410805bf3..de69316e245171b9b0f3047c4c82a0b5326444b6 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
@@ -16,7 +16,7 @@ import info.nightscout.android.medtronic.exception.EncryptionException;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class MedtronicRequestMessage extends ContourNextLinkBinaryRequestMessage {
+public abstract class MedtronicRequestMessage<T> extends ContourNextLinkBinaryRequestMessage<T> {
     static int ENVELOPE_SIZE = 2;
     static int CRC_SIZE = 2;
 
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicSendMessageRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicSendMessageRequestMessage.java
index ee19eaf5d0fcb0d8ac7443c7be77dd899530804f..79053820b388eaea7223d30c7d6e3e94f2959305 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicSendMessageRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/MedtronicSendMessageRequestMessage.java
@@ -3,14 +3,16 @@ package info.nightscout.android.medtronic.message;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 /**
  * Created by volker on 18.12.2016.
  */
 
-public class MedtronicSendMessageRequestMessage  extends MedtronicRequestMessage {
+public abstract class MedtronicSendMessageRequestMessage<T>  extends MedtronicRequestMessage<T> {
     static int ENVELOPE_SIZE = 11;
     static int ENCRYPTED_ENVELOPE_SIZE = 3;
     static int CRC_SIZE = 2;
@@ -34,6 +36,11 @@ public class MedtronicSendMessageRequestMessage  extends MedtronicRequestMessage
         super(CommandType.SEND_MESSAGE, CommandAction.PUMP_REQUEST, pumpSession, buildPayload(sendMessageType, pumpSession, payload));
     }
 
+    @Override
+    protected ContourNextLinkResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException {
+        return null;
+    }
+
     /**
      * MedtronicSendMessage:
      * +-----------------+------------------------------+--------------+-------------------+--------------------------------+
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
index 1218b76740b7c8700c0a760d49ea151ede8215fa..85869867aaf3e5ce37ef1a05fdb76880ca04900b 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/OpenConnectionRequestMessage.java
@@ -12,17 +12,13 @@ import info.nightscout.android.medtronic.exception.EncryptionException;
  * Created by volker on 10.12.2016.
  */
 
-public class OpenConnectionRequestMessage extends ContourNextLinkBinaryRequestMessage {
+public class OpenConnectionRequestMessage extends ContourNextLinkBinaryRequestMessage<OpenConnectionResponseMessage> {
     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(readMessage(mDevice));
-
-        // FIXME - We need to care what the response message is - wrong MAC and all that
-        return response;
+    @Override
+    protected OpenConnectionResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException {
+        return new OpenConnectionResponseMessage(payload);
     }
 }
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 e91db4e6040239f8c51fc1b45e2e6319c07cf8f8..aa71df206607d8ef811415d199576042c063db3b 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
@@ -7,21 +7,18 @@ import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class PumpBasalPatternRequestMessage extends MedtronicSendMessageRequestMessage {
+public class PumpBasalPatternRequestMessage extends MedtronicSendMessageRequestMessage<PumpBasalPatternResponseMessage> {
     public PumpBasalPatternRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.READ_BASAL_PATTERN_REQUEST, pumpSession, null);
     }
 
-    public PumpBasalPatternResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, ChecksumException, EncryptionException {
-        sendMessage(mDevice);
-
-        // Read the 0x81
-        PumpBasalPatternResponseMessage response = new PumpBasalPatternResponseMessage(mPumpSession, readMessage(mDevice));
-
-        return response;
+    @Override
+    protected PumpBasalPatternResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException {
+        return new PumpBasalPatternResponseMessage(mPumpSession, payload);
     }
 }
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 c920309790aa2775dc46d7dd58f92bda38ae23a9..30067b48223b8e1efd4a2dfd2d06f4f091822cc8 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
@@ -12,19 +12,34 @@ import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class PumpStatusRequestMessage extends MedtronicSendMessageRequestMessage {
+public class PumpStatusRequestMessage extends MedtronicSendMessageRequestMessage<PumpStatusResponseMessage> {
     public PumpStatusRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.READ_PUMP_STATUS_REQUEST, pumpSession, null);
     }
 
-    public PumpStatusResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, ChecksumException, EncryptionException, UnexpectedMessageException {
+    public PumpStatusResponseMessage send(UsbHidDriver mDevice, int millis) throws IOException, TimeoutException, ChecksumException, EncryptionException, UnexpectedMessageException {
         sendMessage(mDevice);
-
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
         // Read the 0x81
         readMessage(mDevice);
-
-        PumpStatusResponseMessage response = new PumpStatusResponseMessage(mPumpSession, readMessage(mDevice));
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
+        PumpStatusResponseMessage response = this.getResponse(readMessage(mDevice));
 
         return response;
     }
+
+    @Override
+    protected PumpStatusResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException {
+        return new PumpStatusResponseMessage(mPumpSession, payload);
+    }
 }
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 a1128c947dcf59f5d854f6978955e775ff2527ef..24cbb144d87a530c034e5666127346298e3fcf70 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
@@ -7,24 +7,41 @@ import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class PumpTimeRequestMessage extends MedtronicSendMessageRequestMessage {
+public class PumpTimeRequestMessage extends MedtronicSendMessageRequestMessage<PumpTimeResponseMessage> {
     public PumpTimeRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.TIME_REQUEST, pumpSession, null);
     }
 
-    public PumpTimeResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, ChecksumException, EncryptionException {
+    @Override
+    public PumpTimeResponseMessage send(UsbHidDriver mDevice, int millis) throws IOException, TimeoutException, ChecksumException, EncryptionException, UnexpectedMessageException {
         sendMessage(mDevice);
-
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
         // Read the 0x81
         readMessage(mDevice);
-
+        if (millis > 0) {
+            try {
+                Thread.sleep(millis);
+            } catch (InterruptedException e) {
+            }
+        }
         // Read the 0x80
-        PumpTimeResponseMessage response = new PumpTimeResponseMessage(mPumpSession, readMessage(mDevice));
+        PumpTimeResponseMessage response = this.getResponse(readMessage(mDevice));
 
         return response;
     }
+
+    @Override
+    protected PumpTimeResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException {
+        return new PumpTimeResponseMessage(mPumpSession, payload);
+    }
 }
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoRequestMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoRequestMessage.java
index e2daaf066b167ce65c918735075a9a7dfe5dc236..ff7a2f692eee0d339f577e30c8059d84d5421dcf 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoRequestMessage.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoRequestMessage.java
@@ -12,7 +12,7 @@ import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
 /**
  * Created by lgoedhart on 26/03/2016.
  */
-public class ReadHistoryInfoRequestMessage extends MedtronicSendMessageRequestMessage {
+public class ReadHistoryInfoRequestMessage extends MedtronicSendMessageRequestMessage<ReadHistoryInfoResponseMessage> {
     public ReadHistoryInfoRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
         super(SendMessageType.READ_BASAL_PATTERN_REQUEST, pumpSession, new byte[] {
                 2,
@@ -30,12 +30,8 @@ public class ReadHistoryInfoRequestMessage extends MedtronicSendMessageRequestMe
         });
     }
 
-    public ReadHistoryInfoResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, ChecksumException, EncryptionException, UnexpectedMessageException {
-        sendMessage(mDevice);
-
-        // Read the 0x81
-        ReadHistoryInfoResponseMessage response = new ReadHistoryInfoResponseMessage(mPumpSession, readMessage(mDevice));
-
-        return response;
+    @Override
+    protected ReadHistoryInfoResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException {
+        return new ReadHistoryInfoResponseMessage(mPumpSession, payload);
     }
 }
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 065418b8c7ace5a8d00cb202cdb78e02cf07e6ba..c357cd5f25ac84be95988ea702987df8ed059deb 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
@@ -12,16 +12,13 @@ import info.nightscout.android.medtronic.exception.EncryptionException;
  * Created by volker on 10.12.2016.
  */
 
-public class ReadInfoRequestMessage extends ContourNextLinkBinaryRequestMessage {
+public class ReadInfoRequestMessage extends ContourNextLinkBinaryRequestMessage<ReadInfoResponseMessage> {
     public ReadInfoRequestMessage(MedtronicCnlSession pumpSession) throws ChecksumException {
         super(ContourNextLinkBinaryRequestMessage.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;
+    @Override
+    protected ReadInfoResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException {
+        return new ReadInfoResponseMessage(mPumpSession, payload);
     }
 }
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 a77669e9768de3c3aadb0e3989538c6f24b1a5b3..bc2d01869d3c7a47d2080d03bd134837d74fc618 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
@@ -12,16 +12,13 @@ import info.nightscout.android.medtronic.exception.EncryptionException;
  * Created by volker on 10.12.2016.
  */
 
-public class RequestLinkKeyRequestMessage extends ContourNextLinkBinaryRequestMessage {
+public class RequestLinkKeyRequestMessage extends ContourNextLinkBinaryRequestMessage<RequestLinkKeyResponseMessage> {
     public RequestLinkKeyRequestMessage(MedtronicCnlSession pumpSession) throws ChecksumException {
         super(CommandType.REQUEST_LINK_KEY, pumpSession, null);
     }
 
-    public RequestLinkKeyResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, EncryptionException, ChecksumException {
-        sendMessage(mDevice);
-
-        RequestLinkKeyResponseMessage response = new RequestLinkKeyResponseMessage(mPumpSession, readMessage(mDevice));
-
-        return response;
+    @Override
+    protected RequestLinkKeyResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException {
+        return new RequestLinkKeyResponseMessage(mPumpSession, payload);
     }
 }