diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt index 70d787b01e..1af3a91892 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommand.kt @@ -14,7 +14,7 @@ class BleCommandFail : BleCommand(BleCommandType.FAIL) open class BleCommand(val data: ByteArray) { - constructor(type: BleCommandType) : this(byteArrayOf(type.value, 0)) + constructor(type: BleCommandType) : this(byteArrayOf(type.value)) constructor(type: BleCommandType, payload: ByteArray) : this( byteArrayOf(type.value) + payload @@ -36,4 +36,5 @@ open class BleCommand(val data: ByteArray) { override fun hashCode(): Int { return data.contentHashCode() } + } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt index 7953cbab4b..eb8b6bdb47 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/command/BleCommandType.kt @@ -7,9 +7,7 @@ enum class BleCommandType(val value: Byte) { ABORT(0x03.toByte()), SUCCESS(0x04.toByte()), FAIL(0x05.toByte()), - HELLO( - 0x06.toByte() - ); + HELLO(0x06.toByte()); companion object { diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt index b879cf61c8..23b7ae8054 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/endecrypt/EnDecrypt.kt @@ -32,6 +32,7 @@ class EnDecrypt(private val aapsLogger: AAPSLogger, private val nonce: Nonce, pr ) val decryptedPayload = ByteArray(payload.size - MAC_SIZE) cipher.processPacket(payload, 0, payload.size, decryptedPayload, 0) + aapsLogger.debug(LTag.PUMPBTCOMM, "Decrypted payload ${decryptedPayload.toHex()}") return msg.copy(payload = decryptedPayload) } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt index 5308c88a71..bd5e895f3a 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/message/MessageIO.kt @@ -8,17 +8,34 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptio import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.BleIO import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.PayloadJoiner +import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.CommandType import info.nightscout.androidaps.utils.extensions.toHex class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) { - fun sendMessage(msg: MessagePacket) { + private fun expectCommandType(actual: BleCommand, expected: BleCommand) { + if (actual.data.isEmpty()) { + throw UnexpectedCommandException(actual) + } + // first byte is the command type + if (actual.data[0] == expected.data[0]) { + return + } + throw UnexpectedCommandException(actual) + + } + + fun sendMessage(msg: MessagePacket):MessagePacket? { bleIO.flushIncomingQueues() bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandRTS().data) val expectCTS = bleIO.receivePacket(CharacteristicType.CMD) - if (BleCommand(expectCTS) != BleCommandCTS()) { + if (expectCTS.isEmpty()) { throw UnexpectedCommandException(BleCommand(expectCTS)) } + //if (expectCTS[0] == BleCommandType.RTS.value) { + //the pod is trying to send something, after we sent RTS, let's read it + //} + expectCommandType(BleCommand(expectCTS), BleCommandCTS()) val payload = msg.asByteArray() aapsLogger.debug(LTag.PUMPBTCOMM, "Sending message: ${payload.toHex()}") val splitter = PayloadSplitter(payload) @@ -29,17 +46,18 @@ class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) { } // TODO: peek for NACKs val expectSuccess = bleIO.receivePacket(CharacteristicType.CMD) - if (BleCommand(expectSuccess) != BleCommandSuccess()) { - throw UnexpectedCommandException(BleCommand(expectSuccess)) - } + expectCommandType(BleCommand(expectSuccess), BleCommandSuccess()) // TODO: handle NACKS/FAILS/etc + return null } - fun receiveMessage(): MessagePacket { - val expectRTS = bleIO.receivePacket(CharacteristicType.CMD) - if (BleCommand(expectRTS) != BleCommandRTS()) { - throw UnexpectedCommandException(BleCommand(expectRTS)) + // TODO: use higher timeout when receiving the first packet in a message + fun receiveMessage( firstCmd: ByteArray? = null): MessagePacket { + var expectRTS = firstCmd + if (expectRTS == null) { + expectRTS = bleIO.receivePacket(CharacteristicType.CMD) } + expectCommandType(BleCommand(expectRTS), BleCommandRTS()) bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandCTS().data) try { val joiner = PayloadJoiner(bleIO.receivePacket(CharacteristicType.DATA)) diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt index d5fc2739da..e45c9a322a 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Session.kt @@ -31,12 +31,14 @@ class Session( */ fun sendCommand(cmd: Command): Response { sessionKeys.msgSequenceNumber++ - aapsLogger.debug(LTag.PUMPBTCOMM, "Sending command: ${cmd.encoded.toHex()}") + aapsLogger.debug(LTag.PUMPBTCOMM, "Sending command: ${cmd.encoded.toHex()} in packet $cmd") val msg = getCmdMessage(cmd) aapsLogger.debug(LTag.PUMPBTCOMM, "Sending command(wrapped): ${msg.payload.toHex()}") - msgIO.sendMessage(msg) - + val reply = msgIO.sendMessage(msg) + if (reply != null) { // TODO : this means the last ACK was not received, send it again? + aapsLogger.debug(LTag.PUMPBTCOMM, "Received a message with payload instead of CTS: ${reply.payload.toHex()} in packet $reply") + } val responseMsg = msgIO.receiveMessage() val decrypted = enDecrypt.decrypt(responseMsg) aapsLogger.debug(LTag.PUMPBTCOMM, "Received response: $decrypted") @@ -44,13 +46,15 @@ class Session( sessionKeys.msgSequenceNumber++ val ack = getAck(responseMsg) - aapsLogger.debug(LTag.PUMPBTCOMM, "Sending ACK: ${ack.payload.toHex()}") + aapsLogger.debug(LTag.PUMPBTCOMM, "Sending ACK: ${ack.payload.toHex()} in packet $ack") msgIO.sendMessage(ack) return response } 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) } @@ -61,9 +65,9 @@ class Session( source = myId, destination = podId, payload = ByteArray(0), - eqos = 1, + eqos = 0, ack = true, - ackNumber = response.sequenceNumber.inc() + ackNumber = (response.sequenceNumber.toInt()+1).toByte() ) return enDecrypt.encrypt((msg)) }