kotlin a bit more idiomatic after conversion from Java
This commit is contained in:
parent
647793e0b7
commit
2a14d60bee
11 changed files with 78 additions and 127 deletions
|
@ -1,68 +1,49 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm
|
||||||
|
|
||||||
|
|
||||||
import javax.inject.Singleton
|
|
||||||
import javax.inject.Inject
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.OmnipodDashCommunicationManager
|
|
||||||
import android.bluetooth.BluetoothAdapter
|
import android.bluetooth.BluetoothAdapter
|
||||||
import android.bluetooth.BluetoothManager
|
|
||||||
import info.nightscout.androidaps.logging.AAPSLogger
|
|
||||||
import android.bluetooth.BluetoothGatt
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io.BleIO
|
|
||||||
import kotlin.Throws
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ScanFailException
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.FailedToConnectException
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotSendBleException
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.BleIOBusyException
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmWrite
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotEnableNotifications
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.DescriptorNotFoundException
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.CouldNotConfirmDescriptorWriteException
|
|
||||||
import info.nightscout.androidaps.logging.LTag
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.PodScanner
|
|
||||||
import android.bluetooth.BluetoothDevice
|
import android.bluetooth.BluetoothDevice
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.CharacteristicType
|
import android.bluetooth.BluetoothManager
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks
|
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.BleManager
|
|
||||||
import android.bluetooth.BluetoothProfile
|
import android.bluetooth.BluetoothProfile
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.ServiceDiscoverer
|
|
||||||
import android.bluetooth.BluetoothGattCharacteristic
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
|
import info.nightscout.androidaps.logging.AAPSLogger
|
||||||
|
import info.nightscout.androidaps.logging.LTag
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.BuildConfig
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.BuildConfig
|
||||||
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.callbacks.BleCommCallbacks
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.command.BleCommandHello
|
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.scan.PodScanner
|
||||||
import java.util.*
|
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
|
||||||
|
import javax.inject.Inject
|
||||||
|
import javax.inject.Singleton
|
||||||
|
|
||||||
@Singleton
|
@Singleton
|
||||||
class BleManager @Inject constructor(private val context: Context) : OmnipodDashCommunicationManager {
|
class BleManager @Inject constructor(private val context: Context, private val aapsLogger: AAPSLogger) : OmnipodDashCommunicationManager {
|
||||||
|
|
||||||
private val bluetoothAdapter: BluetoothAdapter
|
private val bluetoothManager: BluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
||||||
private val bluetoothManager: BluetoothManager
|
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
|
||||||
|
|
||||||
@Inject lateinit var aapsLogger: AAPSLogger
|
|
||||||
private var podAddress: String? = null
|
|
||||||
private var gatt: BluetoothGatt? = null
|
|
||||||
private var bleio: BleIO? = null
|
|
||||||
@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, CouldNotConfirmWrite::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)
|
||||||
podAddress = podScanner.scanForPod(PodScanner.SCAN_FOR_SERVICE_UUID, PodScanner.POD_ID_NOT_ACTIVATED).scanResult.device.address
|
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";
|
// For tests: this.podAddress = "B8:27:EB:1D:7E:BB";
|
||||||
connect()
|
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, CouldNotConfirmWrite::class, CouldNotEnableNotifications::class, DescriptorNotFoundException::class, CouldNotConfirmDescriptorWriteException::class)
|
||||||
fun connect() {
|
private fun connect(podAddress: String) {
|
||||||
// TODO: locking?
|
// TODO: locking?
|
||||||
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
val podDevice = bluetoothAdapter.getRemoteDevice(podAddress)
|
||||||
var incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>> =
|
val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>> =
|
||||||
mapOf(CharacteristicType.CMD to LinkedBlockingDeque(),
|
mapOf(CharacteristicType.CMD to LinkedBlockingDeque(),
|
||||||
CharacteristicType.DATA to LinkedBlockingDeque());
|
CharacteristicType.DATA to LinkedBlockingDeque());
|
||||||
val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets)
|
val bleCommCallbacks = BleCommCallbacks(aapsLogger, incomingPackets)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to " + podAddress)
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Connecting to $podAddress")
|
||||||
var autoConnect = true
|
var autoConnect = true
|
||||||
if (BuildConfig.DEBUG) {
|
if (BuildConfig.DEBUG) {
|
||||||
autoConnect = false
|
autoConnect = false
|
||||||
|
@ -70,8 +51,6 @@ class BleManager @Inject constructor(private val context: Context) : OmnipodDash
|
||||||
// it's easier to start testing from scratch on each run.
|
// it's easier to start testing from scratch on each run.
|
||||||
}
|
}
|
||||||
val gatt = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
|
val gatt = podDevice.connectGatt(context, autoConnect, bleCommCallbacks, BluetoothDevice.TRANSPORT_LE)
|
||||||
this.gatt = gatt
|
|
||||||
|
|
||||||
bleCommCallbacks.waitForConnection(CONNECT_TIMEOUT_MS)
|
bleCommCallbacks.waitForConnection(CONNECT_TIMEOUT_MS)
|
||||||
val connectionState = bluetoothManager.getConnectionState(podDevice, BluetoothProfile.GATT)
|
val connectionState = bluetoothManager.getConnectionState(podDevice, BluetoothProfile.GATT)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "GATT connection state: $connectionState")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "GATT connection state: $connectionState")
|
||||||
|
@ -80,10 +59,10 @@ class BleManager @Inject constructor(private val context: Context) : OmnipodDash
|
||||||
}
|
}
|
||||||
val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks)
|
val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks)
|
||||||
val chars = discoverer.discoverServices()
|
val chars = discoverer.discoverServices()
|
||||||
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).asByteArray())
|
||||||
bleio!!.readyToRead()
|
bleIO.readyToRead()
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -92,8 +71,4 @@ class BleManager @Inject constructor(private val context: Context) : OmnipodDash
|
||||||
private const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
|
private const val CONTROLLER_ID = 4242 // TODO read from preferences or somewhere else.
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
bluetoothManager = context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
|
|
||||||
bluetoothAdapter = bluetoothManager.adapter
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -14,13 +14,9 @@ enum class CharacteristicType(val value: String) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
@JvmStatic fun byValue(value: String): CharacteristicType {
|
@JvmStatic
|
||||||
for (type in values()) {
|
fun byValue(value: String): CharacteristicType =
|
||||||
if (type.value == value) {
|
values().firstOrNull { it.value == value }
|
||||||
return type
|
?: throw IllegalArgumentException("Unknown Characteristic Type: $value")
|
||||||
}
|
|
||||||
}
|
|
||||||
throw IllegalArgumentException("Unknown Characteristic Type: $value")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -22,26 +22,25 @@ class ServiceDiscoverer(private val logger: AAPSLogger, private val gatt: Blueto
|
||||||
gatt.discoverServices()
|
gatt.discoverServices()
|
||||||
bleCallbacks.waitForServiceDiscovery(DISCOVER_SERVICES_TIMEOUT_MS)
|
bleCallbacks.waitForServiceDiscovery(DISCOVER_SERVICES_TIMEOUT_MS)
|
||||||
logger.debug(LTag.PUMPBTCOMM, "Services discovered")
|
logger.debug(LTag.PUMPBTCOMM, "Services discovered")
|
||||||
val service = gatt.getService(
|
val service = gatt.getService(SERVICE_UUID.toUuid())
|
||||||
uuidFromString(SERVICE_UUID))
|
|
||||||
?: throw ServiceNotFoundException(SERVICE_UUID)
|
?: throw ServiceNotFoundException(SERVICE_UUID)
|
||||||
val cmdChar = service.getCharacteristic(CharacteristicType.CMD.uUID)
|
val cmdChar = service.getCharacteristic(CharacteristicType.CMD.uUID)
|
||||||
?: throw CharacteristicNotFoundException(CharacteristicType.CMD.value)
|
?: throw CharacteristicNotFoundException(CharacteristicType.CMD.value)
|
||||||
val dataChar = service.getCharacteristic(CharacteristicType.DATA.uUID)
|
val dataChar = service.getCharacteristic(CharacteristicType.DATA.uUID) // TODO: this is never used
|
||||||
?: throw CharacteristicNotFoundException(CharacteristicType.DATA.value)
|
?: throw CharacteristicNotFoundException(CharacteristicType.DATA.value)
|
||||||
var chars = mapOf(CharacteristicType.CMD to cmdChar,
|
var chars = mapOf(CharacteristicType.CMD to cmdChar,
|
||||||
CharacteristicType.DATA to dataChar)
|
CharacteristicType.DATA to dataChar)
|
||||||
return chars
|
return chars
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun String.toUuid(): UUID = UUID(
|
||||||
|
BigInteger(replace("-", "").substring(0, 16), 16).toLong(),
|
||||||
|
BigInteger(replace("-", "").substring(16), 16).toLong()
|
||||||
|
)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private const val SERVICE_UUID = "1a7e-4024-e3ed-4464-8b7e-751e03d0dc5f"
|
private const val SERVICE_UUID = "1a7e-4024-e3ed-4464-8b7e-751e03d0dc5f"
|
||||||
private const val DISCOVER_SERVICES_TIMEOUT_MS = 5000
|
private const val DISCOVER_SERVICES_TIMEOUT_MS = 5000
|
||||||
private fun uuidFromString(s: String): UUID {
|
|
||||||
return UUID(
|
|
||||||
BigInteger(s.replace("-", "").substring(0, 16), 16).toLong(),
|
|
||||||
BigInteger(s.replace("-", "").substring(16), 16).toLong()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,21 +11,19 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.Characte
|
||||||
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.CouldNotConfirmWrite
|
||||||
import java.util.*
|
|
||||||
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
|
||||||
import java.util.concurrent.TimeUnit
|
import java.util.concurrent.TimeUnit
|
||||||
import java.util.concurrent.TimeoutException
|
import java.util.concurrent.TimeoutException
|
||||||
|
|
||||||
class BleCommCallbacks(aapsLogger: AAPSLogger, incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>>) : BluetoothGattCallback() {
|
class BleCommCallbacks(private val aapsLogger: AAPSLogger, private val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>>) : BluetoothGattCallback() {
|
||||||
|
|
||||||
|
private val serviceDiscoveryComplete: CountDownLatch = CountDownLatch(1)
|
||||||
|
private val connected: CountDownLatch = CountDownLatch(1)
|
||||||
|
private val writeQueue: BlockingQueue<CharacteristicWriteConfirmation> = LinkedBlockingQueue(1)
|
||||||
|
private val descriptorWriteQueue: BlockingQueue<DescriptorWriteConfirmation> = LinkedBlockingQueue(1)
|
||||||
|
|
||||||
private val serviceDiscoveryComplete: CountDownLatch
|
|
||||||
private val connected: CountDownLatch
|
|
||||||
private val aapsLogger: AAPSLogger
|
|
||||||
private val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>>
|
|
||||||
private val writeQueue: BlockingQueue<CharacteristicWriteConfirmation>
|
|
||||||
private val descriptorWriteQueue: BlockingQueue<DescriptorWriteConfirmation>
|
|
||||||
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
|
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
|
||||||
super.onConnectionStateChange(gatt, status, newState)
|
super.onConnectionStateChange(gatt, status, newState)
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "OnConnectionStateChange discovered with status/state$status/$newState")
|
aapsLogger.debug(LTag.PUMPBTCOMM, "OnConnectionStateChange discovered with status/state$status/$newState")
|
||||||
|
@ -42,42 +40,53 @@ class BleCommCallbacks(aapsLogger: AAPSLogger, incomingPackets: Map<Characterist
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(InterruptedException::class) fun waitForConnection(timeout_ms: Int) {
|
@Throws(InterruptedException::class)
|
||||||
|
fun waitForConnection(timeout_ms: Int) {
|
||||||
connected.await(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
connected.await(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(InterruptedException::class) fun waitForServiceDiscovery(timeout_ms: Int) {
|
@Throws(InterruptedException::class)
|
||||||
|
fun waitForServiceDiscovery(timeout_ms: Int) {
|
||||||
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, CouldNotConfirmWrite::class)
|
||||||
fun confirmWrite(expectedPayload: ByteArray, timeout_ms: Int) {
|
fun confirmWrite(expectedPayload: ByteArray, timeout_ms: Int) {
|
||||||
val received = writeQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
val received: CharacteristicWriteConfirmation = writeQueue.poll(timeout_ms.toLong(), TimeUnit.MILLISECONDS)
|
||||||
?: throw TimeoutException()
|
?: throw TimeoutException()
|
||||||
if (!Arrays.equals(expectedPayload, received.payload)) {
|
|
||||||
|
when (received) {
|
||||||
|
is CharacteristicWriteConfirmationPayload -> confirmWritePayload(expectedPayload, received)
|
||||||
|
is CharacteristicWriteConfirmationError ->
|
||||||
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Could not confirm write: status was ${received.status}")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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 + ". Status: " + received.status)
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Could not confirm write. Got " + received.payload + ".Excepted: " + expectedPayload + ". Status: " + received.status)
|
||||||
throw CouldNotConfirmWrite(expectedPayload, received.payload!!)
|
throw CouldNotConfirmWrite(expectedPayload, received.payload)
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "Confirmed write with value: " + received.payload)
|
aapsLogger.debug(LTag.PUMPBTCOMM, "Confirmed write with value: " + received.payload)
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
var received: ByteArray? = null
|
val writeConfirmation = if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
|
||||||
received = characteristic.value
|
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite value " + characteristic.getStringValue(0))
|
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite value " + characteristic.getStringValue(0))
|
||||||
|
CharacteristicWriteConfirmationPayload(characteristic.value, status)
|
||||||
|
} else {
|
||||||
|
CharacteristicWriteConfirmationError(status)
|
||||||
}
|
}
|
||||||
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite with status/char/value " +
|
aapsLogger.debug(LTag.PUMPBTCOMM, "OnCharacteristicWrite with status/char/value " +
|
||||||
status + "/" +
|
status + "/" + byValue(characteristic.uuid.toString()) + "/" + characteristic.value)
|
||||||
byValue(characteristic.uuid.toString()) + "/" +
|
|
||||||
received)
|
|
||||||
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)
|
||||||
writeQueue.clear()
|
writeQueue.clear()
|
||||||
}
|
}
|
||||||
val offered = writeQueue.offer(CharacteristicWriteConfirmation(received, status), WRITE_CONFIRM_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
|
val offered = writeQueue.offer(writeConfirmation, WRITE_CONFIRM_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
|
||||||
if (!offered) {
|
if (!offered) {
|
||||||
aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed write confirmation")
|
aapsLogger.warn(LTag.PUMPBTCOMM, "Received delayed write confirmation")
|
||||||
}
|
}
|
||||||
|
@ -130,13 +139,4 @@ class BleCommCallbacks(aapsLogger: AAPSLogger, incomingPackets: Map<Characterist
|
||||||
|
|
||||||
private const val WRITE_CONFIRM_TIMEOUT_MS = 10 // the other thread should be waiting for the exchange
|
private const val WRITE_CONFIRM_TIMEOUT_MS = 10 // the other thread should be waiting for the exchange
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
serviceDiscoveryComplete = CountDownLatch(1)
|
|
||||||
connected = CountDownLatch(1)
|
|
||||||
this.aapsLogger = aapsLogger
|
|
||||||
this.incomingPackets = incomingPackets
|
|
||||||
writeQueue = LinkedBlockingQueue(1)
|
|
||||||
descriptorWriteQueue = LinkedBlockingQueue(1)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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 CharacteristicWriteConfirmation(var payload: ByteArray?, var status: Int)
|
sealed class CharacteristicWriteConfirmation
|
||||||
|
|
||||||
|
class CharacteristicWriteConfirmationPayload(val payload: ByteArray, val status: Int) : CharacteristicWriteConfirmation()
|
||||||
|
|
||||||
|
class CharacteristicWriteConfirmationError(val status: Int) : CharacteristicWriteConfirmation()
|
|
@ -5,13 +5,8 @@ enum class BleCommandType(val value: Byte) {
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
fun byValue(value: Byte): BleCommandType {
|
fun byValue(value: Byte): BleCommandType =
|
||||||
for (type in values()) {
|
BleCommandType.values().firstOrNull { it.value == value }
|
||||||
if (type.value == value) {
|
?: throw IllegalArgumentException("Unknown BleCommandType: $value")
|
||||||
return type
|
|
||||||
}
|
|
||||||
}
|
|
||||||
throw IllegalArgumentException("Unknown BleCommandType: $value")
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,10 +1,3 @@
|
||||||
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
|
||||||
|
|
||||||
class CouldNotConfirmWrite(private val sent: ByteArray, confirmed: ByteArray) : Exception() {
|
class CouldNotConfirmWrite(private val sent: ByteArray, private val confirmed: ByteArray?) : Exception()
|
||||||
|
|
||||||
private val confirmed: Any
|
|
||||||
|
|
||||||
init {
|
|
||||||
this.confirmed = confirmed
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,13 +3,9 @@ package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.excepti
|
||||||
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.BleDiscoveredDevice
|
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.scan.BleDiscoveredDevice
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class ScanFailFoundTooManyException(devices: List<BleDiscoveredDevice>?) : ScanFailException() {
|
class ScanFailFoundTooManyException(devices: List<BleDiscoveredDevice>) : ScanFailException() {
|
||||||
|
|
||||||
private val devices: List<BleDiscoveredDevice>
|
private val devices: List<BleDiscoveredDevice> = ArrayList(devices)
|
||||||
val discoveredDevices: List<BleDiscoveredDevice>
|
val discoveredDevices: List<BleDiscoveredDevice>
|
||||||
get() = Collections.unmodifiableList(devices)
|
get() = Collections.unmodifiableList(devices)
|
||||||
|
|
||||||
init {
|
|
||||||
this.devices = ArrayList(devices)
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -14,7 +14,7 @@ import java.util.concurrent.TimeoutException
|
||||||
|
|
||||||
class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map<CharacteristicType, BluetoothGattCharacteristic>, private val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>>, private val gatt: BluetoothGatt, private val bleCommCallbacks: BleCommCallbacks) {
|
class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map<CharacteristicType, BluetoothGattCharacteristic>, private val incomingPackets: Map<CharacteristicType, BlockingQueue<ByteArray>>, private val gatt: BluetoothGatt, private val bleCommCallbacks: BleCommCallbacks) {
|
||||||
|
|
||||||
private var state: IOState
|
private var state: IOState = IOState.IDLE
|
||||||
|
|
||||||
/***
|
/***
|
||||||
*
|
*
|
||||||
|
@ -29,7 +29,7 @@ class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map<Character
|
||||||
}
|
}
|
||||||
state = IOState.READING
|
state = IOState.READING
|
||||||
}
|
}
|
||||||
val ret = incomingPackets[characteristic]!!.poll(DEFAULT_IO_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
|
val ret = incomingPackets[characteristic]?.poll(DEFAULT_IO_TIMEOUT_MS.toLong(), TimeUnit.MILLISECONDS)
|
||||||
?: throw TimeoutException()
|
?: throw TimeoutException()
|
||||||
synchronized(state) { state = IOState.IDLE }
|
synchronized(state) { state = IOState.IDLE }
|
||||||
return ret
|
return ret
|
||||||
|
@ -97,8 +97,4 @@ class BleIO(private val aapsLogger: AAPSLogger, private val chars: Map<Character
|
||||||
|
|
||||||
private const val DEFAULT_IO_TIMEOUT_MS = 1000
|
private const val DEFAULT_IO_TIMEOUT_MS = 1000
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
state = IOState.IDLE
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -31,7 +31,7 @@ class PodScanner(private val logger: AAPSLogger, private val bluetoothAdapter: B
|
||||||
scanner.flushPendingScanResults(scanCollector)
|
scanner.flushPendingScanResults(scanCollector)
|
||||||
scanner.stopScan(scanCollector)
|
scanner.stopScan(scanCollector)
|
||||||
val collected = scanCollector.collect()
|
val collected = scanCollector.collect()
|
||||||
if (collected.size == 0) {
|
if (collected.isEmpty()) {
|
||||||
throw ScanFailNotFoundException()
|
throw ScanFailNotFoundException()
|
||||||
} else if (collected.size > 1) {
|
} else if (collected.size > 1) {
|
||||||
throw ScanFailFoundTooManyException(collected)
|
throw ScanFailFoundTooManyException(collected)
|
||||||
|
|
|
@ -12,7 +12,7 @@ import java.util.concurrent.ConcurrentHashMap
|
||||||
class ScanCollector(private val logger: AAPSLogger, private val podID: Long) : ScanCallback() {
|
class ScanCollector(private val logger: AAPSLogger, private val podID: Long) : ScanCallback() {
|
||||||
|
|
||||||
// there could be different threads calling the onScanResult callback
|
// there could be different threads calling the onScanResult callback
|
||||||
private val found: ConcurrentHashMap<String, ScanResult>
|
private val found: ConcurrentHashMap<String, ScanResult> = ConcurrentHashMap()
|
||||||
private var scanFailed = 0
|
private var scanFailed = 0
|
||||||
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
override fun onScanResult(callbackType: Int, result: ScanResult) {
|
||||||
// callbackType will be ALL
|
// callbackType will be ALL
|
||||||
|
@ -31,7 +31,7 @@ class ScanCollector(private val logger: AAPSLogger, private val podID: Long) : S
|
||||||
if (scanFailed != 0) {
|
if (scanFailed != 0) {
|
||||||
throw ScanFailException(scanFailed)
|
throw ScanFailException(scanFailed)
|
||||||
}
|
}
|
||||||
logger.debug(LTag.PUMPBTCOMM, "ScanCollector looking for podID: " + podID)
|
logger.debug(LTag.PUMPBTCOMM, "ScanCollector looking for podID: $podID")
|
||||||
for (result in found.values) {
|
for (result in found.values) {
|
||||||
try {
|
try {
|
||||||
val device = BleDiscoveredDevice(result, podID)
|
val device = BleDiscoveredDevice(result, podID)
|
||||||
|
@ -45,7 +45,4 @@ class ScanCollector(private val logger: AAPSLogger, private val podID: Long) : S
|
||||||
return Collections.unmodifiableList(ret)
|
return Collections.unmodifiableList(ret)
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
|
||||||
found = ConcurrentHashMap()
|
|
||||||
}
|
|
||||||
}
|
}
|
Loading…
Reference in a new issue