// safety check to make sure an 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 async Task <byte[]> ReadMessage_0x81(UsbHidDriver mDevice, int timeout = READ_TIMEOUT_MS) { byte[] responseBytes; bool doRetry; var expected = (byte)0x81; do { responseBytes = await ReadMessage(mDevice, timeout); var actual = responseBytes[18]; if (actual != expected) { doRetry = true; Log.d(TAG, "readMessage0x81: did not get 0x81 response, got " + HexDump.ToHexstring(actual)); MedtronicCnlService.cnl0x81++; } else { doRetry = false; break; } } while (doRetry); return(responseBytes); }
protected async Task <byte[]> ReadFromPump(UsbHidDriver mDevice, MedtronicCnlSession pumpSession, string tag) { tag = " (" + tag + ")"; MultipacketSession multipacketSession = null; byte[] tupple; byte[] payload = null; byte[] decrypted = null; bool fetchMoreData = true; int retry = 0; int expectedSegments = 0; int cmd; while (fetchMoreData) { if (multipacketSession != null) { do { if (expectedSegments < 1) { tupple = multipacketSession.MissingSegments(); new MultipacketResendPacketsMessage(pumpSession, tupple).send(mDevice); expectedSegments = read16BEtoUInt(tupple, 0x02); } try { payload = await ReadMessage(mDevice, MULTIPACKET_TIMEOUT_MS); break; } catch (TimeoutException e) { if (++retry >= SEGMENT_RETRY) { throw new TimeoutException("Timeout waiting for response from pump (multipacket)" + tag); } Log.d(TAG, "*** Multisession timeout, expecting:" + expectedSegments + " retry: " + retry); expectedSegments = 0; } } while (retry > 0); } else { try { payload = await ReadMessage(mDevice, READ_TIMEOUT_MS); } catch (TimeoutException e) { throw new TimeoutException("Timeout waiting for response from pump" + tag); } } if (payload.Length < 0x0039) { Log.d(TAG, "*** bad response" + HexDump.DumpHexstring(payload, 0x12, payload.Length - 0x14)); fetchMoreData = true; } else { decrypted = Decode(pumpSession, payload); cmd = read16BEtoUInt(decrypted, RESPONSE_COMMAND); Log.d(TAG, "CMD: " + HexDump.ToHexstring(cmd)); if (MedtronicSendMessageRequestMessage.MessageType.EHSM_SESSION.response(cmd)) { // EHSM_SESSION(0) Log.d(TAG, "*** EHSM response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = true; } else if (MedtronicSendMessageRequestMessage.MessageType.NAK_COMMAND.response(cmd)) { Log.d(TAG, "*** NAK response" + HexDump.DumpHexstring(decrypted)); ClearMessage(mDevice, ERROR_CLEAR_TIMEOUT_MS); // if multipacket was in progress we may need to clear 2 EHSM_SESSION(1) messages from pump short nakcmd = read16BEtoShort(decrypted, 3); byte nakcode = decrypted[5]; throw new UnexpectedMessageException("Pump sent a NAK(" + string.Format("%02X", nakcmd) + ":" + string.Format("%02X", nakcode) + ") response" + tag); } else if (MedtronicSendMessageRequestMessage.MessageType.INITIATE_MULTIPACKET_TRANSFER.response(cmd)) { multipacketSession = new MultipacketSession(decrypted); new AckMessage(pumpSession, MedtronicSendMessageRequestMessage.MessageType.INITIATE_MULTIPACKET_TRANSFER.response()).send(mDevice); expectedSegments = multipacketSession.PacketsToFetch; fetchMoreData = true; } else if (MedtronicSendMessageRequestMessage.MessageType.MULTIPACKET_SEGMENT_TRANSMISSION.response(cmd)) { if (multipacketSession == null) { throw new UnexpectedMessageException("multipacketSession not initiated before segment received" + tag); } multipacketSession.AddSegment(decrypted); expectedSegments--; if (multipacketSession.PayloadComplete) { Log.d(TAG, "*** Multisession Complete"); new AckMessage(pumpSession, MedtronicSendMessageRequestMessage.MessageType.MULTIPACKET_SEGMENT_TRANSMISSION.response()).send(mDevice); // read 0412 = EHSM_SESSION(1) payload = await ReadMessage(mDevice, READ_TIMEOUT_MS); decrypted = Decode(pumpSession, payload); Log.d(TAG, "*** response" + HexDump.DumpHexstring(decrypted)); return(multipacketSession.Response); } else { fetchMoreData = true; } } else if (MedtronicSendMessageRequestMessage.MessageType.END_HISTORY_TRANSMISSION.response(cmd)) { Log.d(TAG, "*** END_HISTORY_TRANSMISSION response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else if (MedtronicSendMessageRequestMessage.MessageType.READ_PUMP_TIME.response(cmd)) { Log.d(TAG, "*** READ_PUMP_TIME response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else if (MedtronicSendMessageRequestMessage.MessageType.READ_PUMP_STATUS.response(cmd)) { Log.d(TAG, "*** READ_PUMP_STATUS response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else if (MedtronicSendMessageRequestMessage.MessageType.READ_HISTORY_INFO.response(cmd)) { Log.d(TAG, "*** READ_HISTORY_INFO response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else if (MedtronicSendMessageRequestMessage.MessageType.READ_BASAL_PATTERN.response(cmd)) { Log.d(TAG, "*** READ_BASAL_PATTERN response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else if (MedtronicSendMessageRequestMessage.MessageType.READ_BOLUS_WIZARD_CARB_RATIOS.response(cmd)) { Log.d(TAG, "*** READ_BOLUS_WIZARD_CARB_RATIOS response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else if (MedtronicSendMessageRequestMessage.MessageType.READ_BOLUS_WIZARD_SENSITIVITY_FACTORS.response(cmd)) { Log.d(TAG, "*** READ_BOLUS_WIZARD_SENSITIVITY_FACTORS response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else if (MedtronicSendMessageRequestMessage.MessageType.READ_BOLUS_WIZARD_BG_TARGETS.response(cmd)) { Log.d(TAG, "*** READ_BOLUS_WIZARD_BG_TARGETS response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = false; } else { Log.d(TAG, "*** ??? response" + HexDump.DumpHexstring(decrypted)); fetchMoreData = true; } } } // when returning non-multipacket decrypted data, we need to trim the 2 byte checksum if (decrypted == null) { return(payload); } return(decrypted.Partial(0, decrypted.Length - 2)); }