- 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:
Andrei Vereha 2021-02-25 19:19:06 +01:00
parent 08ff02dd4f
commit af1d505e36
9 changed files with 58 additions and 24 deletions

View file

@ -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.exceptions.CouldNotConfirmDescriptorWriteException
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.CountDownLatch
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) {
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)
}
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) {
@ -77,7 +78,7 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
CharacteristicWriteConfirmationError(status)
}
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 {
if (writeQueue.size > 0) {
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())
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicChanged with char/value " +
characteristicType + "/" +
payload)
payload.toHex())
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) {
super.onDescriptorWrite(gatt, descriptor, status)
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())
} else {
DescriptorWriteConfirmationError(status)

View file

@ -7,6 +7,7 @@ import info.nightscout.androidaps.logging.AAPSLogger
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.exceptions.*
import info.nightscout.androidaps.utils.extensions.toHex
import java.util.concurrent.BlockingQueue
import java.util.concurrent.TimeUnit
import java.util.concurrent.TimeoutException
@ -48,7 +49,8 @@ class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map<Character
}
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 set = ch!!.setValue(payload)
if (!set) {

View file

@ -7,7 +7,6 @@ class PayloadJoiner() {
private val payload = ByteArrayOutputStream()
fun accumulate(packet: BlePacket) {
}
fun bytes(): ByteArray {

View file

@ -62,7 +62,7 @@ internal class PayloadSplitter(private val payload: ByteArray) {
}
}
internal fun ByteArray.crc32(): Long {
private fun ByteArray.crc32(): Long {
val crc = CRC32()
crc.update(this)
return crc.value

View file

@ -12,7 +12,7 @@ internal class LTKExchanger(private val aapsLogger: AAPSLogger,private val msgIO
val msg = PairMessage(
destination = Address(byteArrayOf(1,2,3,4)),
source = Address(byteArrayOf(5,6,7,8)),
payload = "5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
payload = "545710030100038002420000fffffffe5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
sequenceNumber = 1,
)
msgIO.sendMesssage(msg)

View file

@ -10,12 +10,12 @@ abstract class Message(
val ackNumber: Byte = 0.toByte(),
val eqos: Short = 0.toShort(), // TODO: understand
val priority: Boolean = false,
val lastMessage: Boolean= false,
val gateway: Boolean = false,
val lastMessage: Boolean = false,
val gateway: Boolean = false,
val sas: Boolean = false, // TODO: understand
val tfs: Boolean = false, // TODO: understand
val version: Short = 0.toShort(),
) {
) {
fun asByteArray(): ByteArray {
return payload; // TODO implement

View file

@ -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.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.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.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.PayloadSplitter
import info.nightscout.androidaps.utils.extensions.toHex
class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
fun sendMesssage(msg: Message) {
bleIO.flushIncomingQueues();
bleIO.flushIncomingQueues()
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandRTS().data)
val expectCTS = bleIO.receivePacket(CharacteristicType.CMD)
if (BleCommand(expectCTS) != BleCommandCTS()) {
@ -24,6 +24,7 @@ class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
val splitter = PayloadSplitter(payload)
val packets = splitter.splitInPackets()
for (packet in packets) {
aapsLogger.debug(LTag.PUMPBTCOMM, "Sending DATA: ", packet.asByteArray().toHex())
bleIO.sendAndConfirmPacket(CharacteristicType.DATA, packet.asByteArray())
}
// TODO: peek for NACKs
@ -32,10 +33,9 @@ class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
throw UnexpectedCommandException(BleCommand(expectSuccess))
}
// TODO: handle NACKS/FAILS/etc
bleIO.flushIncomingQueues();
bleIO.flushIncomingQueues()
}
fun receiveMessage(): Message? {
// do the RTS/CTS/data/success dance
return null

View file

@ -1,34 +1,64 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet
import java.nio.ByteBuffer
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
}
}
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 {
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() {
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() {
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() {
override fun asByteArray(): ByteArray {
TODO("Not yet implemented")
return byteArrayOf(index) + payload
}
}

View file

@ -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.dash.R
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashBleManager
import org.apache.commons.lang3.exception.ExceptionUtils
import javax.inject.Inject
class DashInitializePodViewModel @Inject constructor(private val aapsLogger: AAPSLogger,
@ -27,7 +28,8 @@ class DashInitializePodViewModel @Inject constructor(private val aapsLogger: AAP
try {
bleManager.activateNewPod()
} 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
override fun getTextId() = R.string.omnipod_dash_pod_activation_wizard_initialize_pod_text
}
}