From 918f0603a561483cc56999e0971ada9531b4d54c Mon Sep 17 00:00:00 2001
From: Volker Richert <v.richert@addmore.de>
Date: Sun, 18 Dec 2016 16:44:36 +0100
Subject: [PATCH] fix if pump is away from start creating new messages

---
 .../android/medtronic/MedtronicCnlReader.java | 16 ++++++-
 .../message/ContourNextLinkMessage.java       |  5 ++-
 .../message/MedtronicRequestMessage.java      | 11 ++++-
 .../PumpBasalPatternRequestMessage.java       |  3 --
 .../PumpBasalPatternResponseMessage.java      | 13 ++++--
 .../message/PumpStatusRequestMessage.java     |  3 +-
 .../message/PumpStatusResponseMessage.java    |  7 +--
 .../ReadHistoryInfoRequestMessage.java        | 41 ++++++++++++++++++
 .../ReadHistoryInfoResponseMessage.java       | 43 +++++++++++++++++++
 .../service/MedtronicCnlIntentService.java    | 12 ++++++
 .../model/medtronicNg/PumpStatusEvent.java    |  5 ++-
 11 files changed, 143 insertions(+), 16 deletions(-)
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoRequestMessage.java
 create mode 100644 app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java

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 6bea733..f8d7221 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/MedtronicCnlReader.java
@@ -30,6 +30,8 @@ import info.nightscout.android.medtronic.message.PumpStatusRequestMessage;
 import info.nightscout.android.medtronic.message.PumpStatusResponseMessage;
 import info.nightscout.android.medtronic.message.PumpTimeRequestMessage;
 import info.nightscout.android.medtronic.message.PumpTimeResponseMessage;
+import info.nightscout.android.medtronic.message.ReadHistoryInfoRequestMessage;
+import info.nightscout.android.medtronic.message.ReadHistoryInfoResponseMessage;
 import info.nightscout.android.medtronic.message.ReadInfoRequestMessage;
 import info.nightscout.android.medtronic.message.ReadInfoResponseMessage;
 import info.nightscout.android.medtronic.message.RequestLinkKeyRequestMessage;
@@ -152,6 +154,8 @@ public class MedtronicCnlReader {
 
             if (response.getRadioChannel() == mPumpSession.getRadioChannel()) {
                 break;
+            } else {
+                mPumpSession.setRadioChannel((byte)0);
             }
         }
 
@@ -175,7 +179,7 @@ public class MedtronicCnlReader {
         return response.getPumpTime();
     }
 
-    public PumpStatusEvent updatePumpStatus(PumpStatusEvent pumpRecord) throws IOException, EncryptionException, ChecksumException, TimeoutException {
+    public PumpStatusEvent updatePumpStatus(PumpStatusEvent pumpRecord) throws IOException, EncryptionException, ChecksumException, TimeoutException, UnexpectedMessageException {
         Log.d(TAG, "Begin updatePumpStatus");
 
         // FIXME - throw if not in EHSM mode (add a state machine)
@@ -196,6 +200,16 @@ public class MedtronicCnlReader {
         Log.d(TAG, "Finished getBasalPatterns");
     }
 
+
+    public void getHistory() throws EncryptionException, IOException, ChecksumException, TimeoutException, UnexpectedMessageException {
+        Log.d(TAG, "Begin getHistory");
+        // FIXME - throw if not in EHSM mode (add a state machine)
+
+        ReadHistoryInfoResponseMessage response = new ReadHistoryInfoRequestMessage(mPumpSession).send(mDevice);
+
+        Log.d(TAG, "Finished getHistory");
+    }
+
     public void endEHSMSession() throws EncryptionException, IOException, TimeoutException, ChecksumException {
         Log.d(TAG, "Begin endEHSMSession");
         new EndEHSMMessage(mPumpSession).send(mDevice);
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 f548900..7ade344 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
@@ -44,7 +44,6 @@ public class ContourNextLinkMessage {
     }
 
     public enum CommandType {
-        NO_TYPE(0x0),
         OPEN_CONNECTION(0x10),
         CLOSE_CONNECTION(0x11),
         SEND_MESSAGE(0x12),
@@ -53,7 +52,9 @@ public class ContourNextLinkMessage {
         SEND_LINK_KEY(0x17),
         RECEIVE_MESSAGE(0x80),
         SEND_MESSAGE_RESPONSE(0x81),
-        REQUEST_LINK_KEY_RESPONSE(0x86);
+        REQUEST_LINK_KEY_RESPONSE(0x86),
+
+        NO_TYPE(0x0);
 
         private byte value;
 
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 d727510..27a96f2 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
@@ -25,12 +25,19 @@ public class MedtronicRequestMessage extends ContourNextLinkBinaryRequestMessage
     }
 
     public enum SendMessageType {
-        NO_TYPE(0x0),
         BEGIN_EHSM_SESSION(0x412),
         TIME_REQUEST(0x0403),
         READ_PUMP_STATUS_REQUEST(0x0112),
         READ_BASAL_PATTERN_REQUEST(0x0112),
-        END_EHSM_SESSION(0x412);
+        END_EHSM_SESSION(0x412),
+
+        READ_HISTORY_INFO_MESSAGE(0x030C),
+        READ_HISTORY_MESSAGE(0x0304),
+        READ_TRACE_HISTORY_MESSAGE(0x0302),
+
+        INITIATE_MULTIPACKET_TRANSFER_COMMAND(0xFF00),
+
+        NO_TYPE(0x0);
 
         private short value;
 
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 5ce32c2..e91db4e 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
@@ -20,9 +20,6 @@ public class PumpBasalPatternRequestMessage extends MedtronicSendMessageRequestM
         sendMessage(mDevice);
 
         // Read the 0x81
-        readMessage(mDevice);
-
-        // Read the 0x80
         PumpBasalPatternResponseMessage response = new PumpBasalPatternResponseMessage(mPumpSession, readMessage(mDevice));
 
         return response;
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 310bef3..e3f96eb 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
@@ -1,16 +1,21 @@
 package info.nightscout.android.medtronic.message;
 
+import android.util.Log;
+
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 
 import info.nightscout.android.medtronic.MedtronicCnlSession;
 import info.nightscout.android.medtronic.exception.ChecksumException;
 import info.nightscout.android.medtronic.exception.EncryptionException;
+import info.nightscout.android.utils.HexDump;
 
 /**
  * Created by lgoedhart on 27/03/2016.
  */
 public class PumpBasalPatternResponseMessage extends MedtronicSendMessageResponseMessage {
+    private static final String TAG = PumpBasalPatternResponseMessage.class.getSimpleName();
+
     protected PumpBasalPatternResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
         super(pumpSession, payload);
 
@@ -24,10 +29,12 @@ public class PumpBasalPatternResponseMessage extends MedtronicSendMessageRespons
         }
         */
 
-        // FIXME - this needs to go into PumpBasalPatternResponseMessage
-        ByteBuffer basalRatesBuffer = ByteBuffer.allocate(96);
+        ByteBuffer basalRatesBuffer = ByteBuffer.allocate(payload.length);
         basalRatesBuffer.order(ByteOrder.BIG_ENDIAN);
-        basalRatesBuffer.put(this.encode(), 0x39, 96);
+        basalRatesBuffer.put(this.encode());
+
+        String responseString = HexDump.dumpHexString(basalRatesBuffer.array());
+        Log.d(TAG, "PumpStatus: " + responseString);
 
     }
 
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 043fba5..c920309 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
@@ -7,6 +7,7 @@ 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.
@@ -16,7 +17,7 @@ public class PumpStatusRequestMessage extends MedtronicSendMessageRequestMessage
         super(SendMessageType.READ_PUMP_STATUS_REQUEST, pumpSession, null);
     }
 
-    public PumpStatusResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, ChecksumException, EncryptionException {
+    public PumpStatusResponseMessage send(UsbHidDriver mDevice) throws IOException, TimeoutException, ChecksumException, EncryptionException, UnexpectedMessageException {
         sendMessage(mDevice);
 
         // Read the 0x81
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 69afac0..377a651 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
@@ -6,10 +6,12 @@ import java.math.BigDecimal;
 import java.nio.ByteBuffer;
 import java.nio.ByteOrder;
 import java.util.Date;
+import java.util.Locale;
 
 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 info.nightscout.android.model.medtronicNg.PumpStatusEvent;
 
 /**
@@ -45,17 +47,16 @@ public class PumpStatusResponseMessage extends MedtronicSendMessageResponseMessa
     private long rtc;
     private long offset;
 
-    protected PumpStatusResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
+    protected PumpStatusResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException, UnexpectedMessageException {
         super(pumpSession, payload);
 
         if (this.encode().length < (57 + 96)) {
             // Invalid message. Don't try and parse it
             // TODO - deal with this more elegantly
             Log.e(TAG, "Invalid message received for updatePumpStatus");
-            return;
+            throw new UnexpectedMessageException("Invalid message received for updatePumpStatus");
         }
 
-        // FIXME - this needs to go into PumpStatusResponseMessage
         ByteBuffer statusBuffer = ByteBuffer.allocate(96);
         statusBuffer.order(ByteOrder.BIG_ENDIAN);
         statusBuffer.put(this.encode(), 0x39, 96);
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
new file mode 100644
index 0000000..e2daaf0
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoRequestMessage.java
@@ -0,0 +1,41 @@
+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;
+import info.nightscout.android.medtronic.exception.UnexpectedMessageException;
+
+/**
+ * Created by lgoedhart on 26/03/2016.
+ */
+public class ReadHistoryInfoRequestMessage extends MedtronicSendMessageRequestMessage {
+    public ReadHistoryInfoRequestMessage(MedtronicCnlSession pumpSession) throws EncryptionException, ChecksumException {
+        super(SendMessageType.READ_BASAL_PATTERN_REQUEST, pumpSession, new byte[] {
+                2,
+                3,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0,
+                0
+        });
+    }
+
+    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;
+    }
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java b/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java
new file mode 100644
index 0000000..3780502
--- /dev/null
+++ b/app/src/main/java/info/nightscout/android/medtronic/message/ReadHistoryInfoResponseMessage.java
@@ -0,0 +1,43 @@
+package info.nightscout.android.medtronic.message;
+
+import android.util.Log;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+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 info.nightscout.android.utils.HexDump;
+
+/**
+ * Created by lgoedhart on 27/03/2016.
+ */
+public class ReadHistoryInfoResponseMessage extends MedtronicSendMessageResponseMessage {
+    private static final String TAG = ReadHistoryInfoResponseMessage.class.getSimpleName();
+
+    protected ReadHistoryInfoResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException, UnexpectedMessageException {
+        super(pumpSession, payload);
+
+
+        if (this.encode().length < 32) {
+            // Invalid message.
+            // TODO - deal with this more elegantly
+            Log.e(TAG, "Invalid message received for ReadHistoryInfo");
+            throw new UnexpectedMessageException("Invalid message received for ReadHistoryInfo");
+        } else {
+
+            ByteBuffer basalRatesBuffer = ByteBuffer.allocate(payload.length);
+            basalRatesBuffer.order(ByteOrder.BIG_ENDIAN);
+            basalRatesBuffer.put(this.encode());
+
+            String responseString = HexDump.dumpHexString(basalRatesBuffer.array());
+            Log.d(TAG, "ReadHistoryInfo: " + responseString);
+            Log.d(TAG, "ReadHistoryInfo-length: " + basalRatesBuffer.getLong(28));
+        }
+
+
+    }
+
+}
diff --git a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
index f907b94..68fa08f 100644
--- a/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
+++ b/app/src/main/java/info/nightscout/android/medtronic/service/MedtronicCnlIntentService.java
@@ -21,6 +21,7 @@ import java.util.Date;
 import java.util.Locale;
 import java.util.concurrent.TimeoutException;
 
+import info.nightscout.android.BuildConfig;
 import info.nightscout.android.R;
 import info.nightscout.android.USB.UsbHidDriver;
 import info.nightscout.android.medtronic.MainActivity;
@@ -220,6 +221,7 @@ public class MedtronicCnlIntentService extends IntentService {
                     Log.d(TAG, String.format("Connected to Contour Next Link on channel %d.", (int) radioChannel));
                     cnlReader.beginEHSMSession();
 
+                    // read pump status
                     PumpStatusEvent pumpRecord = realm.createObject(PumpStatusEvent.class);
 
                     String deviceName = String.format("medtronic-640g://%s", cnlReader.getStickSerial());
@@ -238,6 +240,16 @@ public class MedtronicCnlIntentService extends IntentService {
                     cnlReader.updatePumpStatus(pumpRecord);
                     activePump.getPumpHistory().add(pumpRecord);
 
+                    // start reading other data in debug only
+                    if (BuildConfig.DEBUG) {
+                        // read basal pattern
+                        //cnlReader.getBasalPatterns();
+
+                        // Read history
+                        //cnlReader.getHistory();
+                    }
+
+
                     cnlReader.endEHSMSession();
 
                     boolean cancelTransaction = true;
diff --git a/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java b/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
index d73f3e6..ba62b7d 100644
--- a/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
+++ b/app/src/main/java/info/nightscout/android/model/medtronicNg/PumpStatusEvent.java
@@ -82,7 +82,10 @@ public class PumpStatusEvent extends RealmObject {
     }
 
     public void setCgmTrend(CGM_TREND cgmTrend) {
-        this.cgmTrend = cgmTrend.name();
+        if (cgmTrend != null)
+            this.cgmTrend = cgmTrend.name();
+        else
+            this.cgmTrend = CGM_TREND.NOT_SET.name();
     }
 
     public void setCgmTrend(String cgmTrend) {
-- 
GitLab