Add Omnipod Dash response parsing

This commit is contained in:
Bart Sopers 2021-03-14 20:14:11 +01:00
parent 2f9c88594b
commit aff38851e1
4 changed files with 53 additions and 2 deletions

View file

@ -90,6 +90,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
return bleIO
}
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
override fun sendCommand(cmd: Command): Observable<PodEvent> = Observable.create { emitter ->
try {
val keys = sessionKeys

View file

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

View file

@ -0,0 +1,44 @@
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.pod.response.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.util.byValue
object ResponseUtil {
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
fun parseResponse(payload: ByteArray): Response {
return when (val responseType = byValue(payload[0], ResponseType.UNKNOWN)) {
ResponseType.ACTIVATION_RESPONSE -> parseActivationResponse(payload)
ResponseType.DEFAULT_STATUS_RESPONSE -> DefaultStatusResponse(payload)
ResponseType.ADDITIONAL_STATUS_RESPONSE -> parseAdditionalStatusResponse(payload)
ResponseType.NAK_RESPONSE -> NakResponse(payload)
ResponseType.UNKNOWN -> throw IllegalResponseException("Unrecognized message type: $responseType")
}
}
@Throws(IllegalResponseException::class)
private fun parseActivationResponse(payload: ByteArray): Response {
return when (val activationResponseType = byValue(payload[1], ResponseType.ActivationResponseType.UNKNOWN)) {
ResponseType.ActivationResponseType.GET_VERSION_RESPONSE -> VersionResponse(payload)
ResponseType.ActivationResponseType.SET_UNIQUE_ID_RESPONSE -> SetUniqueIdResponse(payload)
ResponseType.ActivationResponseType.UNKNOWN -> throw IllegalResponseException("Unrecognized activation response type: $activationResponseType")
}
}
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
private fun parseAdditionalStatusResponse(payload: ByteArray): Response {
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.STATUS_RESPONSE_PAGE_1 -> throw UnsupportedOperationException("Status response page 1 is not (yet) implemented")
ResponseType.StatusResponseType.ALARM_STATUS -> AlarmStatusResponse(payload)
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_3 -> throw UnsupportedOperationException("Status response page 3 is not (yet) implemented")
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_5 -> throw UnsupportedOperationException("Status response page 5 is not (yet) implemented")
ResponseType.StatusResponseType.STATUS_RESPONSE_PAGE_6 -> throw UnsupportedOperationException("Status response page 6 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_81 -> throw UnsupportedOperationException("Status response page 81 is not (yet) implemented")
ResponseType.StatusResponseType.UNKNOWN -> throw IllegalResponseException("Unrecognized additional status response type: $additionalStatusResponseType")
}
}
}

View file

@ -4,13 +4,13 @@ import info.nightscout.androidaps.logging.AAPSLogger
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.endecrypt.EnDecrypt
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.IllegalResponseException
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.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.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.response.NakResponse
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.response.Response
import info.nightscout.androidaps.utils.extensions.toHex
@ -29,6 +29,7 @@ class Session(
* <- response, ACK TODO: retries?
* -> ACK
*/
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
fun sendCommand(cmd: Command): Response {
sessionKeys.msgSequenceNumber++
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending command: ${cmd.encoded.toHex()} in packet $cmd")
@ -49,11 +50,13 @@ class Session(
return response
}
@Throws(IllegalResponseException::class, UnsupportedOperationException::class)
private fun parseResponse(decrypted: MessagePacket): Response {
val payload = parseKeys(arrayOf(RESPONSE_PREFIX), decrypted.payload)[0]
aapsLogger.info(LTag.PUMPBTCOMM, "Received decrypted response: ${payload.toHex()} in packet: $decrypted")
return NakResponse(payload)
return ResponseUtil.parseResponse(payload)
}
private fun getAck(response: MessagePacket): MessagePacket {