Omnipod Dash: provide and verify expected response type
This commit is contained in:
parent
aff38851e1
commit
10c316edd9
8 changed files with 92 additions and 51 deletions
|
@ -10,7 +10,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.definitio
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.*
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.*
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||||
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
import info.nightscout.androidaps.utils.rx.AapsSchedulers
|
||||||
import info.nightscout.androidaps.utils.rx.retryWithBackoff
|
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
import io.reactivex.functions.Action
|
import io.reactivex.functions.Action
|
||||||
import io.reactivex.functions.Consumer
|
import io.reactivex.functions.Consumer
|
||||||
|
@ -72,19 +71,29 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
.setNumberOfUnits(units)
|
.setNumberOfUnits(units)
|
||||||
.setDelayBetweenPulsesInEighthSeconds(rateInEighthPulsesPerSeconds)
|
.setDelayBetweenPulsesInEighthSeconds(rateInEighthPulsesPerSeconds)
|
||||||
.setProgramReminder(ProgramReminder(confirmationBeeps, completionBeeps, 0))
|
.setProgramReminder(ProgramReminder(confirmationBeeps, completionBeeps, 0))
|
||||||
.build()
|
.build(),
|
||||||
|
DefaultStatusResponse::class
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun observeSendGetPodStatusCommand(type: ResponseType.StatusResponseType = ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE): Observable<PodEvent> {
|
private fun observeSendGetPodStatusCommand(type: ResponseType.StatusResponseType = ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE): Observable<PodEvent> {
|
||||||
|
// TODO move somewhere else
|
||||||
|
val expectedResponseType = when (type) {
|
||||||
|
ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE -> DefaultStatusResponse::class
|
||||||
|
ResponseType.StatusResponseType.ALARM_STATUS -> AlarmStatusResponse::class
|
||||||
|
|
||||||
|
else -> return Observable.error(UnsupportedOperationException("No response type to class mapping for ${type.name}"))
|
||||||
|
}
|
||||||
|
|
||||||
return Observable.defer {
|
return Observable.defer {
|
||||||
bleManager.sendCommand(
|
bleManager.sendCommand(
|
||||||
GetStatusCommand.Builder()
|
GetStatusCommand.Builder()
|
||||||
.setUniqueId(podStateManager.uniqueId!!.toInt())
|
.setUniqueId(podStateManager.uniqueId!!.toInt())
|
||||||
.setSequenceNumber(podStateManager.messageSequenceNumber)
|
.setSequenceNumber(podStateManager.messageSequenceNumber)
|
||||||
.setStatusResponseType(type)
|
.setStatusResponseType(type)
|
||||||
.build()
|
.build(),
|
||||||
|
expectedResponseType
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -115,7 +124,8 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
.setSequenceNumber(podStateManager.messageSequenceNumber)
|
.setSequenceNumber(podStateManager.messageSequenceNumber)
|
||||||
.setNonce(1229869870) // TODO
|
.setNonce(1229869870) // TODO
|
||||||
.setAlertConfigurations(alertConfigurations)
|
.setAlertConfigurations(alertConfigurations)
|
||||||
.build()
|
.build(),
|
||||||
|
DefaultStatusResponse::class
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -130,7 +140,8 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
.setProgramReminder(ProgramReminder(atStart = false, atEnd = false, atInterval = 0))
|
.setProgramReminder(ProgramReminder(atStart = false, atEnd = false, atInterval = 0))
|
||||||
.setBasalProgram(basalProgram)
|
.setBasalProgram(basalProgram)
|
||||||
.setCurrentTime(Date())
|
.setCurrentTime(Date())
|
||||||
.build()
|
.build(),
|
||||||
|
DefaultStatusResponse::class
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +170,8 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
.setLotNumber(podStateManager.lotNumber!!.toInt()) //
|
.setLotNumber(podStateManager.lotNumber!!.toInt()) //
|
||||||
.setPodSequenceNumber(podStateManager.podSequenceNumber!!.toInt())
|
.setPodSequenceNumber(podStateManager.podSequenceNumber!!.toInt())
|
||||||
.setInitializationTime(Date())
|
.setInitializationTime(Date())
|
||||||
.build()
|
.build(),
|
||||||
|
SetUniqueIdResponse::class
|
||||||
) //
|
) //
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +181,8 @@ class OmnipodDashManagerImpl @Inject constructor(
|
||||||
GetVersionCommand.Builder() //
|
GetVersionCommand.Builder() //
|
||||||
.setSequenceNumber(podStateManager.messageSequenceNumber) //
|
.setSequenceNumber(podStateManager.messageSequenceNumber) //
|
||||||
.setUniqueId(DEFAULT_UNIQUE_ID) //
|
.setUniqueId(DEFAULT_UNIQUE_ID) //
|
||||||
.build()
|
.build(),
|
||||||
|
VersionResponse::class
|
||||||
) //
|
) //
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,11 +3,13 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
|
||||||
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.Response
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
interface OmnipodDashBleManager {
|
interface OmnipodDashBleManager {
|
||||||
|
|
||||||
fun sendCommand(cmd: Command): Observable<PodEvent>
|
fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent>
|
||||||
|
|
||||||
fun getStatus(): ConnectionStatus
|
fun getStatus(): ConnectionStatus
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.event.PodEvent
|
||||||
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.Response
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
|
||||||
import info.nightscout.androidaps.utils.extensions.toHex
|
import info.nightscout.androidaps.utils.extensions.toHex
|
||||||
import io.reactivex.Observable
|
import io.reactivex.Observable
|
||||||
|
@ -32,6 +33,7 @@ import java.util.concurrent.LinkedBlockingDeque
|
||||||
import java.util.concurrent.TimeoutException
|
import java.util.concurrent.TimeoutException
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import javax.inject.Singleton
|
import javax.inject.Singleton
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class OmnipodDashBleManagerImpl @Inject constructor(
|
class OmnipodDashBleManagerImpl @Inject constructor(
|
||||||
|
@ -90,40 +92,39 @@ class OmnipodDashBleManagerImpl @Inject constructor(
|
||||||
return bleIO
|
return bleIO
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
|
override fun sendCommand(cmd: Command, responseType: KClass<out Response>): Observable<PodEvent> =
|
||||||
override fun sendCommand(cmd: Command): Observable<PodEvent> = Observable.create { emitter ->
|
Observable.create { emitter ->
|
||||||
try {
|
try {
|
||||||
val keys = sessionKeys
|
val keys = sessionKeys
|
||||||
val mIO = msgIO
|
val mIO = msgIO
|
||||||
if (keys == null || mIO == null) {
|
if (keys == null || mIO == null) {
|
||||||
throw Exception("Not connected")
|
throw Exception("Not connected")
|
||||||
|
}
|
||||||
|
emitter.onNext(PodEvent.CommandSending(cmd))
|
||||||
|
// TODO switch to RX
|
||||||
|
emitter.onNext(PodEvent.CommandSent(cmd))
|
||||||
|
|
||||||
|
val enDecrypt = EnDecrypt(
|
||||||
|
aapsLogger,
|
||||||
|
keys.nonce,
|
||||||
|
keys.ck
|
||||||
|
)
|
||||||
|
|
||||||
|
val session = Session(
|
||||||
|
aapsLogger = aapsLogger,
|
||||||
|
msgIO = mIO,
|
||||||
|
myId = myId,
|
||||||
|
podId = podId,
|
||||||
|
sessionKeys = keys,
|
||||||
|
enDecrypt = enDecrypt
|
||||||
|
)
|
||||||
|
val response = session.sendCommand(cmd, responseType)
|
||||||
|
emitter.onNext(PodEvent.ResponseReceived(response))
|
||||||
|
emitter.onComplete()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
emitter.tryOnError(ex)
|
||||||
}
|
}
|
||||||
emitter.onNext(PodEvent.CommandSending(cmd))
|
|
||||||
// TODO switch to RX
|
|
||||||
emitter.onNext(PodEvent.CommandSent(cmd))
|
|
||||||
|
|
||||||
val enDecrypt = EnDecrypt(
|
|
||||||
aapsLogger,
|
|
||||||
keys.nonce,
|
|
||||||
keys.ck
|
|
||||||
)
|
|
||||||
|
|
||||||
val session = Session(
|
|
||||||
aapsLogger = aapsLogger,
|
|
||||||
msgIO = mIO,
|
|
||||||
myId = myId,
|
|
||||||
podId = podId,
|
|
||||||
sessionKeys = keys,
|
|
||||||
enDecrypt = enDecrypt
|
|
||||||
)
|
|
||||||
val response = session.sendCommand(cmd)
|
|
||||||
emitter.onNext(PodEvent.ResponseReceived(response))
|
|
||||||
|
|
||||||
emitter.onComplete()
|
|
||||||
} catch (ex: Exception) {
|
|
||||||
emitter.tryOnError(ex)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun getStatus(): ConnectionStatus {
|
override fun getStatus(): ConnectionStatus {
|
||||||
var s: ConnectionStatus
|
var s: ConnectionStatus
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||||
|
|
||||||
|
class CouldNotParseResponseException(message: String?) : Exception(message)
|
|
@ -1,3 +1,9 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||||
|
|
||||||
class IllegalResponseException(message: String?) : Exception(message)
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
class IllegalResponseException(
|
||||||
|
expectedResponseType: KClass<out Response>,
|
||||||
|
actualResponse: Response
|
||||||
|
) : Exception("Illegal response: expected ${expectedResponseType.simpleName} but got $actualResponse")
|
|
@ -0,0 +1,5 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||||
|
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.AlarmStatusResponse
|
||||||
|
|
||||||
|
class PodAlarmException(val response: AlarmStatusResponse) : Exception("Pod is in alarm: ${response.alarmType.value} ${response.alarmType.name}")
|
|
@ -1,32 +1,32 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session
|
||||||
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.IllegalResponseException
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotParseResponseException
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.*
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.*
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.byValue
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.byValue
|
||||||
|
|
||||||
object ResponseUtil {
|
object ResponseUtil {
|
||||||
|
|
||||||
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
|
@Throws(CouldNotParseResponseException::class, UnsupportedOperationException::class)
|
||||||
fun parseResponse(payload: ByteArray): Response {
|
fun parseResponse(payload: ByteArray): Response {
|
||||||
return when (val responseType = byValue(payload[0], ResponseType.UNKNOWN)) {
|
return when (val responseType = byValue(payload[0], ResponseType.UNKNOWN)) {
|
||||||
ResponseType.ACTIVATION_RESPONSE -> parseActivationResponse(payload)
|
ResponseType.ACTIVATION_RESPONSE -> parseActivationResponse(payload)
|
||||||
ResponseType.DEFAULT_STATUS_RESPONSE -> DefaultStatusResponse(payload)
|
ResponseType.DEFAULT_STATUS_RESPONSE -> DefaultStatusResponse(payload)
|
||||||
ResponseType.ADDITIONAL_STATUS_RESPONSE -> parseAdditionalStatusResponse(payload)
|
ResponseType.ADDITIONAL_STATUS_RESPONSE -> parseAdditionalStatusResponse(payload)
|
||||||
ResponseType.NAK_RESPONSE -> NakResponse(payload)
|
ResponseType.NAK_RESPONSE -> NakResponse(payload)
|
||||||
ResponseType.UNKNOWN -> throw IllegalResponseException("Unrecognized message type: $responseType")
|
ResponseType.UNKNOWN -> throw CouldNotParseResponseException("Unrecognized message type: $responseType")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IllegalResponseException::class)
|
@Throws(CouldNotParseResponseException::class)
|
||||||
private fun parseActivationResponse(payload: ByteArray): Response {
|
private fun parseActivationResponse(payload: ByteArray): Response {
|
||||||
return when (val activationResponseType = byValue(payload[1], ResponseType.ActivationResponseType.UNKNOWN)) {
|
return when (val activationResponseType = byValue(payload[1], ResponseType.ActivationResponseType.UNKNOWN)) {
|
||||||
ResponseType.ActivationResponseType.GET_VERSION_RESPONSE -> VersionResponse(payload)
|
ResponseType.ActivationResponseType.GET_VERSION_RESPONSE -> VersionResponse(payload)
|
||||||
ResponseType.ActivationResponseType.SET_UNIQUE_ID_RESPONSE -> SetUniqueIdResponse(payload)
|
ResponseType.ActivationResponseType.SET_UNIQUE_ID_RESPONSE -> SetUniqueIdResponse(payload)
|
||||||
ResponseType.ActivationResponseType.UNKNOWN -> throw IllegalResponseException("Unrecognized activation response type: $activationResponseType")
|
ResponseType.ActivationResponseType.UNKNOWN -> throw CouldNotParseResponseException("Unrecognized activation response type: $activationResponseType")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
|
@Throws(CouldNotParseResponseException::class, UnsupportedOperationException::class)
|
||||||
private fun parseAdditionalStatusResponse(payload: ByteArray): Response {
|
private fun parseAdditionalStatusResponse(payload: ByteArray): Response {
|
||||||
return when (val additionalStatusResponseType = byValue(payload[2], ResponseType.StatusResponseType.UNKNOWN)) {
|
return when (val additionalStatusResponseType = byValue(payload[2], ResponseType.StatusResponseType.UNKNOWN)) {
|
||||||
ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE -> DefaultStatusResponse(payload) // Unreachable; this response type is only used for requesting a default status response
|
ResponseType.StatusResponseType.DEFAULT_STATUS_RESPONSE -> DefaultStatusResponse(payload) // Unreachable; this response type is only used for requesting a default status response
|
||||||
|
@ -38,7 +38,7 @@ object ResponseUtil {
|
||||||
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_70 -> throw UnsupportedOperationException("Status response page 70 is not (yet) implemented")
|
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_70 -> throw UnsupportedOperationException("Status response page 70 is not (yet) implemented")
|
||||||
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_80 -> throw UnsupportedOperationException("Status response page 80 is not (yet) implemented")
|
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_80 -> throw UnsupportedOperationException("Status response page 80 is not (yet) implemented")
|
||||||
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_81 -> throw UnsupportedOperationException("Status response page 81 is not (yet) implemented")
|
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_81 -> throw UnsupportedOperationException("Status response page 81 is not (yet) implemented")
|
||||||
ResponseType.StatusResponseType.UNKNOWN -> throw IllegalResponseException("Unrecognized additional status response type: $additionalStatusResponseType")
|
ResponseType.StatusResponseType.UNKNOWN -> throw CouldNotParseResponseException("Unrecognized additional status response type: $additionalStatusResponseType")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -4,15 +4,19 @@ import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
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.endecrypt.EnDecrypt
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.endecrypt.EnDecrypt
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotParseResponseException
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.IllegalResponseException
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.IllegalResponseException
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.PodAlarmException
|
||||||
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.MessageType
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageType
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.StringLengthPrefixEncoding
|
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.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.Response
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
|
||||||
import info.nightscout.androidaps.utils.extensions.toHex
|
import info.nightscout.androidaps.utils.extensions.toHex
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class Session(
|
class Session(
|
||||||
private val aapsLogger: AAPSLogger,
|
private val aapsLogger: AAPSLogger,
|
||||||
|
@ -29,8 +33,8 @@ class Session(
|
||||||
* <- response, ACK TODO: retries?
|
* <- response, ACK TODO: retries?
|
||||||
* -> ACK
|
* -> ACK
|
||||||
*/
|
*/
|
||||||
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
|
@Throws(CouldNotParseResponseException::class, UnsupportedOperationException::class)
|
||||||
fun sendCommand(cmd: Command): Response {
|
fun sendCommand(cmd: Command, responseType: KClass<out Response>): Response {
|
||||||
sessionKeys.msgSequenceNumber++
|
sessionKeys.msgSequenceNumber++
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending command: ${cmd.encoded.toHex()} in packet $cmd")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending command: ${cmd.encoded.toHex()} in packet $cmd")
|
||||||
|
|
||||||
|
@ -43,6 +47,13 @@ class Session(
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Received response: $decrypted")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Received response: $decrypted")
|
||||||
val response = parseResponse(decrypted)
|
val response = parseResponse(decrypted)
|
||||||
|
|
||||||
|
if (!responseType.isInstance(response)) {
|
||||||
|
if (response is AlarmStatusResponse) {
|
||||||
|
throw PodAlarmException(response)
|
||||||
|
}
|
||||||
|
throw IllegalResponseException(responseType, response)
|
||||||
|
}
|
||||||
|
|
||||||
sessionKeys.msgSequenceNumber++
|
sessionKeys.msgSequenceNumber++
|
||||||
val ack = getAck(responseMsg)
|
val ack = getAck(responseMsg)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending ACK: ${ack.payload.toHex()} in packet $ack")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending ACK: ${ack.payload.toHex()} in packet $ack")
|
||||||
|
@ -50,7 +61,7 @@ class Session(
|
||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
|
@Throws(CouldNotParseResponseException::class, UnsupportedOperationException::class)
|
||||||
private fun parseResponse(decrypted: MessagePacket): Response {
|
private fun parseResponse(decrypted: MessagePacket): Response {
|
||||||
|
|
||||||
val payload = parseKeys(arrayOf(RESPONSE_PREFIX), decrypted.payload)[0]
|
val payload = parseKeys(arrayOf(RESPONSE_PREFIX), decrypted.payload)[0]
|
||||||
|
|
Loading…
Reference in a new issue