Add some checks and logging in Omnipod packet and message exchange
This commit is contained in:
parent
37c1d30ecc
commit
9a5cd3c902
7 changed files with 88 additions and 24 deletions
|
@ -971,9 +971,7 @@ public class OmnipodPumpPlugin extends PumpPluginAbstract implements OmnipodPump
|
||||||
|
|
||||||
// Don't trigger an alert when we exceeded the thresholds, but the last communication was successful
|
// Don't trigger an alert when we exceeded the thresholds, but the last communication was successful
|
||||||
// This happens when we simply didn't need to send any commands to the pump
|
// This happens when we simply didn't need to send any commands to the pump
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -15,6 +15,15 @@ import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RLMe
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkBLEError;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.defs.RileyLinkBLEError;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.OmnipodAction;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.action.OmnipodAction;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPacketTypeException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalResponseException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalSequenceNumberException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceOutOfSyncException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceResyncException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NotEnoughDataException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodReturnedErrorResponseException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.MessageBlock;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodMessage;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodPacket;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.OmnipodPacket;
|
||||||
|
@ -28,15 +37,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType;
|
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType;
|
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodState;
|
import info.nightscout.androidaps.plugins.pump.omnipod.defs.state.PodState;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.CommunicationException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalPacketTypeException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalResponseException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceOutOfSyncException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NonceResyncException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.NotEnoughDataException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodFaultException;
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.PodReturnedErrorResponseException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Created by andy on 6/29/18.
|
* Created by andy on 6/29/18.
|
||||||
|
@ -153,6 +154,8 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
packetAddress = addressOverride;
|
packetAddress = addressOverride;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
podState.increaseMessageNumber();
|
||||||
|
|
||||||
boolean firstPacket = true;
|
boolean firstPacket = true;
|
||||||
byte[] encodedMessage;
|
byte[] encodedMessage;
|
||||||
// this does not work well with the deactivate pod command, we somehow either
|
// this does not work well with the deactivate pod command, we somehow either
|
||||||
|
@ -207,7 +210,6 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.getPacketType() == PacketType.ACK) {
|
if (response.getPacketType() == PacketType.ACK) {
|
||||||
podState.increasePacketNumber(1);
|
|
||||||
throw new IllegalPacketTypeException(null, PacketType.ACK);
|
throw new IllegalPacketTypeException(null, PacketType.ACK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -216,6 +218,9 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
while (receivedMessage == null) {
|
while (receivedMessage == null) {
|
||||||
try {
|
try {
|
||||||
receivedMessage = OmnipodMessage.decodeMessage(receivedMessageData);
|
receivedMessage = OmnipodMessage.decodeMessage(receivedMessageData);
|
||||||
|
if (receivedMessage.getSequenceNumber() != podState.getMessageNumber()) {
|
||||||
|
throw new IllegalSequenceNumberException(podState.getMessageNumber(), receivedMessage.getSequenceNumber());
|
||||||
|
}
|
||||||
} catch (NotEnoughDataException ex) {
|
} catch (NotEnoughDataException ex) {
|
||||||
// Message is (probably) not complete yet
|
// Message is (probably) not complete yet
|
||||||
OmnipodPacket ackForCon = createAckPacket(podState, packetAddress, ackAddressOverride);
|
OmnipodPacket ackForCon = createAckPacket(podState, packetAddress, ackAddressOverride);
|
||||||
|
@ -235,8 +240,6 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
podState.increaseMessageNumber(2);
|
|
||||||
|
|
||||||
ackUntilQuiet(podState, packetAddress, ackAddressOverride);
|
ackUntilQuiet(podState, packetAddress, ackAddressOverride);
|
||||||
|
|
||||||
List<MessageBlock> messageBlocks = receivedMessage.getMessageBlocks();
|
List<MessageBlock> messageBlocks = receivedMessage.getMessageBlocks();
|
||||||
|
@ -250,7 +253,13 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return messageBlocks.get(0);
|
MessageBlock messageBlock = messageBlocks.get(0);
|
||||||
|
|
||||||
|
if (messageBlock.getType() != MessageBlockType.ERROR_RESPONSE) {
|
||||||
|
podState.increaseMessageNumber();
|
||||||
|
}
|
||||||
|
|
||||||
|
return messageBlock;
|
||||||
}
|
}
|
||||||
|
|
||||||
private OmnipodPacket createAckPacket(PodState podState, Integer packetAddress, Integer messageAddress) {
|
private OmnipodPacket createAckPacket(PodState podState, Integer packetAddress, Integer messageAddress) {
|
||||||
|
@ -286,7 +295,7 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
throw new CommunicationException(CommunicationException.Type.UNEXPECTED_EXCEPTION, ex);
|
throw new CommunicationException(CommunicationException.Type.UNEXPECTED_EXCEPTION, ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
podState.increasePacketNumber(1);
|
podState.increasePacketNumber();
|
||||||
}
|
}
|
||||||
|
|
||||||
private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet) {
|
private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet) {
|
||||||
|
@ -300,6 +309,8 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet, int repeatCount, int responseTimeoutMilliseconds, int exchangeTimeoutMilliseconds, int preambleExtensionMilliseconds) {
|
private OmnipodPacket exchangePackets(PodState podState, OmnipodPacket packet, int repeatCount, int responseTimeoutMilliseconds, int exchangeTimeoutMilliseconds, int preambleExtensionMilliseconds) {
|
||||||
long timeoutTime = System.currentTimeMillis() + exchangeTimeoutMilliseconds;
|
long timeoutTime = System.currentTimeMillis() + exchangeTimeoutMilliseconds;
|
||||||
|
|
||||||
|
podState.increasePacketNumber();
|
||||||
|
|
||||||
while (System.currentTimeMillis() < timeoutTime) {
|
while (System.currentTimeMillis() < timeoutTime) {
|
||||||
OmnipodPacket response = null;
|
OmnipodPacket response = null;
|
||||||
try {
|
try {
|
||||||
|
@ -311,17 +322,34 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
throw new CommunicationException(CommunicationException.Type.UNEXPECTED_EXCEPTION, ex);
|
throw new CommunicationException(CommunicationException.Type.UNEXPECTED_EXCEPTION, ex);
|
||||||
}
|
}
|
||||||
if (response == null || !response.isValid()) {
|
if (response == null) {
|
||||||
|
if (isLoggingEnabled()) {
|
||||||
|
LOG.debug("exchangePackets response is null");
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
} else if (!response.isValid()) {
|
||||||
|
if (isLoggingEnabled()) {
|
||||||
|
LOG.debug("exchangePackets response is invalid: " + response);
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (response.getAddress() != packet.getAddress()) {
|
if (response.getAddress() != packet.getAddress()) {
|
||||||
continue;
|
if (isLoggingEnabled()) {
|
||||||
}
|
LOG.debug("Packet address " + response.getAddress() + " doesn't match " + packet.getAddress());
|
||||||
if (response.getSequenceNumber() != ((podState.getPacketNumber() + 1) & 0b11111)) {
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
podState.increasePacketNumber(2);
|
if (response.getSequenceNumber() != podState.getPacketNumber()) {
|
||||||
|
if (isLoggingEnabled()) {
|
||||||
|
LOG.debug("Packet sequence number " + response.getSequenceNumber() + " does not match " + podState.getPacketNumber());
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Once we have verification that the POD heard us, we can increment our counters
|
||||||
|
podState.increasePacketNumber();
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
throw new CommunicationException(CommunicationException.Type.TIMEOUT);
|
throw new CommunicationException(CommunicationException.Type.TIMEOUT);
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.omnipod.comm.exception;
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.exception.OmnipodException;
|
||||||
|
|
||||||
|
public class IllegalSequenceNumberException extends OmnipodException {
|
||||||
|
private final int expected;
|
||||||
|
private final int actual;
|
||||||
|
|
||||||
|
public IllegalSequenceNumberException(int expected, int actual) {
|
||||||
|
super("Invalid sequence number. Expected="+ expected +", actual="+ actual, false);
|
||||||
|
this.expected = expected;
|
||||||
|
this.actual = actual;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getExpected() {
|
||||||
|
return expected;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getActual() {
|
||||||
|
return actual;
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.comm.message;
|
package info.nightscout.androidaps.plugins.pump.omnipod.comm.message;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage;
|
import info.nightscout.androidaps.plugins.pump.common.hw.rileylink.ble.data.RLMessage;
|
||||||
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
import info.nightscout.androidaps.plugins.pump.common.utils.ByteUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType;
|
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PacketType;
|
||||||
|
@ -79,4 +81,14 @@ public class OmnipodPacket implements RLMessage {
|
||||||
return valid;
|
return valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return "OmnipodPacket{" +
|
||||||
|
"packetAddress=" + packetAddress +
|
||||||
|
", packetType=" + packetType +
|
||||||
|
", sequenceNumber=" + sequenceNumber +
|
||||||
|
", encodedMessage=" + ByteUtil.shortHexStringWithoutSpaces(encodedMessage) +
|
||||||
|
", valid=" + valid +
|
||||||
|
'}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -46,12 +46,12 @@ public abstract class PodState {
|
||||||
this.packetNumber = packetNumber;
|
this.packetNumber = packetNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increaseMessageNumber(int increment) {
|
public void increaseMessageNumber() {
|
||||||
setMessageNumber((messageNumber + increment) & 0b1111);
|
setMessageNumber((messageNumber + 1) & 0b1111);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void increasePacketNumber(int increment) {
|
public void increasePacketNumber() {
|
||||||
setPacketNumber((packetNumber + increment) & 0b11111);
|
setPacketNumber((packetNumber + 1) & 0b11111);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasFaultEvent() {
|
public boolean hasFaultEvent() {
|
||||||
|
|
|
@ -37,6 +37,7 @@ import info.nightscout.androidaps.plugins.pump.common.utils.DateTimeUtil;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationService;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodCommunicationService;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodManager;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.OmnipodManager;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.SetupActionResult;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.SetupActionResult;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.exception.IllegalSequenceNumberException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.StatusResponse;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoRecentPulseLog;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.response.podinfo.PodInfoResponse;
|
||||||
|
@ -612,6 +613,8 @@ public class AapsOmnipodManager implements OmnipodCommunicationManagerInterface
|
||||||
comment = getStringResource(R.string.omnipod_driver_error_invalid_progress_state);
|
comment = getStringResource(R.string.omnipod_driver_error_invalid_progress_state);
|
||||||
} else if (ex instanceof IllegalResponseException) {
|
} else if (ex instanceof IllegalResponseException) {
|
||||||
comment = getStringResource(R.string.omnipod_driver_error_invalid_response);
|
comment = getStringResource(R.string.omnipod_driver_error_invalid_response);
|
||||||
|
} else if (ex instanceof IllegalSequenceNumberException) {
|
||||||
|
comment = getStringResource(R.string.omnipod_driver_error_invalid_sequence_number);
|
||||||
} else if (ex instanceof MessageDecodingException) {
|
} else if (ex instanceof MessageDecodingException) {
|
||||||
comment = getStringResource(R.string.omnipod_driver_error_message_decoding_failed);
|
comment = getStringResource(R.string.omnipod_driver_error_message_decoding_failed);
|
||||||
} else if (ex instanceof NonceOutOfSyncException) {
|
} else if (ex instanceof NonceOutOfSyncException) {
|
||||||
|
|
|
@ -1756,6 +1756,7 @@
|
||||||
<string name="omnipod_driver_error_invalid_packet_type">Communication failed: received an invalid packet from the Pod.</string>
|
<string name="omnipod_driver_error_invalid_packet_type">Communication failed: received an invalid packet from the Pod.</string>
|
||||||
<string name="omnipod_driver_error_invalid_progress_state">Communication failed: the Pod is in a wrong state.</string>
|
<string name="omnipod_driver_error_invalid_progress_state">Communication failed: the Pod is in a wrong state.</string>
|
||||||
<string name="omnipod_driver_error_invalid_response">Communication failed: received an invalid response from the Pod.</string>
|
<string name="omnipod_driver_error_invalid_response">Communication failed: received an invalid response from the Pod.</string>
|
||||||
|
<string name="omnipod_driver_error_invalid_sequence_number">Communication failed: received a message with an invalid sequence number from the Pod.</string>
|
||||||
<string name="omnipod_driver_error_message_decoding_failed">Communication failed: failed to decode message from the Pod.</string>
|
<string name="omnipod_driver_error_message_decoding_failed">Communication failed: failed to decode message from the Pod.</string>
|
||||||
<string name="omnipod_driver_error_nonce_resync_failed">Communication failed: nonce resync failed.</string>
|
<string name="omnipod_driver_error_nonce_resync_failed">Communication failed: nonce resync failed.</string>
|
||||||
<string name="omnipod_driver_error_nonce_out_of_sync">Communication failed: nonce out of sync.</string>
|
<string name="omnipod_driver_error_nonce_out_of_sync">Communication failed: nonce out of sync.</string>
|
||||||
|
|
Loading…
Reference in a new issue