add BusyException

This commit is contained in:
Andrei Vereha 2021-03-28 23:09:44 +02:00
parent 8d2d38163a
commit 38a1d9c6bc
7 changed files with 52 additions and 33 deletions

View file

@ -19,6 +19,7 @@ import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.pod.state.Omn
import info.nightscout.androidaps.utils.extensions.toHex import info.nightscout.androidaps.utils.extensions.toHex
import io.reactivex.Observable import io.reactivex.Observable
import java.util.concurrent.TimeoutException import java.util.concurrent.TimeoutException
import java.util.concurrent.atomic.AtomicBoolean
import javax.inject.Inject import javax.inject.Inject
import javax.inject.Singleton import javax.inject.Singleton
@ -28,8 +29,7 @@ class OmnipodDashBleManagerImpl @Inject constructor(
private val aapsLogger: AAPSLogger, private val aapsLogger: AAPSLogger,
private val podState: OmnipodDashPodStateManager private val podState: OmnipodDashPodStateManager
) : OmnipodDashBleManager { ) : OmnipodDashBleManager {
private val busy = AtomicBoolean(false);
// TODO: add busy AtomicBoolean
private val bluetoothManager: BluetoothManager = private val bluetoothManager: BluetoothManager =
context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager context.getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter private val bluetoothAdapter: BluetoothAdapter = bluetoothManager.adapter
@ -41,38 +41,47 @@ class OmnipodDashBleManagerImpl @Inject constructor(
?: myId.increment() // pod not activated ?: myId.increment() // pod not activated
override fun sendCommand(cmd: Command): Observable<PodEvent> = Observable.create { emitter -> override fun sendCommand(cmd: Command): Observable<PodEvent> = Observable.create { emitter ->
val conn = connection ?: throw NotConnectedException("Not connected") if (!busy.compareAndSet(false, true)) {
throw BusyException()
val session = conn.session ?: throw NotConnectedException("Missing session")
emitter.onNext(PodEvent.CommandSending(cmd))
val sendResult = session.sendCommand(cmd)
when(sendResult) {
is CommandSendErrorSending -> {
emitter.tryOnError(CouldNotSendCommandException())
return@create
}
is CommandSendSuccess ->
emitter.onNext(PodEvent.CommandSent(cmd))
is CommandSendErrorConfirming ->
emitter.onNext(PodEvent.CommandSendNotConfirmed(cmd))
} }
try {
val conn = connection ?: throw NotConnectedException("Not connected")
val readResult = session.readAndAckCommandResponse() val session = conn.session ?: throw NotConnectedException("Missing session")
when (readResult){
is CommandReceiveSuccess ->
emitter.onNext(PodEvent.ResponseReceived(readResult.result))
is CommandAckError -> emitter.onNext(PodEvent.CommandSending(cmd))
emitter.onNext(PodEvent.ResponseReceived(readResult.result))
is CommandReceiveError -> { when (session.sendCommand(cmd)) {
emitter.tryOnError(MessageIOException("Could not read response: $readResult")) is CommandSendErrorSending -> {
return@create emitter.tryOnError(CouldNotSendCommandException())
return@create
}
is CommandSendSuccess ->
emitter.onNext(PodEvent.CommandSent(cmd))
is CommandSendErrorConfirming ->
emitter.onNext(PodEvent.CommandSendNotConfirmed(cmd))
} }
when (val readResult = session.readAndAckCommandResponse()) {
is CommandReceiveSuccess ->
emitter.onNext(PodEvent.ResponseReceived(readResult.result))
is CommandAckError ->
emitter.onNext(PodEvent.ResponseReceived(readResult.result))
is CommandReceiveError -> {
emitter.tryOnError(MessageIOException("Could not read response: $readResult"))
return@create
}
}
emitter.onComplete()
} catch (ex: Exception) {
disconnect()
emitter.tryOnError(ex)
} finally {
busy.set(false)
} }
emitter.onComplete()
} }
override fun getStatus(): ConnectionStatus { override fun getStatus(): ConnectionStatus {
@ -84,6 +93,9 @@ class OmnipodDashBleManagerImpl @Inject constructor(
} }
override fun connect(): Observable<PodEvent> = Observable.create { emitter -> override fun connect(): Observable<PodEvent> = Observable.create { emitter ->
if (!busy.compareAndSet(false, true)) {
throw BusyException()
}
try { try {
emitter.onNext(PodEvent.BluetoothConnecting) emitter.onNext(PodEvent.BluetoothConnecting)
@ -110,6 +122,8 @@ class OmnipodDashBleManagerImpl @Inject constructor(
} catch (ex: Exception) { } catch (ex: Exception) {
disconnect() disconnect()
emitter.tryOnError(ex) emitter.tryOnError(ex)
} finally {
busy.set(false)
} }
} }
@ -126,6 +140,9 @@ class OmnipodDashBleManagerImpl @Inject constructor(
} }
override fun pairNewPod(): Observable<PodEvent> = Observable.create { emitter -> override fun pairNewPod(): Observable<PodEvent> = Observable.create { emitter ->
if (!busy.compareAndSet(false, true)) {
throw BusyException()
}
try { try {
if (podState.ltk != null) { if (podState.ltk != null) {
@ -170,6 +187,8 @@ class OmnipodDashBleManagerImpl @Inject constructor(
} catch (ex: Exception) { } catch (ex: Exception) {
disconnect() disconnect()
emitter.tryOnError(ex) emitter.tryOnError(ex)
} finally {
busy.set(false)
} }
} }

View file

@ -46,7 +46,6 @@ class BleCommCallbacks(
connected.await(timeoutMs.toLong(), TimeUnit.MILLISECONDS) connected.await(timeoutMs.toLong(), TimeUnit.MILLISECONDS)
} catch (e: InterruptedException) { } catch (e: InterruptedException) {
aapsLogger.warn(LTag.PUMPBTCOMM,"Interrupted while waiting for Connection") aapsLogger.warn(LTag.PUMPBTCOMM,"Interrupted while waiting for Connection")
} }
} }

View file

@ -12,7 +12,6 @@ enum class BleCommandType(val value: Byte) {
companion object { companion object {
@JvmStatic
fun byValue(value: Byte): BleCommandType = fun byValue(value: Byte): BleCommandType =
values().firstOrNull { it.value == value } values().firstOrNull { it.value == value }
?: throw IllegalArgumentException("Unknown BleCommandType: $value") ?: throw IllegalArgumentException("Unknown BleCommandType: $value")

View file

@ -0,0 +1,3 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.exceptions
class BusyException(): Exception("Bluetooth busy")

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.io package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.CrcMismatchException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.CrcMismatchException
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.IncorrectPacketException import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message.IncorrectPacketException

View file

@ -1,4 +1,4 @@
package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.message package info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.BlePacket import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.BlePacket
import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.FirstBlePacket import info.nightscout.androidaps.plugins.pump.omnipod.dash.driver.comm.packet.FirstBlePacket

View file

@ -35,7 +35,6 @@ class BleDiscoveredDevice(val scanResult: ScanResult, private val scanRecord: Sc
} }
@Throws(DiscoveredInvalidPodException::class) @Throws(DiscoveredInvalidPodException::class)
private fun validatePodId() { private fun validatePodId() {
val serviceUUIDs = scanRecord.serviceUuids val serviceUUIDs = scanRecord.serviceUuids
val hexPodId = extractUUID16(serviceUUIDs[3]) + extractUUID16(serviceUUIDs[4]) val hexPodId = extractUUID16(serviceUUIDs[3]) + extractUUID16(serviceUUIDs[4])