ble: start implementing message reading

This commit is contained in:
Andrei Vereha 2021-02-26 11:18:02 +01:00
parent af1d505e36
commit ea4db2c17b
8 changed files with 72 additions and 27 deletions

View file

@ -1,4 +1,5 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command
class BleCommandNack {
}
import java.nio.ByteBuffer
class BleCommandNack(idx: Byte): BleCommand(BleCommandType.NACK, byteArrayOf(idx))

View file

@ -3,13 +3,32 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.BlePacket
import java.io.ByteArrayOutputStream
sealed class PayloadJoinerAction
class PayloadJoinerActionAccept(): PayloadJoinerAction()
class PayloadJoinerActionReject(val idx: Byte): PayloadJoinerAction()
class PayloadJoiner() {
var oneExtra: Boolean=false
private val payload = ByteArrayOutputStream()
fun accumulate(packet: BlePacket) {
fun start(payload: ByteArray): Int {
return 0;
}
fun accumulate(payload: ByteArray): PayloadJoinerAction {
return PayloadJoinerActionAccept()
}
fun finalize(): PayloadJoinerAction {
return PayloadJoinerActionAccept()
}
fun bytes(): ByteArray {
return ByteArray(0);
}
}

View file

@ -3,13 +3,13 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ltk
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.Address
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.PairMessage
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
import info.nightscout.androidaps.utils.extensions.hexStringToByteArray
internal class LTKExchanger(private val aapsLogger: AAPSLogger,private val msgIO: MessageIO) {
fun negociateLTKAndNonce(): LTK? {
val msg = PairMessage(
val msg = MessagePacket(
destination = Address(byteArrayOf(1,2,3,4)),
source = Address(byteArrayOf(5,6,7,8)),
payload = "545710030100038002420000fffffffe5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ltk
class PairMessage

View file

@ -2,18 +2,15 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommand
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandCTS
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandRTS
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.UnexpectedCommandException
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.*
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.PayloadSplitter
import info.nightscout.androidaps.utils.extensions.toHex
class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
fun sendMesssage(msg: Message) {
fun sendMesssage(msg: MessagePacket) {
bleIO.flushIncomingQueues()
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandRTS().data)
val expectCTS = bleIO.receivePacket(CharacteristicType.CMD)
@ -36,8 +33,35 @@ class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
bleIO.flushIncomingQueues()
}
fun receiveMessage(): Message? {
// do the RTS/CTS/data/success dance
return null
fun receiveMessage(): MessagePacket {
val expectRTS = bleIO.receivePacket(CharacteristicType.CMD)
if (BleCommand(expectRTS) != BleCommandCTS()) {
throw UnexpectedCommandException(BleCommand(expectRTS))
}
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandCTS().data)
val joiner = PayloadJoiner()
var data = bleIO.receivePacket(CharacteristicType.DATA)
val fragments = joiner.start(data)
for (i in 1 until fragments) {
data = bleIO.receivePacket(CharacteristicType.DATA)
val accumlateAction = joiner.accumulate(data)
if (accumlateAction is PayloadJoinerActionReject) {
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandNack(accumlateAction.idx).data)
}
}
if (joiner.oneExtra) {
var data = bleIO.receivePacket(CharacteristicType.DATA)
val accumulateAction = joiner.accumulate(data)
if (accumulateAction is PayloadJoinerActionReject) {
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandNack(accumulateAction.idx).data)
}
}
val finalCmd = when (joiner.finalize()) {
is PayloadJoinerActionAccept -> BleCommandSuccess()
is PayloadJoinerActionReject -> BleCommandFail()
}
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, finalCmd.data)
val fullPayload = joiner.bytes()
return MessagePacket.parse(fullPayload)
}
}

View file

@ -1,6 +1,6 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
abstract class Message(
data class MessagePacket(
val type: MessageType,
val source: Address,
val destination: Address,
@ -14,10 +14,16 @@ abstract class Message(
val gateway: Boolean = false,
val sas: Boolean = false, // TODO: understand
val tfs: Boolean = false, // TODO: understand
val version: Short = 0.toShort(),
) {
val version: Short = 0.toShort()) {
fun asByteArray(): ByteArray {
return payload; // TODO implement
// TODO: implement proper serialization
return this.payload
}
companion object {
fun parse(payload: ByteArray): MessagePacket {
TODO("implement message header parsing")
}
}
}

View file

@ -1,8 +0,0 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
class PairMessage(source: Address, destination: Address, payload: ByteArray, sequenceNumber: Byte
) : Message(
type=MessageType.PAIRING, source, destination, payload, sequenceNumber,
) {
}

View file

@ -7,7 +7,6 @@ sealed class BlePacket {
abstract fun asByteArray(): ByteArray
companion object {
const val MAX_BLE_PACKET_LEN = 30 // we use this as the size allocated for the ByteBuffer
}
}
@ -62,3 +61,4 @@ data class LastOptionalPlusOneBlePacket(val index: Byte, val payload: ByteArray)
return byteArrayOf(index) + payload
}
}