Implement more suggestions after the switch to Kotlin
This commit is contained in:
parent
2a14d60bee
commit
f2fed8adc4
11 changed files with 54 additions and 41 deletions
|
@ -13,7 +13,6 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.
|
||||||
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.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.scan.PodScanner
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner
|
||||||
import java.util.*
|
|
||||||
import java.util.concurrent.BlockingQueue
|
import java.util.concurrent.BlockingQueue
|
||||||
import java.util.concurrent.LinkedBlockingDeque
|
import java.util.concurrent.LinkedBlockingDeque
|
||||||
import java.util.concurrent.TimeoutException
|
import java.util.concurrent.TimeoutException
|
||||||
|
@ -26,7 +25,7 @@ class BleManager @Inject constructor(private val context: Context, private val a
|
||||||
private val bluetoothManager: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
private val bluetoothManager: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
|
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
|
||||||
|
|
||||||
@Throws(InterruptedException::class, ScanFailException::class, FailedToConnectException::class, CouldNotSendBleException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWrite::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
|
@Throws(InterruptedException::class, ScanFailException::class, FailedToConnectException::class, CouldNotSendBleException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWriteException::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
|
||||||
fun activateNewPod() {
|
fun activateNewPod() {
|
||||||
aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation")
|
aapsLogger.info(LTag.PUMPBTCOMM, "starting new pod activation")
|
||||||
val podScanner = PodScanner(aapsLogger, bluetoothAdapter)
|
val podScanner = PodScanner(aapsLogger, bluetoothAdapter)
|
||||||
|
@ -35,7 +34,7 @@ class BleManager @Inject constructor(private val context: Context, private val a
|
||||||
connect(podAddress)
|
connect(podAddress)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(FailedToConnectException::class, CouldNotSendBleException::class, InterruptedException::class, BleIOBusyException::class, TimeoutException::class, CouldNotConfirmWrite::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
|
@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) {
|
||||||
// TODO: locking?
|
// TODO: locking?
|
||||||
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
||||||
|
@ -61,7 +60,7 @@ class BleManager @Inject constructor(private val context: Context, private val a
|
||||||
val chars = discoverer.discoverServices()
|
val chars = discoverer.discoverServices()
|
||||||
val bleIO = BleIO(aapsLogger, chars, incomingPackets, gatt, bleCommCallbacks)
|
val bleIO = BleIO(aapsLogger, chars, incomingPackets, gatt, bleCommCallbacks)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Saying hello to the pod")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Saying hello to the pod")
|
||||||
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandHello(CONTROLLER_ID).asByteArray())
|
bleIO.sendAndConfirmPacket(CharacteristicType.CMD, BleCommandHello(CONTROLLER_ID).data)
|
||||||
bleIO.readyToRead()
|
bleIO.readyToRead()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ 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
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType.Companion.byValue
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.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.CouldNotConfirmWrite
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWriteException
|
||||||
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
|
||||||
|
@ -50,23 +50,21 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
serviceDiscoveryComplete.await(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
serviceDiscoveryComplete.await(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(InterruptedException::class, TimeoutException::class, CouldNotConfirmWrite::class)
|
@Throws(InterruptedException::class, TimeoutException::class, CouldNotConfirmWriteException::class)
|
||||||
fun confirmWrite(expectedPayload: ByteArray, timeout_ms: Int) {
|
fun confirmWrite(expectedPayload: ByteArray, timeout_ms: Int) {
|
||||||
val received: CharacteristicWriteConfirmation = writeQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
val received: CharacteristicWriteConfirmation = writeQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
||||||
?: throw TimeoutException()
|
?: throw TimeoutException()
|
||||||
|
|
||||||
when (received) {
|
when (received) {
|
||||||
is CharacteristicWriteConfirmationPayload -> confirmWritePayload(expectedPayload, received)
|
is CharacteristicWriteConfirmationPayload -> confirmWritePayload(expectedPayload, received)
|
||||||
is CharacteristicWriteConfirmationError ->
|
is CharacteristicWriteConfirmationError -> throw CouldNotConfirmWriteException(received.status)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Could not confirm write: status was ${received.status}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 + ". Status: " + received.status)
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm write. Got " + received.payload + ".Excepted: " + expectedPayload)
|
||||||
throw CouldNotConfirmWrite(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)
|
||||||
}
|
}
|
||||||
|
@ -74,8 +72,7 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
|
override fun onCharacteristicWrite(gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, status: Int) {
|
||||||
super.onCharacteristicWrite(gatt, characteristic, status)
|
super.onCharacteristicWrite(gatt, characteristic, status)
|
||||||
val writeConfirmation = if (status == BluetoothGatt.GATT_SUCCESS) {
|
val writeConfirmation = if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite value " + characteristic.getStringValue(0))
|
CharacteristicWriteConfirmationPayload(characteristic.value)
|
||||||
CharacteristicWriteConfirmationPayload(characteristic.value, status)
|
|
||||||
} else {
|
} else {
|
||||||
CharacteristicWriteConfirmationError(status)
|
CharacteristicWriteConfirmationError(status)
|
||||||
}
|
}
|
||||||
|
@ -107,26 +104,33 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
|
|
||||||
@Throws(InterruptedException::class, CouldNotConfirmDescriptorWriteException::class)
|
@Throws(InterruptedException::class, CouldNotConfirmDescriptorWriteException::class)
|
||||||
fun confirmWriteDescriptor(descriptorUUID: String, timeout_ms: Int) {
|
fun confirmWriteDescriptor(descriptorUUID: String, timeout_ms: Int) {
|
||||||
val confirmed = descriptorWriteQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
val confirmed: DescriptorWriteConfirmation = descriptorWriteQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
||||||
if (descriptorUUID != confirmed.uuid) {
|
?: throw TimeoutException()
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm descriptor write. Got " + confirmed.uuid + ".Expected: " + descriptorUUID + ". Status: " + confirmed.status)
|
when (confirmed) {
|
||||||
throw CouldNotConfirmDescriptorWriteException(confirmed.uuid!!, descriptorUUID)
|
is DescriptorWriteConfirmationError -> throw CouldNotConfirmWriteException(confirmed.status)
|
||||||
|
is DescriptorWriteConfirmationUUID -> if (confirmed.uuid != descriptorUUID) {
|
||||||
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm descriptor write. Got ${confirmed.uuid}. Expected: ${descriptorUUID}")
|
||||||
|
throw CouldNotConfirmDescriptorWriteException(descriptorUUID, confirmed.uuid)
|
||||||
|
} else {
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Confirmed descriptor write : " + confirmed.uuid)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
var uuid: String? = null
|
val writeConfirmation = if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
aapsLogger.debug(LTag.PUMPBTCOMM, "OnDescriptor value " + descriptor.value)
|
||||||
uuid = descriptor.uuid.toString()
|
DescriptorWriteConfirmationUUID(descriptor.uuid.toString())
|
||||||
|
} else {
|
||||||
|
DescriptorWriteConfirmationError(status)
|
||||||
}
|
}
|
||||||
val confirmation = DescriptorWriteConfirmation(status, uuid)
|
|
||||||
try {
|
try {
|
||||||
if (descriptorWriteQueue.size > 0) {
|
if (descriptorWriteQueue.size > 0) {
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, "Descriptor write queue should be empty, found: " + descriptorWriteQueue.size)
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Descriptor write queue should be empty, found: " + descriptorWriteQueue.size)
|
||||||
descriptorWriteQueue.clear()
|
descriptorWriteQueue.clear()
|
||||||
}
|
}
|
||||||
val offered = descriptorWriteQueue.offer(confirmation, WRITE_CONFIRM_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
|
val offered = descriptorWriteQueue.offer(writeConfirmation, WRITE_CONFIRM_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
|
||||||
if (!offered) {
|
if (!offered) {
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed descriptor write confirmation")
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed descriptor write confirmation")
|
||||||
}
|
}
|
||||||
|
@ -136,7 +140,6 @@ class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingP
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
private const val WRITE_CONFIRM_TIMEOUT_MS = 10 // the confirmation queue should be empty anyway
|
||||||
private const val WRITE_CONFIRM_TIMEOUT_MS = 10 // the other thread should be waiting for the exchange
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -2,6 +2,6 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbac
|
||||||
|
|
||||||
sealed class CharacteristicWriteConfirmation
|
sealed class CharacteristicWriteConfirmation
|
||||||
|
|
||||||
class CharacteristicWriteConfirmationPayload(val payload: ByteArray, val status: Int) : CharacteristicWriteConfirmation()
|
data class CharacteristicWriteConfirmationPayload(val payload: ByteArray) : CharacteristicWriteConfirmation()
|
||||||
|
|
||||||
class CharacteristicWriteConfirmationError(val status: Int) : CharacteristicWriteConfirmation()
|
data class CharacteristicWriteConfirmationError(val status: Int) : CharacteristicWriteConfirmation()
|
|
@ -1,3 +1,7 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks
|
||||||
|
|
||||||
class DescriptorWriteConfirmation(var status: Int, var uuid: String?)
|
sealed class DescriptorWriteConfirmation
|
||||||
|
|
||||||
|
data class DescriptorWriteConfirmationUUID(val uuid: String): DescriptorWriteConfirmation()
|
||||||
|
|
||||||
|
data class DescriptorWriteConfirmationError(val status: Int): DescriptorWriteConfirmation()
|
|
@ -2,7 +2,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command
|
||||||
|
|
||||||
abstract class BleCommand {
|
abstract class BleCommand {
|
||||||
|
|
||||||
private val data: ByteArray
|
val data: ByteArray
|
||||||
|
|
||||||
constructor(type: BleCommandType) {
|
constructor(type: BleCommandType) {
|
||||||
data = byteArrayOf(type.value)
|
data = byteArrayOf(type.value)
|
||||||
|
@ -14,8 +14,4 @@ abstract class BleCommand {
|
||||||
data[0] = type.value
|
data[0] = type.value
|
||||||
System.arraycopy(payload, 0, data, 1, payload.size)
|
System.arraycopy(payload, 0, data, 1, payload.size)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun asByteArray(): ByteArray {
|
|
||||||
return data
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,3 +1,6 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||||
|
|
||||||
class CouldNotConfirmDescriptorWriteException(private val received: String, private val expected: String) : Exception()
|
class CouldNotConfirmDescriptorWriteException(override val message: String?) : Exception(message) {
|
||||||
|
constructor(sent: String, confirmed: String): this("Could not confirm write. Sent: {$sent} .Received: ${confirmed}")
|
||||||
|
constructor(status: Int): this("Could not confirm write. Write status: ${status}")
|
||||||
|
}
|
|
@ -1,3 +0,0 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
|
||||||
|
|
||||||
class CouldNotConfirmWrite(private val sent: ByteArray, private val confirmed: ByteArray?) : Exception()
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||||
|
|
||||||
|
class CouldNotConfirmWriteException(override val message: String?) : Exception(message) {
|
||||||
|
constructor(sent: ByteArray, confirmed: ByteArray): this("Could not confirm write. Sent: {$sent} .Received: ${confirmed}")
|
||||||
|
constructor(status: Int): this("Could not confirm write. Write status: ${status}")
|
||||||
|
}
|
|
@ -2,4 +2,7 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.excepti
|
||||||
|
|
||||||
import android.os.ParcelUuid
|
import android.os.ParcelUuid
|
||||||
|
|
||||||
class DiscoveredInvalidPodException(message: String, serviceUUIds: List<ParcelUuid?>) : Exception("$message service UUIDs: $serviceUUIds")
|
class DiscoveredInvalidPodException: Exception {
|
||||||
|
constructor(message: String) : super(message) {}
|
||||||
|
constructor(message: String, serviceUUIds: List<ParcelUuid?>) : super("$message service UUIDs: $serviceUUIds"){}
|
||||||
|
}
|
|
@ -41,7 +41,7 @@ class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map<Character
|
||||||
* @param payload the data to send
|
* @param payload the data to send
|
||||||
* @throws CouldNotSendBleException
|
* @throws CouldNotSendBleException
|
||||||
*/
|
*/
|
||||||
@Throws(CouldNotSendBleException::class, BleIOBusyException::class, InterruptedException::class, CouldNotConfirmWrite::class, TimeoutException::class)
|
@Throws(CouldNotSendBleException::class, BleIOBusyException::class, InterruptedException::class, CouldNotConfirmWriteException::class, TimeoutException::class)
|
||||||
fun sendAndConfirmPacket(characteristic: CharacteristicType, payload: ByteArray) {
|
fun sendAndConfirmPacket(characteristic: CharacteristicType, payload: ByteArray) {
|
||||||
synchronized(state) {
|
synchronized(state) {
|
||||||
if (state != IOState.IDLE) {
|
if (state != IOState.IDLE) {
|
||||||
|
|
|
@ -8,9 +8,10 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val podID: Long) {
|
||||||
|
|
||||||
private val sequenceNo: Int
|
private val sequenceNo: Int
|
||||||
private val lotNo: Long
|
private val lotNo: Long
|
||||||
@Throws(DiscoveredInvalidPodException::class) private fun validateServiceUUIDs() {
|
@Throws(DiscoveredInvalidPodException::class)
|
||||||
|
private fun validateServiceUUIDs() {
|
||||||
val scanRecord = scanResult.scanRecord
|
val scanRecord = scanResult.scanRecord
|
||||||
?: throw DiscoveredInvalidPodException("Scan record is null")
|
?: throw DiscoveredInvalidPodException("Scan record is null");
|
||||||
val serviceUUIDs = scanRecord.serviceUuids
|
val serviceUUIDs = scanRecord.serviceUuids
|
||||||
if (serviceUUIDs.size != 9) {
|
if (serviceUUIDs.size != 9) {
|
||||||
throw DiscoveredInvalidPodException("Expected 9 service UUIDs, got" + serviceUUIDs.size, serviceUUIDs)
|
throw DiscoveredInvalidPodException("Expected 9 service UUIDs, got" + serviceUUIDs.size, serviceUUIDs)
|
||||||
|
@ -26,7 +27,8 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val podID: Long) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(DiscoveredInvalidPodException::class) private fun validatePodID() {
|
@Throws(DiscoveredInvalidPodException::class)
|
||||||
|
private fun validatePodID() {
|
||||||
val scanRecord = scanResult.scanRecord
|
val scanRecord = scanResult.scanRecord
|
||||||
val serviceUUIDs = scanRecord.serviceUuids
|
val serviceUUIDs = scanRecord.serviceUuids
|
||||||
val hexPodID = extractUUID16(serviceUUIDs[3]) + extractUUID16(serviceUUIDs[4])
|
val hexPodID = extractUUID16(serviceUUIDs[3]) + extractUUID16(serviceUUIDs[4])
|
||||||
|
|
Loading…
Reference in a new issue