ble: start implementing message splitting and sending
This commit is contained in:
parent
5b128e6def
commit
08ff02dd4f
21 changed files with 316 additions and 29 deletions
|
@ -12,6 +12,9 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callback
|
|||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandHello
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.*
|
||||
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.ltk.LTKExchanger
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.MessageIO
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.status.ConnectionStatus
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.command.base.Command
|
||||
|
@ -34,16 +37,21 @@ class OmnipodDashBleManagerImpl @Inject constructor(private val context: Context
|
|||
val podScanner = PodScanner(aapsLogger, bluetoothAdapter)
|
||||
val podAddress = podScanner.scanForPod(PodScanner.SCAN_FOR_SERVICE_UUID, PodScanner.POD_ID_NOT_ACTIVATED).scanResult.device.address
|
||||
// For tests: this.podAddress = "B8:27:EB:1D:7E:BB";
|
||||
connect(podAddress)
|
||||
val bleIO = connect(podAddress)
|
||||
val msgIO = MessageIO(aapsLogger, bleIO)
|
||||
val ltkExchanger = LTKExchanger(aapsLogger, msgIO)
|
||||
val ltk = ltkExchanger.negociateLTKAndNonce()
|
||||
|
||||
aapsLogger.info(LTag.PUMPCOMM, "Got LTK and Nonce Prefix: ${ltk}")
|
||||
}
|
||||
|
||||
@Throws(FailedToConnectException::class, CouldNotSendBleException::class, InterruptedException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWriteException::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
|
||||
private fun connect(podAddress: String) {
|
||||
private fun connect(podAddress: String): BleIO {
|
||||
// TODO: locking?
|
||||
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
||||
val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>> =
|
||||
mapOf(CharacteristicType.CMD to LinkedBlockingDeque(),
|
||||
CharacteristicType.DATA to LinkedBlockingDeque());
|
||||
CharacteristicType.DATA to LinkedBlockingDeque())
|
||||
val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets)
|
||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to $podAddress")
|
||||
var autoConnect = true
|
||||
|
@ -65,6 +73,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(private val context: Context
|
|||
aapsLogger.debug(LTag.PUMPBTCOMM, "Saying hello to the pod")
|
||||
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandHello(CONTROLLER_ID).data)
|
||||
bleIO.readyToRead()
|
||||
return bleIO
|
||||
}
|
||||
|
||||
override fun sendCommand(cmd: Command): Response {
|
||||
|
@ -84,6 +93,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(private val context: Context
|
|||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val CONNECT_TIMEOUT_MS = 5000
|
||||
private const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
|
||||
}
|
||||
|
|
|
@ -4,9 +4,11 @@ import android.bluetooth.BluetoothGatt
|
|||
import android.bluetooth.BluetoothGattCharacteristic
|
||||
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.CharacteristicNotFoundException
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ServiceNotFoundException
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import android.bluetooth.BluetoothGattDescriptor
|
|||
import android.bluetooth.BluetoothProfile
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType.Companion.byValue
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType
|
||||
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 java.util.concurrent.BlockingQueue
|
||||
|
|
|
@ -1,17 +1,33 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command
|
||||
|
||||
abstract class BleCommand {
|
||||
open class BleCommand(val data: ByteArray) {
|
||||
|
||||
val data: ByteArray
|
||||
constructor(type: BleCommandType) : this(byteArrayOf(type.value)) {}
|
||||
|
||||
constructor(type: BleCommandType) {
|
||||
data = byteArrayOf(type.value)
|
||||
constructor(type: BleCommandType, payload: ByteArray): this(
|
||||
byteArrayOf(type.value) + payload
|
||||
) {}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other !is BleCommand) return false
|
||||
|
||||
if (!data.contentEquals(other.data)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
constructor(type: BleCommandType, payload: ByteArray) {
|
||||
val n = payload.size + 1
|
||||
data = ByteArray(n)
|
||||
data[0] = type.value
|
||||
System.arraycopy(payload, 0, data, 1, payload.size)
|
||||
override fun hashCode(): Int {
|
||||
return data.contentHashCode()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class BleCommandRTS(): BleCommand(BleCommandType.RTS) {}
|
||||
|
||||
class BleCommandCTS(): BleCommand(BleCommandType.CTS) {}
|
||||
|
||||
class BleCommandAbort(): BleCommand(BleCommandType.ABORT) {}
|
||||
|
||||
class BleCommandSuccess(): BleCommand(BleCommandType.SUCCESS) {}
|
||||
|
||||
class BleCommandFail(): BleCommand(BleCommandType.FAIL) {}
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command
|
||||
|
||||
class BleCommandNack {
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.CharacteristicType
|
||||
|
||||
class CouldNotEnableNotifications(cmd: CharacteristicType) : Exception(cmd.value)
|
|
@ -0,0 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommand
|
||||
import java.lang.Exception
|
||||
|
||||
class UnexpectedCommandException(val cmd: BleCommand): Exception("Unexpected command: ${cmd}") {
|
||||
}
|
|
@ -5,7 +5,6 @@ import android.bluetooth.BluetoothGattCharacteristic
|
|||
import android.bluetooth.BluetoothGattDescriptor
|
||||
import info.nightscout.androidaps.logging.AAPSLogger
|
||||
import info.nightscout.androidaps.logging.LTag
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.*
|
||||
import java.util.concurrent.BlockingQueue
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
|
||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io
|
||||
|
||||
import java.math.BigInteger
|
||||
import java.util.*
|
|
@ -0,0 +1,16 @@
|
|||
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
|
||||
|
||||
class PayloadJoiner() {
|
||||
private val payload = ByteArrayOutputStream()
|
||||
|
||||
fun accumulate(packet: BlePacket) {
|
||||
|
||||
}
|
||||
|
||||
fun bytes(): ByteArray {
|
||||
return ByteArray(0);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
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.FirstBlePacket
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.LastBlePacket
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.LastOptionalPlusOneBlePacket
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.MiddleBlePacket
|
||||
import java.lang.Integer.min
|
||||
import java.util.zip.CRC32
|
||||
|
||||
internal class PayloadSplitter(private val payload: ByteArray) {
|
||||
fun splitInPackets(): List<BlePacket> {
|
||||
val ret = ArrayList<BlePacket>()
|
||||
val crc32 = payload.crc32();
|
||||
if (payload.size <= 18) {
|
||||
val end = min(14, payload.size)
|
||||
ret.add(FirstBlePacket(
|
||||
totalFragments = 0,
|
||||
payload = payload.copyOfRange(0, end),
|
||||
size = payload.size.toByte(),
|
||||
crc32 = crc32,
|
||||
))
|
||||
if (payload.size > 14) {
|
||||
ret.add(LastOptionalPlusOneBlePacket(
|
||||
index = 1,
|
||||
payload = payload.copyOfRange(end, payload.size),
|
||||
))
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
val middleFragments = (payload.size-18)/19
|
||||
val rest = ((payload.size - middleFragments.toInt() * 19) - 18).toByte()
|
||||
ret.add(FirstBlePacket(
|
||||
totalFragments = (middleFragments + 1).toByte(),
|
||||
payload = payload.copyOfRange(0, 18),
|
||||
))
|
||||
for( i in 1..middleFragments ) {
|
||||
val p = if (i ==1 ) {
|
||||
payload.copyOfRange(18,37)
|
||||
}else {
|
||||
payload.copyOfRange((i-1)*19+18, (i-1)*19+18+19)
|
||||
}
|
||||
ret.add(MiddleBlePacket(
|
||||
index = i.toByte(),
|
||||
payload = p,
|
||||
))
|
||||
}
|
||||
val end = min(14, rest.toInt())
|
||||
ret.add(LastBlePacket(
|
||||
index = (middleFragments+1).toByte(),
|
||||
size = rest,
|
||||
payload = payload.copyOfRange(middleFragments*19+18,middleFragments*19+18+end),
|
||||
crc32 = crc32,
|
||||
))
|
||||
if (rest > 14) {
|
||||
ret.add(LastOptionalPlusOneBlePacket(
|
||||
index = (middleFragments+2).toByte(),
|
||||
payload = payload.copyOfRange(middleFragments*19+18+14, payload.size),
|
||||
))
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
internal fun ByteArray.crc32(): Long {
|
||||
val crc = CRC32()
|
||||
crc.update(this)
|
||||
return crc.value
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
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.io.BleIO
|
||||
|
||||
data class LTK(val ltk: ByteArray, val noncePrefix: ByteArray) {
|
||||
init{
|
||||
require(ltk.size == 16)
|
||||
require(noncePrefix.size == 16)
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
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.utils.extensions.hexStringToByteArray
|
||||
|
||||
internal class LTKExchanger(private val aapsLogger: AAPSLogger,private val msgIO: MessageIO) {
|
||||
|
||||
fun negociateLTKAndNonce(): LTK? {
|
||||
val msg = PairMessage(
|
||||
destination = Address(byteArrayOf(1,2,3,4)),
|
||||
source = Address(byteArrayOf(5,6,7,8)),
|
||||
payload = "5350313d0004024200032c5350323d000bffc32dbd20030e01000016".hexStringToByteArray(),
|
||||
sequenceNumber = 1,
|
||||
)
|
||||
msgIO.sendMesssage(msg)
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
data class Address(val address: ByteArray) {
|
||||
init {
|
||||
require(address.size == 4)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
abstract class Message(
|
||||
val type: MessageType,
|
||||
val source: Address,
|
||||
val destination: Address,
|
||||
val payload: ByteArray,
|
||||
val sequenceNumber: Byte,
|
||||
val ack: Boolean = false,
|
||||
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 sas: Boolean = false, // TODO: understand
|
||||
val tfs: Boolean = false, // TODO: understand
|
||||
val version: Short = 0.toShort(),
|
||||
) {
|
||||
|
||||
fun asByteArray(): ByteArray {
|
||||
return payload; // TODO implement
|
||||
}
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
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
|
||||
|
||||
class MessageIO(private val aapsLogger: AAPSLogger, private val bleIO: BleIO) {
|
||||
fun sendMesssage(msg: Message) {
|
||||
bleIO.flushIncomingQueues();
|
||||
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandRTS().data)
|
||||
val expectCTS = bleIO.receivePacket(CharacteristicType.CMD)
|
||||
if (BleCommand(expectCTS) != BleCommandCTS()) {
|
||||
throw UnexpectedCommandException(BleCommand(expectCTS))
|
||||
}
|
||||
val payload = msg.asByteArray()
|
||||
val splitter = PayloadSplitter(payload)
|
||||
val packets = splitter.splitInPackets()
|
||||
for (packet in packets) {
|
||||
bleIO.sendAndConfirmPacket(CharacteristicType.DATA, packet.asByteArray())
|
||||
}
|
||||
// TODO: peek for NACKs
|
||||
val expectSuccess = bleIO.receivePacket(CharacteristicType.CMD)
|
||||
if (BleCommand(expectSuccess) != BleCommandCTS()) {
|
||||
throw UnexpectedCommandException(BleCommand(expectSuccess))
|
||||
}
|
||||
// TODO: handle NACKS/FAILS/etc
|
||||
bleIO.flushIncomingQueues();
|
||||
}
|
||||
|
||||
|
||||
fun receiveMessage(): Message? {
|
||||
// do the RTS/CTS/data/success dance
|
||||
return null
|
||||
}
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message
|
||||
|
||||
enum class MessageType(val value: Byte) {
|
||||
CLEAR(0),
|
||||
ENCRYPTED(1),
|
||||
SESSION_ESTABLISHMENT(2),
|
||||
PAIRING(3);
|
||||
|
||||
companion object {
|
||||
fun byValue(value: Byte): MessageType =
|
||||
MessageType.values().firstOrNull() {it.value == value}
|
||||
?: throw IllegalArgumentException("Unknown MessageType: $value")
|
||||
}
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
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,
|
||||
) {
|
||||
|
||||
}
|
|
@ -1,3 +1,34 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet
|
||||
|
||||
class BlePacket
|
||||
sealed class BlePacket {
|
||||
|
||||
abstract fun asByteArray(): ByteArray
|
||||
}
|
||||
|
||||
data class FirstBlePacket(val totalFragments: Byte, val payload: ByteArray, val size: Byte = 0, val crc32: Long? = null) : BlePacket() {
|
||||
|
||||
override fun asByteArray(): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
data class MiddleBlePacket(val index: Byte, val payload: ByteArray) : BlePacket() {
|
||||
|
||||
override fun asByteArray(): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
data class LastBlePacket(val index: Byte, val size: Byte, val payload: ByteArray, val crc32: Long) : BlePacket() {
|
||||
|
||||
override fun asByteArray(): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
||||
data class LastOptionalPlusOneBlePacket(val index: Byte, val payload: ByteArray) : BlePacket() {
|
||||
|
||||
override fun asByteArray(): ByteArray {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,33 +1,34 @@
|
|||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan
|
||||
|
||||
import android.bluetooth.le.ScanRecord
|
||||
import android.bluetooth.le.ScanResult
|
||||
import android.os.ParcelUuid
|
||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DiscoveredInvalidPodException
|
||||
|
||||
class BleDiscoveredDevice(val scanResult: ScanResult, private val podId: Long) {
|
||||
class BleDiscoveredDevice(val scanResult: ScanResult, val scanRecord: ScanRecord, private val podId: Long) {
|
||||
|
||||
private val sequenceNo: Int
|
||||
private val lotNo: Long
|
||||
@Throws(DiscoveredInvalidPodException::class)
|
||||
private fun validateServiceUUIDs() {
|
||||
val scanRecord = scanResult.scanRecord
|
||||
?: throw DiscoveredInvalidPodException("Scan record is null");
|
||||
val serviceUuids = scanRecord.serviceUuids
|
||||
if (serviceUuids.size != 9) {
|
||||
throw DiscoveredInvalidPodException("Expected 9 service UUIDs, got" + serviceUuids.size, serviceUuids)
|
||||
|
||||
}
|
||||
if (extractUUID16(serviceUuids[0]) != MAIN_SERVICE_UUID) {
|
||||
// this is the service that we filtered for
|
||||
throw DiscoveredInvalidPodException("The first exposed service UUID should be 4024, got " + extractUUID16(serviceUuids[0]), serviceUuids)
|
||||
}
|
||||
// TODO understand what is serviceUUIDs[1]. 0x2470. Alarms?
|
||||
if (extractUUID16(serviceUuids[2]) != "000a") {
|
||||
if (extractUUID16(serviceUuids[2]) != UNKNOWN_THIRD_SERVICE_UUID) {
|
||||
// constant?
|
||||
throw DiscoveredInvalidPodException("The third exposed service UUID should be 000a, got " + serviceUuids[2], serviceUuids)
|
||||
}
|
||||
}
|
||||
|
||||
@Throws(DiscoveredInvalidPodException::class)
|
||||
|
||||
private fun validatePodId() {
|
||||
val scanRecord = scanResult.scanRecord
|
||||
val serviceUUIDs = scanRecord.serviceUuids
|
||||
|
@ -39,7 +40,6 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val podId: Long) {
|
|||
}
|
||||
|
||||
private fun parseLotNo(): Long {
|
||||
val scanRecord = scanResult.scanRecord
|
||||
val serviceUUIDs = scanRecord.serviceUuids
|
||||
val lotSeq = extractUUID16(serviceUUIDs[5]) +
|
||||
extractUUID16(serviceUUIDs[6]) +
|
||||
|
@ -48,7 +48,6 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val podId: Long) {
|
|||
}
|
||||
|
||||
private fun parseSeqNo(): Int {
|
||||
val scanRecord = scanResult.scanRecord
|
||||
val serviceUUIDs = scanRecord.serviceUuids
|
||||
val lotSeq = extractUUID16(serviceUUIDs[7]) +
|
||||
extractUUID16(serviceUUIDs[8])
|
||||
|
@ -57,8 +56,9 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val podId: Long) {
|
|||
|
||||
override fun toString(): String {
|
||||
return "BleDiscoveredDevice{" +
|
||||
"scanResult=" + scanResult +
|
||||
"scanRecord=" + scanRecord +
|
||||
", podID=" + podId +
|
||||
"scanResult=" + scanResult +
|
||||
", sequenceNo=" + sequenceNo +
|
||||
", lotNo=" + lotNo +
|
||||
'}'
|
||||
|
@ -66,6 +66,7 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val podId: Long) {
|
|||
|
||||
companion object {
|
||||
const val MAIN_SERVICE_UUID = "4024";
|
||||
const val UNKNOWN_THIRD_SERVICE_UUID = "000a" // FIXME: why is this 000a?
|
||||
private fun extractUUID16(uuid: ParcelUuid): String {
|
||||
return uuid.toString().substring(4, 8)
|
||||
}
|
||||
|
|
|
@ -33,9 +33,11 @@ class ScanCollector(private val logger: AAPSLogger, private val podID: Long) : S
|
|||
logger.debug(LTag.PUMPBTCOMM, "ScanCollector looking for podID: $podID")
|
||||
for (result in found.values) {
|
||||
try {
|
||||
val device = BleDiscoveredDevice(result, podID)
|
||||
ret.add(device)
|
||||
logger.debug(LTag.PUMPBTCOMM, "ScanCollector found: " + result.toString() + "Pod ID: " + podID)
|
||||
result.scanRecord?.let {
|
||||
val device = BleDiscoveredDevice(result, result.scanRecord, podID)
|
||||
ret.add(device)
|
||||
logger.debug(LTag.PUMPBTCOMM, "ScanCollector found: " + result.toString() + "Pod ID: " + podID)
|
||||
}
|
||||
} catch (e: DiscoveredInvalidPodException) {
|
||||
logger.debug(LTag.PUMPBTCOMM, "ScanCollector: pod not matching$e")
|
||||
// this is not the POD we are looking for
|
||||
|
|
Loading…
Reference in a new issue