simplify read error handling

This commit is contained in:
Andrei Vereha 2021-04-02 14:03:22 +02:00
parent e8bc50f458
commit 0f58185109
18 changed files with 80 additions and 100 deletions

View file

@ -542,7 +542,6 @@ class OmnipodDashPumpPlugin @Inject constructor(
"Time, Date and/or TimeZone changed. [timeChangeType=" + timeChangeType.name + ", eventHandlingEnabled=" + eventHandlingEnabled + "]" "Time, Date and/or TimeZone changed. [timeChangeType=" + timeChangeType.name + ", eventHandlingEnabled=" + eventHandlingEnabled + "]"
) )
if (timeChangeType == TimeChangeType.TimeChanged) { if (timeChangeType == TimeChangeType.TimeChanged) {
aapsLogger.info(LTag.PUMP, "Ignoring time change because it is not a DST or TZ change") aapsLogger.info(LTag.PUMP, "Ignoring time change because it is not a DST or TZ change")
return return

View file

@ -248,7 +248,8 @@ class OmnipodDashManagerImpl @Inject constructor(
Observable.defer { Observable.defer {
Observable.timer(podStateManager.firstPrimeBolusVolume!!.toLong(), TimeUnit.SECONDS) Observable.timer(podStateManager.firstPrimeBolusVolume!!.toLong(), TimeUnit.SECONDS)
.flatMap { Observable.empty() } .flatMap { Observable.empty() }
}) }
)
observables.add( observables.add(
Observable.defer { Observable.defer {
bleManager.sendCommand( bleManager.sendCommand(
@ -349,7 +350,8 @@ class OmnipodDashManagerImpl @Inject constructor(
Observable.defer { Observable.defer {
Observable.timer(podStateManager.secondPrimeBolusVolume!!.toLong(), TimeUnit.SECONDS) Observable.timer(podStateManager.secondPrimeBolusVolume!!.toLong(), TimeUnit.SECONDS)
.flatMap { Observable.empty() } .flatMap { Observable.empty() }
}) }
)
observables.add( observables.add(
observeSendProgramBolusCommand( observeSendProgramBolusCommand(
podStateManager.secondPrimeBolusVolume!! * 0.05, podStateManager.secondPrimeBolusVolume!! * 0.05,

View file

@ -1,3 +1,3 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
class CouldNotParseResponseException(message: String?) : Exception(message) class CouldNotParseResponseException(message: String?) : Exception(message)

View file

@ -6,4 +6,4 @@ import kotlin.reflect.KClass
class IllegalResponseException( class IllegalResponseException(
expectedResponseType: KClass<out Response>, expectedResponseType: KClass<out Response>,
actualResponse: Response actualResponse: Response
) : Exception("Illegal response: expected ${expectedResponseType.simpleName} but got $actualResponse") ) : Exception("Illegal response: expected ${expectedResponseType.simpleName} but got $actualResponse")

View file

@ -2,4 +2,4 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.excepti
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.NakResponse import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.NakResponse
class NakResponseException(val response: NakResponse) : Exception("Received NAK response: ${response.nakErrorType.value} ${response.nakErrorType.name}") class NakResponseException(val response: NakResponse) : Exception("Received NAK response: ${response.nakErrorType.value} ${response.nakErrorType.name}")

View file

@ -10,4 +10,4 @@ class PodAlarmException(val response: AlarmStatusResponse) : Exception(
response.alarmType.value.toInt() and 0xff, response.alarmType.value.toInt() and 0xff,
response.alarmType.name response.alarmType.name
) )
) )

View file

@ -15,10 +15,6 @@ import info.nightscout.androidaps.utils.extensions.toHex
import java.util.concurrent.BlockingQueue import java.util.concurrent.BlockingQueue
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
sealed class BleReceiveResult
data class BleReceivePayload(val payload: ByteArray) : BleReceiveResult()
data class BleReceiveError(val msg: String, val cause: Throwable? = null) : BleReceiveResult()
sealed class BleSendResult sealed class BleSendResult
object BleSendSuccess : BleSendResult() object BleSendSuccess : BleSendResult()
@ -39,13 +35,16 @@ open class BleIO(
* @param characteristic where to read from(CMD or DATA) * @param characteristic where to read from(CMD or DATA)
* @return a byte array with the received data or error * @return a byte array with the received data or error
*/ */
fun receivePacket(timeoutMs: Long = DEFAULT_IO_TIMEOUT_MS): BleReceiveResult { fun receivePacket(timeoutMs: Long = DEFAULT_IO_TIMEOUT_MS): ByteArray? {
return try { return try {
val packet = incomingPackets.poll(timeoutMs, TimeUnit.MILLISECONDS) val packet = incomingPackets.poll(timeoutMs, TimeUnit.MILLISECONDS)
if (packet == null) BleReceiveError("Timeout") if (packet == null) {
else BleReceivePayload(packet) aapsLogger.debug(LTag.PUMPBTCOMM, "Timeout reading $type packet")
}
packet
} catch (e: InterruptedException) { } catch (e: InterruptedException) {
BleReceiveError("Interrupted", cause = e) aapsLogger.debug(LTag.PUMPBTCOMM, "Interrupted while reading packet: $e")
null
} }
} }

View file

@ -13,7 +13,7 @@ sealed class BleConfirmResult
object BleConfirmSuccess : BleConfirmResult() object BleConfirmSuccess : BleConfirmResult()
data class BleConfirmIncorrectData(val payload: ByteArray) : BleConfirmResult() data class BleConfirmIncorrectData(val payload: ByteArray) : BleConfirmResult()
data class BleConfirmError(val msg: String, val cause: Throwable? = null) : BleConfirmResult() data class BleConfirmError(val msg: String) : BleConfirmResult()
class CmdBleIO( class CmdBleIO(
logger: AAPSLogger, logger: AAPSLogger,
@ -37,14 +37,12 @@ class CmdBleIO(
fun hello() = sendAndConfirmPacket(BleCommandHello(OmnipodDashBleManagerImpl.CONTROLLER_ID).data) fun hello() = sendAndConfirmPacket(BleCommandHello(OmnipodDashBleManagerImpl.CONTROLLER_ID).data)
fun expectCommandType(expected: BleCommand, timeoutMs: Long = DEFAULT_IO_TIMEOUT_MS): BleConfirmResult { fun expectCommandType(expected: BleCommand, timeoutMs: Long = DEFAULT_IO_TIMEOUT_MS): BleConfirmResult {
return when (val actual = receivePacket(timeoutMs)) { return receivePacket(timeoutMs)?.let {
is BleReceiveError -> BleConfirmError(actual.toString()) if (it.isNotEmpty() && it[0] == expected.data[0])
is BleReceivePayload -> BleConfirmSuccess
if (actual.payload.isEmpty() || actual.payload[0] != expected.data[0]) { else
BleConfirmIncorrectData(actual.payload) BleConfirmIncorrectData(it)
} else {
BleConfirmSuccess
}
} }
?: BleConfirmError("Error reading packet")
} }
} }

View file

@ -9,12 +9,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.P
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.PayloadSplitter
import info.nightscout.androidaps.utils.extensions.toHex import info.nightscout.androidaps.utils.extensions.toHex
sealed class MesssageReceiveResult
data class MessageReceiveSuccess(val msg: MessagePacket) : MesssageReceiveResult()
data class MessageReceiveError(val msg: String, val cause: Throwable? = null) : MesssageReceiveResult() {
constructor(e: PacketReceiveResult) : this("Could not read DATA packet: $e")
}
sealed class MessageSendResult sealed class MessageSendResult
object MessageSendSuccess : MessageSendResult() object MessageSendSuccess : MessageSendResult()
data class MessageSendErrorSending(val msg: String, val cause: Throwable? = null) : MessageSendResult() { data class MessageSendErrorSending(val msg: String, val cause: Throwable? = null) : MessageSendResult() {
@ -43,14 +37,13 @@ class MessageIO(
cmdBleIO.flushIncomingQueue() cmdBleIO.flushIncomingQueue()
dataBleIO.flushIncomingQueue() dataBleIO.flushIncomingQueue()
val sendResult = cmdBleIO.sendAndConfirmPacket(BleCommandRTS.data) val rtsSendResult = cmdBleIO.sendAndConfirmPacket(BleCommandRTS.data)
if (sendResult is BleSendErrorSending) { if (rtsSendResult is BleSendErrorSending) {
return MessageSendErrorSending(sendResult) return MessageSendErrorSending(rtsSendResult)
} }
val expectCTS = cmdBleIO.expectCommandType(BleCommandCTS) val expectCTS = cmdBleIO.expectCommandType(BleCommandCTS)
if (expectCTS !is BleConfirmSuccess) { if (expectCTS !is BleConfirmSuccess) {
return MessageSendErrorSending(sendResult) return MessageSendErrorSending(expectCTS.toString())
} }
val payload = msg.asByteArray() val payload = msg.asByteArray()
@ -90,19 +83,21 @@ class MessageIO(
} }
} }
fun receiveMessage(): MesssageReceiveResult { fun receiveMessage(): MessagePacket? {
cmdBleIO.expectCommandType(BleCommandRTS, MESSAGE_READ_TIMEOUT_MS) cmdBleIO.expectCommandType(BleCommandRTS, MESSAGE_READ_TIMEOUT_MS)
val sendResult = cmdBleIO.sendAndConfirmPacket(BleCommandCTS.data) val sendResult = cmdBleIO.sendAndConfirmPacket(BleCommandCTS.data)
if (sendResult !is BleSendSuccess) { if (sendResult !is BleSendSuccess) {
return MessageReceiveError("Error sending CTS: $sendResult") aapsLogger.warn(LTag.PUMPBTCOMM, "Error sending CTS: $sendResult")
return null
} }
readReset() readReset()
var expected: Byte = 0 var expected: Byte = 0
try { try {
val firstPacket = expectBlePacket(0) val firstPacket = expectBlePacket(0)
if (firstPacket !is PacketReceiveSuccess) { if (firstPacket !is PacketReceiveSuccess) {
return MessageReceiveError(firstPacket) aapsLogger.warn(LTag.PUMPBTCOMM, "Error reading first packet:$firstPacket")
return null
} }
val joiner = PayloadJoiner(firstPacket.payload) val joiner = PayloadJoiner(firstPacket.payload)
maxMessageReadTries = joiner.fullFragments * 2 + 2 maxMessageReadTries = joiner.fullFragments * 2 + 2
@ -110,7 +105,8 @@ class MessageIO(
expected++ expected++
val packet = expectBlePacket(expected) val packet = expectBlePacket(expected)
if (packet !is PacketReceiveSuccess) { if (packet !is PacketReceiveSuccess) {
return MessageReceiveError(packet) aapsLogger.warn(LTag.PUMPBTCOMM, "Error reading packet:$packet")
return null
} }
joiner.accumulate(packet.payload) joiner.accumulate(packet.payload)
} }
@ -118,21 +114,22 @@ class MessageIO(
expected++ expected++
val packet = expectBlePacket(expected) val packet = expectBlePacket(expected)
if (packet !is PacketReceiveSuccess) { if (packet !is PacketReceiveSuccess) {
return MessageReceiveError(packet) aapsLogger.warn(LTag.PUMPBTCOMM, "Error reading packet:$packet")
return null
} }
joiner.accumulate(packet.payload) joiner.accumulate(packet.payload)
} }
val fullPayload = joiner.finalize() val fullPayload = joiner.finalize()
cmdBleIO.sendAndConfirmPacket(BleCommandSuccess.data) cmdBleIO.sendAndConfirmPacket(BleCommandSuccess.data)
return MessageReceiveSuccess(MessagePacket.parse(fullPayload)) return MessagePacket.parse(fullPayload)
} catch (e: IncorrectPacketException) { } catch (e: IncorrectPacketException) {
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not read message: $e") aapsLogger.warn(LTag.PUMPBTCOMM, "Received incorrect packet: $e")
cmdBleIO.sendAndConfirmPacket(BleCommandAbort.data) cmdBleIO.sendAndConfirmPacket(BleCommandAbort.data)
return MessageReceiveError("Received incorrect packet: $e", cause = e) return null
} catch (e: CrcMismatchException) { } catch (e: CrcMismatchException) {
aapsLogger.warn(LTag.PUMPBTCOMM, "CRC mismatch: $e") aapsLogger.warn(LTag.PUMPBTCOMM, "CRC mismatch: $e")
cmdBleIO.sendAndConfirmPacket(BleCommandFail.data) cmdBleIO.sendAndConfirmPacket(BleCommandFail.data)
return MessageReceiveError("CRC mismatch: $e", cause = e) return null
} finally { } finally {
readReset() readReset()
} }
@ -157,7 +154,7 @@ class MessageIO(
is BleCommandNack -> { is BleCommandNack -> {
// // Consume NACK // // Consume NACK
val received = cmdBleIO.receivePacket() val received = cmdBleIO.receivePacket()
if (received !is BleReceivePayload) { if (received == null) {
MessageSendErrorSending(received.toString()) MessageSendErrorSending(received.toString())
} else { } else {
val sendResult = dataBleIO.sendAndConfirmPacket(packets[receivedCmd.idx.toInt()].toByteArray()) val sendResult = dataBleIO.sendAndConfirmPacket(packets[receivedCmd.idx.toInt()].toByteArray())
@ -185,29 +182,19 @@ class MessageIO(
while (messageReadTries < maxMessageReadTries && packetTries < MAX_PACKET_READ_TRIES) { while (messageReadTries < maxMessageReadTries && packetTries < MAX_PACKET_READ_TRIES) {
messageReadTries++ messageReadTries++
packetTries++ packetTries++
val received = dataBleIO.receivePacket()
when (val received = dataBleIO.receivePacket()) { if (received == null || received.isEmpty()) {
is BleReceiveError -> { if (nackOnTimeout)
if (nackOnTimeout)
cmdBleIO.sendAndConfirmPacket(BleCommandNack(index).data)
aapsLogger.info(LTag.PUMPBTCOMM, "Error receiving DATA packet: $received")
}
is BleReceivePayload -> {
val payload = received.payload
if (payload.isEmpty()) {
aapsLogger.info(LTag.PUMPBTCOMM, "Received empty payload at index $index")
continue
}
if (payload[0] == index) {
return PacketReceiveSuccess(payload)
}
receivedOutOfOrder[payload[0]] = payload
cmdBleIO.sendAndConfirmPacket(BleCommandNack(index).data) cmdBleIO.sendAndConfirmPacket(BleCommandNack(index).data)
} aapsLogger.info(LTag.PUMPBTCOMM, "Error reading index: $index. Received: $received")
continue
} }
if (received[0] == index) {
return PacketReceiveSuccess(received)
}
receivedOutOfOrder[received[0]] = received
cmdBleIO.sendAndConfirmPacket(BleCommandNack(index).data)
} }
return PacketReceiveError("Reached the maximum number tries to read a packet") return PacketReceiveError("Reached the maximum number tries to read a packet")
} }

View file

@ -5,7 +5,11 @@ import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Id
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.MessageIOException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.MessageIOException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PairingException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PairingException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageSendErrorSending
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageSendSuccess
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.RandomByteGenerator
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.X25519KeyGenerator
@ -37,11 +41,8 @@ internal class LTKExchanger(
throw PairingException("Could not send SP1: $sp1Result") throw PairingException("Could not send SP1: $sp1Result")
} }
val podSps1 = msgIO.receiveMessage() val podSps1 = msgIO.receiveMessage() ?: throw PairingException("Could not read SPS1")
if (podSps1 !is MessageReceiveSuccess) { processSps1FromPod(podSps1)
throw PairingException("Could not read SPS1: $podSps1")
}
processSps1FromPod(podSps1.msg)
// now we have all the data to generate: confPod, confPdm, ltk and noncePrefix // now we have all the data to generate: confPod, confPdm, ltk and noncePrefix
seq++ seq++
@ -51,11 +52,8 @@ internal class LTKExchanger(
throw PairingException("Could not send sps2: $sp2Result") throw PairingException("Could not send sps2: $sp2Result")
} }
val podSps2 = msgIO.receiveMessage() val podSps2 = msgIO.receiveMessage() ?: throw PairingException("Could not read SPS2")
if (podSps2 !is MessageReceiveSuccess) { validatePodSps2(podSps2)
throw PairingException("Could not read SPS2: $podSps2")
}
validatePodSps2(podSps2.msg)
seq++ seq++
// send SP0GP0 // send SP0GP0
@ -65,12 +63,10 @@ internal class LTKExchanger(
} }
// No exception throwing after this point. It is possible that the pod saved the LTK // No exception throwing after this point. It is possible that the pod saved the LTK
val p0 = msgIO.receiveMessage() msgIO.receiveMessage()
if (p0 is MessageReceiveSuccess) { ?.let { validateP0(it) }
validateP0(p0.msg) ?: aapsLogger.warn(LTag.PUMPBTCOMM, "Could not read P0")
} else {
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not read P0: $p0")
}
return PairResult( return PairResult(
ltk = keyExchange.ltk, ltk = keyExchange.ltk,
msgSeq = seq msgSeq = seq

View file

@ -41,4 +41,4 @@ object ResponseUtil {
ResponseType.StatusResponseType.UNKNOWN -> throw CouldNotParseResponseException("Unrecognized additional status response type: ${payload[2]}") ResponseType.StatusResponseType.UNKNOWN -> throw CouldNotParseResponseException("Unrecognized additional status response type: ${payload[2]}")
} }
} }
} }

View file

@ -9,6 +9,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptio
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.NakResponseException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.NakResponseException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PodAlarmException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PodAlarmException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.* import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding.Companion.parseKeys
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse
@ -73,11 +74,11 @@ class Session(
var responseMsgPacket: MessagePacket? = null var responseMsgPacket: MessagePacket? = null
for (i in 0..MAX_TRIES) { for (i in 0..MAX_TRIES) {
val responseMsg = msgIO.receiveMessage() val responseMsg = msgIO.receiveMessage()
if (responseMsg !is MessageReceiveSuccess) { if (responseMsg == null) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Error receiving response: $responseMsg") aapsLogger.debug(LTag.PUMPBTCOMM, "Error receiving response: $responseMsg")
continue continue
} }
responseMsgPacket = responseMsg.msg responseMsgPacket = responseMsg
} }
responseMsgPacket responseMsgPacket

View file

@ -7,7 +7,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecryp
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.SessionEstablishmentException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.SessionEstablishmentException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageReceiveSuccess
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageSendSuccess import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageSendSuccess
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType
import info.nightscout.androidaps.utils.extensions.toHex import info.nightscout.androidaps.utils.extensions.toHex
@ -46,11 +45,9 @@ class SessionEstablisher(
throw SessionEstablishmentException("Could not send the EAP AKA challenge: $sendResult") throw SessionEstablishmentException("Could not send the EAP AKA challenge: $sendResult")
} }
val challengeResponse = msgIO.receiveMessage() val challengeResponse = msgIO.receiveMessage()
if (challengeResponse !is MessageReceiveSuccess) { ?: throw SessionEstablishmentException("Could not establish session")
throw SessionEstablishmentException("Could not establish session: $challengeResponse")
}
processChallengeResponse(challengeResponse.msg) processChallengeResponse(challengeResponse)
msgSeq++ msgSeq++
var success = eapSuccess() var success = eapSuccess()
@ -101,7 +98,7 @@ class SessionEstablisher(
if (eapMsg.attributes.size == 1 && eapMsg.attributes[0] is EapAkaAttributeClientErrorCode) { if (eapMsg.attributes.size == 1 && eapMsg.attributes[0] is EapAkaAttributeClientErrorCode) {
throw SessionEstablishmentException( throw SessionEstablishmentException(
"Received CLIENT_ERROR_CODE for EAP-AKA challenge: ${ "Received CLIENT_ERROR_CODE for EAP-AKA challenge: ${
eapMsg.attributes[0].toByteArray().toHex() eapMsg.attributes[0].toByteArray().toHex()
}" }"
) )
} }

View file

@ -64,6 +64,5 @@ sealed class PodEvent {
override fun toString(): String { override fun toString(): String {
return "ResponseReceived(command=$command, response=$response)" return "ResponseReceived(command=$command, response=$response)"
} }
} }
} }

View file

@ -13,7 +13,7 @@ class ProgramInsulinCommand internal constructor(
multiCommandFlag: Boolean, multiCommandFlag: Boolean,
nonce: Int, nonce: Int,
insulinProgramElements: insulinProgramElements:
List<ShortInsulinProgramElement>, List<ShortInsulinProgramElement>,
private val checksum: Short, private val checksum: Short,
private val byte9: Byte, private val byte9: Byte,
private val byte10And11: Short, private val byte10And11: Short,

View file

@ -468,8 +468,8 @@ class OmnipodDashOverviewFragment : DaggerFragment() {
private fun updateRefreshStatusButton() { private fun updateRefreshStatusButton() {
buttonBinding.buttonRefreshStatus.isEnabled = buttonBinding.buttonRefreshStatus.isEnabled =
podStateManager.isUniqueIdSet && podStateManager.isUniqueIdSet &&
podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED) && podStateManager.activationProgress.isAtLeast(ActivationProgress.PHASE_1_COMPLETED) &&
isQueueEmpty() isQueueEmpty()
} }
private fun updateResumeDeliveryButton() { private fun updateResumeDeliveryButton() {

View file

@ -21,11 +21,14 @@ class DashDeactivatePodViewModel @Inject constructor(
) : DeactivatePodViewModel(injector, logger) { ) : DeactivatePodViewModel(injector, logger) {
override fun doExecuteAction(): Single<PumpEnactResult> = Single.create { source -> override fun doExecuteAction(): Single<PumpEnactResult> = Single.create { source ->
commandQueueProvider.customCommand(CommandDeactivatePod(), object : Callback() { commandQueueProvider.customCommand(
override fun run() { CommandDeactivatePod(),
source.onSuccess(result) object : Callback() {
override fun run() {
source.onSuccess(result)
}
} }
}) )
} }
override fun discardPod() { override fun discardPod() {

View file

@ -55,5 +55,4 @@ class ProgramBasalCommandTest {
encoded encoded
) )
} }
} }