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.exceptions.ConnectException
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.util.*
@ -19,14 +21,23 @@ class ServiceDiscoverer(
/***
* 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")
bleCallbacks.startServiceDiscovery()
val discover = gatt.discoverServices()
if (!discover) {
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")
val service = gatt.getService(SERVICE_UUID.toUuid())
?: throw ConnectException("Service not found: $SERVICE_UUID")
@ -34,11 +45,10 @@ class ServiceDiscoverer(
?: throw ConnectException("Characteristic not found: ${CharacteristicType.CMD.value}")
val dataChar = service.getCharacteristic(CharacteristicType.DATA.uuid)
?: throw ConnectException("Characteristic not found: ${CharacteristicType.DATA.value}")
var chars = mapOf(
return mapOf(
CharacteristicType.CMD to cmdChar,
CharacteristicType.DATA to dataChar
)
return chars
}
private fun String.toUuid(): UUID = UUID(
@ -49,6 +59,5 @@ class ServiceDiscoverer(
companion object {
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)
}
fun waitForServiceDiscovery(timeoutMs: Int) {
fun waitForServiceDiscovery(timeoutMs: Long) {
try {
serviceDiscoveryComplete.await(timeoutMs.toLong(), TimeUnit.MILLISECONDS)
serviceDiscoveryComplete.await(timeoutMs, TimeUnit.MILLISECONDS)
} catch (e: InterruptedException) {
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.BluetoothProfile
import android.content.Context
import android.os.SystemClock
import info.nightscout.androidaps.extensions.toHex
import info.nightscout.androidaps.logging.AAPSLogger
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 java.lang.IllegalArgumentException
import java.util.concurrent.CountDownLatch
import kotlin.math.absoluteValue
sealed class ConnectionState
@ -31,7 +33,7 @@ object Handshaking: ConnectionState()
object Connected : 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 {
if (timeoutMs == null && stopConnection == null) {
throw IllegalArgumentException("One of timeoutMs or stopConnection has to be non null")
@ -73,14 +75,24 @@ class Connection(
if (!gatt.connect()) {
throw FailedToConnectException("connect() returned false")
}
val before = SystemClock.elapsedRealtime()
if (waitForConnection(connectionWaitCond) !is Connected) {
podState.bluetoothConnectionState = OmnipodDashPodStateManager.BluetoothConnectionState.DISCONNECTED
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
val discoverer = ServiceDiscoverer(aapsLogger, gatt, bleCommCallbacks)
val discovered = discoverer.discoverServices()
val discovered = discoverer.discoverServices(connectionWaitCond)
val cmdBleIO = CmdBleIO(
aapsLogger,
discovered[CharacteristicType.CMD]!!,
@ -121,9 +133,9 @@ class Connection(
bleCommCallbacks.waitForConnection(it)
}
connectionWaitCond.stopConnection?.let {
while (!bleCommCallbacks.waitForConnection(300)) {
while (!bleCommCallbacks.waitForConnection(STOP_CONNECTING_CHECK_INTERVAL_MS)) {
if (it.count == 0L) {
return NotConnected
ConnectException("stopConnecting called")
}
}
}
@ -180,5 +192,7 @@ class Connection(
companion object {
const val BASE_CONNECT_TIMEOUT_MS = 10000L
const val MIN_DISCOVERY_TIMEOUT_MS = 10000L
const val STOP_CONNECTING_CHECK_INTERVAL_MS = 500L
}
}