Skip to content
Snippets Groups Projects
Commit 88516e2b authored by Pogman's avatar Pogman
Browse files

Fixes to stop the CNL from going into an error state:

 Intercept unexpected messages from the CNL

These usually come from pump requests as it can occasionally resend message responses several times (possibly due to a missed CNL ACK during CNL-PUMP comms?)

Mostly noted on the higher radio channels, channel 26 shows this the most

If these messages are not cleared the CNL will likely error needing to be unplugged to reset as it expects them to be read before any further commands are sent
parent 02593e29
No related branches found
No related tags found
No related merge requests found
......@@ -20,7 +20,7 @@ public abstract class ContourNextLinkMessage {
private static final String TAG = ContourNextLinkMessage.class.getSimpleName();
private static final int USB_BLOCKSIZE = 64;
private static final int READ_TIMEOUT_MS = 10000;
private static final int READ_TIMEOUT_MS = 15000; //ASTM standard is 15 seconds (note was previously set at 10 seconds)
private static final String BAYER_USB_HEADER = "ABC";
protected ByteBuffer mPayload;
......@@ -142,6 +142,56 @@ public abstract class ContourNextLinkMessage {
return responseMessage.toByteArray();
}
// safety check to make sure a expected 0x81 response is received before next expected 0x80 response
// very infrequent as clearMessage catches most issues but very important to save a CNL error situation
protected int readMessage_0x81(UsbHidDriver mDevice) throws IOException, TimeoutException {
int responseSize = 0;
boolean doRetry;
do {
byte[] responseBytes = readMessage(mDevice);
if (responseBytes[18] != (byte) 0x81) {
doRetry = true;
Log.d(TAG, "readMessage0x81: did not get 0x81 response, got " + responseBytes[18]);
} else {
doRetry = false;
responseSize = responseBytes.length;
}
} while (doRetry);
return responseSize;
}
// intercept unexpected messages from the CNL
// these usually come from pump requests as it can occasionally resend message responses several times (possibly due to a missed CNL ACK during CNL-PUMP comms?)
// mostly noted on the higher radio channels, channel 26 shows this the most
// if these messages are not cleared the CNL will likely error needing to be unplugged to reset as it expects them to be read before any further commands are sent
protected int clearMessage(UsbHidDriver mDevice) throws IOException {
byte[] responseBuffer = new byte[USB_BLOCKSIZE];
int bytesRead;
int bytesClear = 0;
do {
bytesRead = mDevice.read(responseBuffer, 2000);
if (bytesRead > 0) {
bytesClear += bytesRead;
String responseString = HexDump.dumpHexString(responseBuffer);
Log.d(TAG, "READ: " + responseString);
}
} while (bytesRead > 0);
if (bytesClear > 0) {
Log.d(TAG, "clearMessage: message stream cleared bytes: " + bytesClear);
}
return bytesClear;
}
public enum ASCII {
STX(0x02),
EOT(0x04),
......
......@@ -20,6 +20,10 @@ public class EHSMMessage extends MedtronicSendMessageRequestMessage<ContourNext
@Override
public ContourNextLinkResponseMessage send(UsbHidDriver mDevice, int millis) throws IOException, TimeoutException, UnexpectedMessageException {
// clear unexpected incoming messages
clearMessage(mDevice);
sendMessage(mDevice);
if (millis > 0) {
try {
......@@ -27,11 +31,17 @@ public class EHSMMessage extends MedtronicSendMessageRequestMessage<ContourNext
} catch (InterruptedException e) {
}
}
// The End EHSM Session only has an 0x81 response
if (readMessage_0x81(mDevice) != 48) {
throw new UnexpectedMessageException("length of EHSMMessage response does not match");
}
/*
readMessage(mDevice);
if (this.encode().length != 54) {
throw new UnexpectedMessageException("length of EHSMMessage response does not match");
}
*/
return null;
}
}
......@@ -22,6 +22,10 @@ public class PumpStatusRequestMessage extends MedtronicSendMessageRequestMessage
}
public PumpStatusResponseMessage send(UsbHidDriver mDevice, int millis) throws IOException, TimeoutException, ChecksumException, EncryptionException, UnexpectedMessageException {
// clear unexpected incoming messages
clearMessage(mDevice);
sendMessage(mDevice);
if (millis > 0) {
try {
......@@ -31,7 +35,7 @@ public class PumpStatusRequestMessage extends MedtronicSendMessageRequestMessage
}
}
// Read the 0x81
readMessage(mDevice);
readMessage_0x81(mDevice);
if (millis > 0) {
try {
Log.d(TAG, "waiting " + millis +" ms");
......
......@@ -19,6 +19,10 @@ public class PumpTimeRequestMessage extends MedtronicSendMessageRequestMessage<P
@Override
public PumpTimeResponseMessage send(UsbHidDriver mDevice, int millis) throws IOException, TimeoutException, ChecksumException, EncryptionException, UnexpectedMessageException {
// clear unexpected incoming messages
clearMessage(mDevice);
sendMessage(mDevice);
if (millis > 0) {
try {
......@@ -27,7 +31,7 @@ public class PumpTimeRequestMessage extends MedtronicSendMessageRequestMessage<P
}
}
// Read the 0x81
readMessage(mDevice);
readMessage_0x81(mDevice);
if (millis > 0) {
try {
Thread.sleep(millis);
......@@ -44,4 +48,4 @@ public class PumpTimeRequestMessage extends MedtronicSendMessageRequestMessage<P
protected PumpTimeResponseMessage getResponse(byte[] payload) throws ChecksumException, EncryptionException, IOException, UnexpectedMessageException {
return new PumpTimeResponseMessage(mPumpSession, payload);
}
}
}
\ No newline at end of file
......@@ -10,6 +10,7 @@ import info.nightscout.android.BuildConfig;
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;
/**
......@@ -20,14 +21,15 @@ public class PumpTimeResponseMessage extends MedtronicSendMessageResponseMessage
private Date pumpTime;
protected PumpTimeResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException {
protected PumpTimeResponseMessage(MedtronicCnlSession pumpSession, byte[] payload) throws EncryptionException, ChecksumException, UnexpectedMessageException {
super(pumpSession, payload);
if (this.encode().length < (61 + 8)) {
// Invalid message. Return an invalid date.
// TODO - deal with this more elegantly
Log.e(TAG, "Invalid message received for getPumpTime");
pumpTime = new Date();
throw new UnexpectedMessageException("Invalid message received for getPumpTime");
// pumpTime = new Date();
} else {
ByteBuffer dateBuffer = ByteBuffer.allocate(8);
dateBuffer.order(ByteOrder.BIG_ENDIAN);
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment