ble: start implementing message reading
This commit is contained in:
parent
af1d505e36
commit
ea4db2c17b
8 changed files with 72 additions and 27 deletions
|
@ -1,4 +1,5 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command
|
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))
|
||||||
|
|
|
@ -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 info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.BlePacket
|
||||||
import java.io.ByteArrayOutputStream
|
import java.io.ByteArrayOutputStream
|
||||||
|
|
||||||
|
sealed class PayloadJoinerAction
|
||||||
|
|
||||||
|
class PayloadJoinerActionAccept(): PayloadJoinerAction()
|
||||||
|
class PayloadJoinerActionReject(val idx: Byte): PayloadJoinerAction()
|
||||||
|
|
||||||
class PayloadJoiner() {
|
class PayloadJoiner() {
|
||||||
|
var oneExtra: Boolean=false
|
||||||
|
|
||||||
private val payload = ByteArrayOutputStream()
|
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 {
|
fun bytes(): ByteArray {
|
||||||
return ByteArray(0);
|
return ByteArray(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
|
@ -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.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.Address
|
||||||
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.PairMessage
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessagePacket
|
||||||
import info.nightscout.androidaps.utils.extensions.hexStringToByteArray
|
import info.nightscout.androidaps.utils.extensions.hexStringToByteArray
|
||||||
|
|
||||||
internal class LTKExchanger(private val aapsLogger: AAPSLogger,private val msgIO: MessageIO) {
|
internal class LTKExchanger(private val aapsLogger: AAPSLogger,private val msgIO: MessageIO) {
|
||||||
|
|
||||||
fun negociateLTKAndNonce(): LTK? {
|
fun negociateLTKAndNonce(): LTK? {
|
||||||
val msg = PairMessage(
|
val msg = MessagePacket(
|
||||||
destination = Address(byteArrayOf(1,2,3,4)),
|
destination = Address(byteArrayOf(1,2,3,4)),
|
||||||
source = Address(byteArrayOf(5,6,7,8)),
|
source = Address(byteArrayOf(5,6,7,8)),
|
||||||
payload = "545710030100038002420000fffffffe5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
|
payload = "545710030100038002420000fffffffe5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ltk
|
||||||
|
|
||||||
|
class PairMessage
|
|
@ -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.AAPSLogger
|
||||||
import info.nightscout.androidaps.logging.LTag
|
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.*
|
||||||
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.exceptions.UnexpectedCommandException
|
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.*
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.PayloadSplitter
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.PayloadSplitter
|
||||||
import info.nightscout.androidaps.utils.extensions.toHex
|
import info.nightscout.androidaps.utils.extensions.toHex
|
||||||
|
|
||||||
class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
|
class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
|
||||||
|
|
||||||
fun sendMesssage(msg: Message) {
|
fun sendMesssage(msg: MessagePacket) {
|
||||||
bleIO.flushIncomingQueues()
|
bleIO.flushIncomingQueues()
|
||||||
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandRTS().data)
|
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandRTS().data)
|
||||||
val expectCTS = bleIO.receivePacket(CharacteristicType.CMD)
|
val expectCTS = bleIO.receivePacket(CharacteristicType.CMD)
|
||||||
|
@ -36,8 +33,35 @@ class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
|
||||||
bleIO.flushIncomingQueues()
|
bleIO.flushIncomingQueues()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun receiveMessage(): Message? {
|
fun receiveMessage(): MessagePacket {
|
||||||
// do the RTS/CTS/data/success dance
|
val expectRTS = bleIO.receivePacket(CharacteristicType.CMD)
|
||||||
return null
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||||
|
|
||||||
abstract class Message(
|
data class MessagePacket(
|
||||||
val type: MessageType,
|
val type: MessageType,
|
||||||
val source: Address,
|
val source: Address,
|
||||||
val destination: Address,
|
val destination: Address,
|
||||||
|
@ -14,10 +14,16 @@ abstract class Message(
|
||||||
val gateway: Boolean = false,
|
val gateway: Boolean = false,
|
||||||
val sas: Boolean = false, // TODO: understand
|
val sas: Boolean = false, // TODO: understand
|
||||||
val tfs: Boolean = false, // TODO: understand
|
val tfs: Boolean = false, // TODO: understand
|
||||||
val version: Short = 0.toShort(),
|
val version: Short = 0.toShort()) {
|
||||||
) {
|
|
||||||
|
|
||||||
fun asByteArray(): ByteArray {
|
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")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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,
|
|
||||||
) {
|
|
||||||
|
|
||||||
}
|
|
|
@ -7,7 +7,6 @@ sealed class BlePacket {
|
||||||
abstract fun asByteArray(): ByteArray
|
abstract fun asByteArray(): ByteArray
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
const val MAX_BLE_PACKET_LEN = 30 // we use this as the size allocated for the ByteBuffer
|
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
|
return byteArrayOf(index) + payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue