diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt index 664db805e0..1d1e24ba42 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/ServiceDiscoverer.kt @@ -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 { + fun discoverServices(connectionWaitCond: ConnectionWaitCondition): Map { 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 } } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt index 471467235d..2a668065f0 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/callbacks/BleCommCallbacks.kt @@ -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") } diff --git a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt index 3ea2fc44e1..d86fc8cbc0 100644 --- a/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt +++ b/omnipod-dash/src/main/java/info/nightscout/androidaps/plugins/pump/omnipod/dash/driver/comm/session/Connection.kt @@ -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 } }