ble:
- address review comments: renames and removed unused vars - implement serialization for BlePackets - improve logging, add .toHex() where we have []byte ``` INFO[0009] Received SP1 SP2 payload 5350313d0004024200032c5350323d000bffc32dbd20030e01000016 TRAC[0009] Read field: SP1= :: 02420003 :: 4 TRAC[0009] Read field: ,SP2= :: ffc32dbd20030e01000016 :: 11 INFO[0009] Received SP1 SP2: 02420003 :: ffc32dbd20030e01000016 ```
This commit is contained in:
parent
08ff02dd4f
commit
af1d505e36
9 changed files with 58 additions and 24 deletions
|
@ -11,6 +11,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.Chara
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType.Companion.byValue
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType.Companion.byValue
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWriteException
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWriteException
|
||||||
|
import info.nightscout.androidaps.utils.extensions.toHex
|
||||||
import java.util.concurrent.BlockingQueue
|
import java.util.concurrent.BlockingQueue
|
||||||
import java.util.concurrent.CountDownLatch
|
import java.util.concurrent.CountDownLatch
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
|
@ -63,10 +64,10 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
|
|
||||||
private fun confirmWritePayload(expectedPayload: ByteArray, received: CharacteristicWriteConfirmationPayload) {
|
private fun confirmWritePayload(expectedPayload: ByteArray, received: CharacteristicWriteConfirmationPayload) {
|
||||||
if (!expectedPayload.contentEquals(received.payload)) {
|
if (!expectedPayload.contentEquals(received.payload)) {
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm write. Got " + received.payload + ".Excepted: " + expectedPayload)
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm write. Got " + received.payload.toHex() + ".Excepted: " + expectedPayload.toHex())
|
||||||
throw CouldNotConfirmWriteException(expectedPayload, received.payload)
|
throw CouldNotConfirmWriteException(expectedPayload, received.payload)
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Confirmed write with value: " + received.payload)
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Confirmed write with value: " + received.payload.toHex())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
|
override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
|
||||||
|
@ -77,7 +78,7 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
CharacteristicWriteConfirmationError(status)
|
CharacteristicWriteConfirmationError(status)
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite with status/char/value " +
|
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite with status/char/value " +
|
||||||
status + "/" + byValue(characteristic.uuid.toString()) + "/" + characteristic.value)
|
status + "/" + byValue(characteristic.uuid.toString()) + "/" + characteristic.value.toHex())
|
||||||
try {
|
try {
|
||||||
if (writeQueue.size > 0) {
|
if (writeQueue.size > 0) {
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, "Write confirm queue should be empty. found: " + writeQueue.size)
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Write confirm queue should be empty. found: " + writeQueue.size)
|
||||||
|
@ -98,7 +99,7 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
val characteristicType = byValue(characteristic.uuid.toString())
|
val characteristicType = byValue(characteristic.uuid.toString())
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicChanged with char/value " +
|
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicChanged with char/value " +
|
||||||
characteristicType + "/" +
|
characteristicType + "/" +
|
||||||
payload)
|
payload.toHex())
|
||||||
incomingPackets[characteristicType]!!.add(payload)
|
incomingPackets[characteristicType]!!.add(payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,7 +121,7 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
|
override fun onDescriptorWrite(gatt: BluetoothGatt, descriptor: BluetoothGattDescriptor, status: Int) {
|
||||||
super.onDescriptorWrite(gatt, descriptor, status)
|
super.onDescriptorWrite(gatt, descriptor, status)
|
||||||
val writeConfirmation = if (status == BluetoothGatt.GATT_SUCCESS) {
|
val writeConfirmation = if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "OnDescriptor value " + descriptor.value)
|
aapsLogger.debug(LTag.PUMPBTCOMM, "OnDescriptor value " + descriptor.value.toHex())
|
||||||
DescriptorWriteConfirmationUUID(descriptor.uuid.toString())
|
DescriptorWriteConfirmationUUID(descriptor.uuid.toString())
|
||||||
} else {
|
} else {
|
||||||
DescriptorWriteConfirmationError(status)
|
DescriptorWriteConfirmationError(status)
|
||||||
|
|
|
@ -7,6 +7,7 @@ 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.callbacks.BleCommCallbacks
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.*
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.*
|
||||||
|
import info.nightscout.androidaps.utils.extensions.toHex
|
||||||
import java.util.concurrent.BlockingQueue
|
import java.util.concurrent.BlockingQueue
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.TimeoutException
|
import java.util.concurrent.TimeoutException
|
||||||
|
@ -48,7 +49,8 @@ class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map<Character
|
||||||
}
|
}
|
||||||
state = IOState.WRITING
|
state = IOState.WRITING
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "BleIO: Sending data on" + characteristic.name + "/" + payload.toString())
|
aapsLogger.debug(LTag.PUMPBTCOMM, "BleIO: Sending data on " + characteristic.name + "/" + payload.toHex())
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM, "BleIO: Sending data on " + characteristic.name + "/" + payload.toHex())
|
||||||
val ch = chars[characteristic]
|
val ch = chars[characteristic]
|
||||||
val set = ch!!.setValue(payload)
|
val set = ch!!.setValue(payload)
|
||||||
if (!set) {
|
if (!set) {
|
||||||
|
|
|
@ -7,7 +7,6 @@ class PayloadJoiner() {
|
||||||
private val payload = ByteArrayOutputStream()
|
private val payload = ByteArrayOutputStream()
|
||||||
|
|
||||||
fun accumulate(packet: BlePacket) {
|
fun accumulate(packet: BlePacket) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun bytes(): ByteArray {
|
fun bytes(): ByteArray {
|
||||||
|
|
|
@ -62,7 +62,7 @@ internal class PayloadSplitter(private val payload: ByteArray) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun ByteArray.crc32(): Long {
|
private fun ByteArray.crc32(): Long {
|
||||||
val crc = CRC32()
|
val crc = CRC32()
|
||||||
crc.update(this)
|
crc.update(this)
|
||||||
return crc.value
|
return crc.value
|
||||||
|
|
|
@ -12,7 +12,7 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger,private val msgIO
|
||||||
val msg = PairMessage(
|
val msg = PairMessage(
|
||||||
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 = "5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
|
payload = "545710030100038002420000fffffffe5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
|
||||||
sequenceNumber = 1,
|
sequenceNumber = 1,
|
||||||
)
|
)
|
||||||
msgIO.sendMesssage(msg)
|
msgIO.sendMesssage(msg)
|
||||||
|
|
|
@ -10,12 +10,12 @@ abstract class Message(
|
||||||
val ackNumber: Byte = 0.toByte(),
|
val ackNumber: Byte = 0.toByte(),
|
||||||
val eqos: Short = 0.toShort(), // TODO: understand
|
val eqos: Short = 0.toShort(), // TODO: understand
|
||||||
val priority: Boolean = false,
|
val priority: Boolean = false,
|
||||||
val lastMessage: Boolean= false,
|
val lastMessage: Boolean = false,
|
||||||
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
|
return payload; // TODO implement
|
||||||
|
|
|
@ -2,19 +2,19 @@ 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.BleManager
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommand
|
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.BleCommandCTS
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandHello
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandRTS
|
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.BleIO
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType
|
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
|
||||||
|
|
||||||
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: Message) {
|
||||||
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)
|
||||||
if (BleCommand(expectCTS) != BleCommandCTS()) {
|
if (BleCommand(expectCTS) != BleCommandCTS()) {
|
||||||
|
@ -24,6 +24,7 @@ class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
|
||||||
val splitter = PayloadSplitter(payload)
|
val splitter = PayloadSplitter(payload)
|
||||||
val packets = splitter.splitInPackets()
|
val packets = splitter.splitInPackets()
|
||||||
for (packet in packets) {
|
for (packet in packets) {
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending DATA: ", packet.asByteArray().toHex())
|
||||||
bleIO.sendAndConfirmPacket(CharacteristicType.DATA, packet.asByteArray())
|
bleIO.sendAndConfirmPacket(CharacteristicType.DATA, packet.asByteArray())
|
||||||
}
|
}
|
||||||
// TODO: peek for NACKs
|
// TODO: peek for NACKs
|
||||||
|
@ -32,10 +33,9 @@ class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
|
||||||
throw UnexpectedCommandException(BleCommand(expectSuccess))
|
throw UnexpectedCommandException(BleCommand(expectSuccess))
|
||||||
}
|
}
|
||||||
// TODO: handle NACKS/FAILS/etc
|
// TODO: handle NACKS/FAILS/etc
|
||||||
bleIO.flushIncomingQueues();
|
bleIO.flushIncomingQueues()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun receiveMessage(): Message? {
|
fun receiveMessage(): Message? {
|
||||||
// do the RTS/CTS/data/success dance
|
// do the RTS/CTS/data/success dance
|
||||||
return null
|
return null
|
||||||
|
|
|
@ -1,34 +1,64 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet
|
||||||
|
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
sealed class BlePacket {
|
sealed class BlePacket {
|
||||||
|
|
||||||
abstract fun asByteArray(): ByteArray
|
abstract fun asByteArray(): ByteArray
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
|
||||||
|
const val MAX_BLE_PACKET_LEN = 30 // we use this as the size allocated for the ByteBuffer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class FirstBlePacket(val totalFragments: Byte, val payload: ByteArray, val size: Byte = 0, val crc32: Long? = null) : BlePacket() {
|
data class FirstBlePacket(val totalFragments: Byte, val payload: ByteArray, val size: Byte? = null, val crc32: Long? = null) : BlePacket() {
|
||||||
|
|
||||||
override fun asByteArray(): ByteArray {
|
override fun asByteArray(): ByteArray {
|
||||||
TODO("Not yet implemented")
|
val bb = ByteBuffer
|
||||||
|
.allocate(MAX_BLE_PACKET_LEN)
|
||||||
|
.put(0) // index
|
||||||
|
.put(totalFragments) // # of fragments except FirstBlePacket and LastOptionalPlusOneBlePacket
|
||||||
|
crc32?.let {
|
||||||
|
bb.putInt(crc32.toInt())
|
||||||
|
}
|
||||||
|
size?.let {
|
||||||
|
bb.put(size)
|
||||||
|
}
|
||||||
|
bb.put(payload)
|
||||||
|
val ret = ByteArray(bb.position())
|
||||||
|
bb.flip()
|
||||||
|
bb.get(ret)
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class MiddleBlePacket(val index: Byte, val payload: ByteArray) : BlePacket() {
|
data class MiddleBlePacket(val index: Byte, val payload: ByteArray) : BlePacket() {
|
||||||
|
|
||||||
override fun asByteArray(): ByteArray {
|
override fun asByteArray(): ByteArray {
|
||||||
TODO("Not yet implemented")
|
return byteArrayOf(index) + payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LastBlePacket(val index: Byte, val size: Byte, val payload: ByteArray, val crc32: Long) : BlePacket() {
|
data class LastBlePacket(val index: Byte, val size: Byte, val payload: ByteArray, val crc32: Long) : BlePacket() {
|
||||||
|
|
||||||
override fun asByteArray(): ByteArray {
|
override fun asByteArray(): ByteArray {
|
||||||
TODO("Not yet implemented")
|
val bb = ByteBuffer
|
||||||
|
.allocate(MAX_BLE_PACKET_LEN)
|
||||||
|
.put(index)
|
||||||
|
.put(size)
|
||||||
|
.putInt(crc32.toInt())
|
||||||
|
.put(payload)
|
||||||
|
val ret = ByteArray(bb.position())
|
||||||
|
bb.flip()
|
||||||
|
bb.get(ret)
|
||||||
|
return ret
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
data class LastOptionalPlusOneBlePacket(val index: Byte, val payload: ByteArray) : BlePacket() {
|
data class LastOptionalPlusOneBlePacket(val index: Byte, val payload: ByteArray) : BlePacket() {
|
||||||
|
|
||||||
override fun asByteArray(): ByteArray {
|
override fun asByteArray(): ByteArray {
|
||||||
TODO("Not yet implemented")
|
return byteArrayOf(index) + payload
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InitializePodViewModel
|
import info.nightscout.androidaps.plugins.pump.omnipod.common.ui.wizard.activation.viewmodel.action.InitializePodViewModel
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.R
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManager
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManager
|
||||||
|
import org.apache.commons.lang3.exception.ExceptionUtils
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
class DashInitializePodViewModel @Inject constructor(private val aapsLogger: AAPSLogger,
|
class DashInitializePodViewModel @Inject constructor(private val aapsLogger: AAPSLogger,
|
||||||
|
@ -27,7 +28,8 @@ class DashInitializePodViewModel @Inject constructor(private val aapsLogger: AAP
|
||||||
try {
|
try {
|
||||||
bleManager.activateNewPod()
|
bleManager.activateNewPod()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
aapsLogger.error(LTag.PUMP, "TEST ACTIVATE Exception" + e.toString())
|
aapsLogger.error(LTag.PUMP, "TEST ACTIVATE Exception" + e.toString() + ExceptionUtils.getStackTrace(e))
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,4 +41,4 @@ class DashInitializePodViewModel @Inject constructor(private val aapsLogger: AAP
|
||||||
|
|
||||||
@StringRes
|
@StringRes
|
||||||
override fun getTextId() = R.string.omnipod_dash_pod_activation_wizard_initialize_pod_text
|
override fun getTextId() = R.string.omnipod_dash_pod_activation_wizard_initialize_pod_text
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue