Pad NonceResyncableMessageBlock with GetStatusCommands to ensure > 1 packet in order to improve command verification
This commit is contained in:
parent
78d789db4e
commit
1dd296ef0e
3 changed files with 39 additions and 22 deletions
|
@ -148,7 +148,20 @@ public class OmnipodCommunicationService extends RileyLinkCommunicationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean firstPacket = true;
|
boolean firstPacket = true;
|
||||||
byte[] encodedMessage = message.getEncoded();
|
byte[] encodedMessage;
|
||||||
|
if (message.isNonceResyncable()) {
|
||||||
|
OmnipodMessage paddedMessage = new OmnipodMessage(message);
|
||||||
|
// If messages are nonce resyncable, we want do distinguish between certain and uncertain failures for verification purposes
|
||||||
|
// However, some commands (e.g. cancel delivery) are single packet command by nature. When we get a timeout with a single packet,
|
||||||
|
// we are unsure whether or not the command was received by the pod
|
||||||
|
// However, if we send > 1 packet, we know that the command wasn't received if we never send the subsequent packets,
|
||||||
|
// because the last packet contains the CRC.
|
||||||
|
// So we pad the message with get status commands to make it > packet
|
||||||
|
paddedMessage.padWithGetStatusCommands(PacketType.PDM.getMaxBodyLength()); // First packet is of type PDM
|
||||||
|
encodedMessage = paddedMessage.getEncoded();
|
||||||
|
} else {
|
||||||
|
encodedMessage = message.getEncoded();
|
||||||
|
}
|
||||||
|
|
||||||
OmnipodPacket response = null;
|
OmnipodPacket response = null;
|
||||||
while (encodedMessage.length > 0) {
|
while (encodedMessage.length > 0) {
|
||||||
|
|
|
@ -221,18 +221,6 @@ public class OmnipodManager {
|
||||||
|
|
||||||
logStartingCommandExecution("cancelDelivery [deliveryTypes=" + deliveryTypes + ", acknowledgementBeep=" + acknowledgementBeep + "]");
|
logStartingCommandExecution("cancelDelivery [deliveryTypes=" + deliveryTypes + ", acknowledgementBeep=" + acknowledgementBeep + "]");
|
||||||
|
|
||||||
try {
|
|
||||||
// As the cancel delivery command is a single packet command,
|
|
||||||
// first verify that the pod is reachable by obtaining a status response
|
|
||||||
// FIXME replace this with padding the CancelDelivery command message
|
|
||||||
// with GetStatusResponse commands to ensure that the message > 1 packets
|
|
||||||
StatusResponse podStatus = getPodStatus();
|
|
||||||
} catch (OmnipodException ex) {
|
|
||||||
logCommandExecutionFinished("cancelDelivery");
|
|
||||||
ex.setCertainFailure(true);
|
|
||||||
throw ex;
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
executeAndVerify(() -> communicationService.executeAction(new CancelDeliveryAction(podState, deliveryTypes, acknowledgementBeep)));
|
executeAndVerify(() -> communicationService.executeAction(new CancelDeliveryAction(podState, deliveryTypes, acknowledgementBeep)));
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
@ -1,14 +1,12 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.comm.message;
|
package info.nightscout.androidaps.plugins.pump.omnipod.comm.message;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
|
||||||
import org.slf4j.LoggerFactory;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
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.OmnipodCommunicationService;
|
import info.nightscout.androidaps.plugins.pump.omnipod.comm.message.command.GetStatusCommand;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType;
|
import info.nightscout.androidaps.plugins.pump.omnipod.defs.MessageBlockType;
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.defs.PodInfoType;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.exception.CrcMismatchException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.exception.CrcMismatchException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.exception.MessageDecodingException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.exception.MessageDecodingException;
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.exception.NotEnoughDataException;
|
import info.nightscout.androidaps.plugins.pump.omnipod.exception.NotEnoughDataException;
|
||||||
|
@ -16,11 +14,16 @@ import info.nightscout.androidaps.plugins.pump.omnipod.util.OmniCRC;
|
||||||
|
|
||||||
public class OmnipodMessage {
|
public class OmnipodMessage {
|
||||||
|
|
||||||
private static final Logger LOG = LoggerFactory.getLogger(OmnipodCommunicationService.class);
|
|
||||||
private final int address;
|
private final int address;
|
||||||
private final List<MessageBlock> messageBlocks;
|
private final List<MessageBlock> messageBlocks;
|
||||||
private final int sequenceNumber;
|
private final int sequenceNumber;
|
||||||
|
|
||||||
|
public OmnipodMessage(OmnipodMessage other) {
|
||||||
|
address = other.address;
|
||||||
|
messageBlocks = new ArrayList<>(other.messageBlocks);
|
||||||
|
sequenceNumber = other.sequenceNumber;
|
||||||
|
}
|
||||||
|
|
||||||
public OmnipodMessage(int address, List<MessageBlock> messageBlocks, int sequenceNumber) {
|
public OmnipodMessage(int address, List<MessageBlock> messageBlocks, int sequenceNumber) {
|
||||||
this.address = address;
|
this.address = address;
|
||||||
this.messageBlocks = messageBlocks;
|
this.messageBlocks = messageBlocks;
|
||||||
|
@ -88,6 +91,12 @@ public class OmnipodMessage {
|
||||||
return encodedData;
|
return encodedData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void padWithGetStatusCommands(int packetSize) {
|
||||||
|
while (getEncoded().length < packetSize) {
|
||||||
|
messageBlocks.add(new GetStatusCommand(PodInfoType.NORMAL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<MessageBlock> getMessageBlocks() {
|
public List<MessageBlock> getMessageBlocks() {
|
||||||
return messageBlocks;
|
return messageBlocks;
|
||||||
}
|
}
|
||||||
|
@ -106,14 +115,21 @@ public class OmnipodMessage {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isNonceResyncable() {
|
public boolean isNonceResyncable() {
|
||||||
return messageBlocks.size() > 0 && (messageBlocks.get(0) instanceof NonceResyncableMessageBlock);
|
for (MessageBlock messageBlock : messageBlocks) {
|
||||||
|
if (messageBlock instanceof NonceResyncableMessageBlock) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSentNonce() {
|
public int getSentNonce() {
|
||||||
if (!isNonceResyncable()) {
|
for (MessageBlock messageBlock : messageBlocks) {
|
||||||
throw new UnsupportedOperationException("Message is not nonce resyncable");
|
if (messageBlock instanceof NonceResyncableMessageBlock) {
|
||||||
|
return ((NonceResyncableMessageBlock) messageBlock).getNonce();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return ((NonceResyncableMessageBlock) messageBlocks.get(0)).getNonce();
|
throw new UnsupportedOperationException("Message is not nonce resyncable");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void resyncNonce(int nonce) {
|
public void resyncNonce(int nonce) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue