timeout for service discovery

This commit is contained in:
Andrei Vereha 2021-06-27 22:12:21 +02:00
parent 9c0aa54e6b
commit 0582fe0326
3 changed files with 34 additions and 11 deletions

View file

@ -7,6 +7,8 @@ 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.ConnectException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions.ConnectException
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.session.Connection.Companion.STOP_CONNECTING_CHECK_INTERVAL_MS
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.session.ConnectionWaitCondition
import java.math.BigInteger import java.math.BigInteger
import java.util.* import java.util.*
@ -19,14 +21,23 @@ class ServiceDiscoverer(
/*** /***
* This is first step after connection establishment * This is first step after connection establishment
*/ */
fun discoverServices(): Map<CharacteristicType, BluetoothGattCharacteristic> { fun discoverServices(connectionWaitCond: ConnectionWaitCondition): Map<CharacteristicType, BluetoothGattCharacteristic> {
logger.debug(LTag.PUMPBTCOMM, "Discovering services") logger.debug(LTag.PUMPBTCOMM, "Discovering services")
bleCallbacks.startServiceDiscovery() bleCallbacks.startServiceDiscovery()
val discover = gatt.discoverServices() val discover = gatt.discoverServices()
if (!discover) { if (!discover) {
throw ConnectException("Could not start discovering services`") throw ConnectException("Could not start discovering services`")
} }
bleCallbacks.waitForServiceDiscovery(DISCOVER_SERVICES_TIMEOUT_MS) connectionWaitCond.timeoutMs?.let {
bleCallbacks.waitForServiceDiscovery(it)
}
connectionWaitCond.stopConnection?.let {
while (!bleCallbacks.waitForConnection(STOP_CONNECTING_CHECK_INTERVAL_MS)) {
if (it.count == 0L) {
throw ConnectException("stopConnecting called")
}
}
}
logger.debug(LTag.PUMPBTCOMM, "Services discovered") logger.debug(LTag.PUMPBTCOMM, "Services discovered")
val service = gatt.getService(SERVICE_UUID.toUuid()) val service = gatt.getService(SERVICE_UUID.toUuid())
?: throw ConnectException("Service not found: $SERVICE_UUID") ?: throw ConnectException("Service not found: $SERVICE_UUID")
@ -34,11 +45,10 @@ class ServiceDiscoverer(
?: throw ConnectException("Characteristic not found: ${CharacteristicType.CMD.value}") ?: throw ConnectException("Characteristic not found: ${CharacteristicType.CMD.value}")
val dataChar = service.getCharacteristic(CharacteristicType.DATA.uuid) val dataChar = service.getCharacteristic(CharacteristicType.DATA.uuid)
?: throw ConnectException("Characteristic not found: ${CharacteristicType.DATA.value}") ?: throw ConnectException("Characteristic not found: ${CharacteristicType.DATA.value}")
var chars = mapOf( return mapOf(
CharacteristicType.CMD to cmdChar, CharacteristicType.CMD to cmdChar,
CharacteristicType.DATA to dataChar CharacteristicType.DATA to dataChar
) )
return chars
} }
private fun String.toUuid(): UUID = UUID( private fun String.toUuid(): UUID = UUID(
@ -49,6 +59,5 @@ class ServiceDiscoverer(
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
} }
} }

View file

@ -66,9 +66,9 @@ class BleCommCallbacks(
serviceDiscoveryComplete = CountDownLatch(1) serviceDiscoveryComplete = CountDownLatch(1)
} }
fun waitForServiceDiscovery(timeoutMs: Int) { fun waitForServiceDiscovery(timeoutMs: Long) {
try { try {
serviceDiscoveryComplete.await(timeoutMs.toLong(), TimeUnit.MILLISECONDS) serviceDiscoveryComplete.await(timeoutMs, TimeUnit.MILLISECONDS)
} catch (e: InterruptedException) { } catch (e: InterruptedException) {
aapsLogger.warn(LTag.PUMPBTCOMM, "Interrupted while waiting for ServiceDiscovery") aapsLogger.warn(LTag.PUMPBTCOMM, "Interrupted while waiting for ServiceDiscovery")
} }

View file

@ -5,6 +5,7 @@ import android.bluetooth.BluetoothGatt
import android.bluetooth.BluetoothManager import android.bluetooth.BluetoothManager
import android.bluetooth.BluetoothProfile import android.bluetooth.BluetoothProfile
import android.content.Context import android.content.Context
import android.os.SystemClock
import info.nightscout.androidaps.extensions.toHex import info.nightscout.androidaps.extensions.toHex
import info.nightscout.androidaps.logging.AAPSLogger import info.nightscout.androidaps.logging.AAPSLogger
import info.nightscout.androidaps.logging.LTag import info.nightscout.androidaps.logging.LTag
@ -23,6 +24,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.OmnipodDashPodStateManager
import java.lang.IllegalArgumentException import java.lang.IllegalArgumentException
import java.util.concurrent.CountDownLatch import java.util.concurrent.CountDownLatch
import kotlin.math.absoluteValue
sealed class ConnectionState sealed class ConnectionState
@ -31,7 +33,7 @@ object Handshaking: ConnectionState()
object Connected : ConnectionState() object Connected : ConnectionState()
object NotConnected : ConnectionState() object NotConnected : ConnectionState()
data class ConnectionWaitCondition(val timeoutMs: Long?=null, val stopConnection: CountDownLatch?=null) { data class ConnectionWaitCondition(var timeoutMs: Long?=null, val stopConnection: CountDownLatch?=null) {
init { init {
if (timeoutMs == null && stopConnection == null) { if (timeoutMs == null && stopConnection == null) {
throw IllegalArgumentException("One of timeoutMs or stopConnection has to be non null") throw IllegalArgumentException("One of timeoutMs or stopConnection has to be non null")
@ -73,14 +75,24 @@ class Connection(
if (!gatt.connect()) { if (!gatt.connect()) {
throw FailedToConnectException("connect() returned false") throw FailedToConnectException("connect() returned false")
} }
val before = SystemClock.elapsedRealtime()
if (waitForConnection(connectionWaitCond) !is Connected) { if (waitForConnection(connectionWaitCond) !is Connected) {
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
throw FailedToConnectException(podDevice.address) throw FailedToConnectException(podDevice.address)
} }
val waitedMs = SystemClock.elapsedRealtime() - before
val timeoutMs = connectionWaitCond.timeoutMs
if (timeoutMs != null) {
var newTimeout = timeoutMs - waitedMs
if (newTimeout < MIN_DISCOVERY_TIMEOUT_MS) {
newTimeout = MIN_DISCOVERY_TIMEOUT_MS
}
connectionWaitCond.timeoutMs = newTimeout
}
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.CONNECTED
val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks) val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks)
val discovered = discoverer.discoverServices() val discovered = discoverer.discoverServices(connectionWaitCond)
val cmdBleIO = CmdBleIO( val cmdBleIO = CmdBleIO(
aapsLogger, aapsLogger,
discovered[CharacteristicType.CMD]!!, discovered[CharacteristicType.CMD]!!,
@ -121,9 +133,9 @@ class Connection(
bleCommCallbacks.waitForConnection(it) bleCommCallbacks.waitForConnection(it)
} }
connectionWaitCond.stopConnection?.let { connectionWaitCond.stopConnection?.let {
while (!bleCommCallbacks.waitForConnection(300)) { while (!bleCommCallbacks.waitForConnection(STOP_CONNECTING_CHECK_INTERVAL_MS)) {
if (it.count == 0L) { if (it.count == 0L) {
return NotConnected ConnectException("stopConnecting called")
} }
} }
} }
@ -180,5 +192,7 @@ class Connection(
companion object { companion object {
const val BASE_CONNECT_TIMEOUT_MS = 10000L const val BASE_CONNECT_TIMEOUT_MS = 10000L
const val MIN_DISCOVERY_TIMEOUT_MS = 10000L
const val STOP_CONNECTING_CHECK_INTERVAL_MS = 500L
} }
} }