@@ -28,7 +28,6 @@ import kotlinx.atomicfu.atomic
2828import kotlinx.atomicfu.updateAndGet
2929import kotlinx.coroutines.CoroutineName
3030import kotlinx.coroutines.CoroutineScope
31- import kotlinx.coroutines.Job
3231import kotlinx.coroutines.NonCancellable
3332import kotlinx.coroutines.SupervisorJob
3433import kotlinx.coroutines.flow.Flow
@@ -42,6 +41,7 @@ import kotlinx.coroutines.flow.map
4241import kotlinx.coroutines.flow.onEach
4342import kotlinx.coroutines.flow.onSubscription
4443import kotlinx.coroutines.flow.updateAndGet
44+ import kotlinx.coroutines.isActive
4545import kotlinx.coroutines.job
4646import kotlinx.coroutines.sync.withLock
4747import kotlinx.coroutines.withContext
@@ -109,9 +109,11 @@ internal class CBPeripheralCoreBluetoothPeripheral(
109109 private val logging : Logging ,
110110) : CoreBluetoothPeripheral {
111111
112- private val job = SupervisorJob (parentCoroutineContext.job) // todo: Disconnect/dispose CBPeripheral on completion?
113- private val scope = CoroutineScope (parentCoroutineContext + job + CoroutineName (" Kable/Peripheral@${cbPeripheral.identifier.UUIDString } " ))
114- internal val connectionScope = CoroutineScope (scope.coroutineContext + Job (scope.coroutineContext[Job ]) + CoroutineName (" Kable/Connect@${cbPeripheral.identifier.UUIDString } " ))
112+ private val scope = CoroutineScope (
113+ parentCoroutineContext +
114+ SupervisorJob (parentCoroutineContext.job) +
115+ CoroutineName (" Kable/Peripheral/${cbPeripheral.identifier.UUIDString } " ),
116+ )
115117
116118 private val centralManager: CentralManager = CentralManager .Default
117119
@@ -160,18 +162,11 @@ internal class CBPeripheralCoreBluetoothPeripheral(
160162
161163 private val _connection = atomic<Connection ?>(null )
162164 private val connection: Connection
163- inline get() = _connection .value ? : throw NotReadyException (toString())
165+ inline get() = _connection .value?. takeIf { it.scope.isActive } ? : throw NotReadyException (toString())
164166
165167 override val name: String? get() = cbPeripheral.name
166168
167- private val connectAction = connectionScope.sharedRepeatableAction(::establishConnection)
168-
169- private fun onDisconnected () {
170- logger.info { message = " Disconnected" }
171- connectAction.reset()
172- _connection .value?.close()
173- _connection .value = null
174- }
169+ private val connectAction = scope.sharedRepeatableAction(::establishConnection)
175170
176171 override suspend fun connect () {
177172 connectAction.await()
@@ -185,11 +180,15 @@ internal class CBPeripheralCoreBluetoothPeripheral(
185180 _state .value = State .Connecting .Bluetooth
186181
187182 centralManager.delegate.onDisconnected.onEach { identifier ->
188- if (identifier == cbPeripheral.identifier) onDisconnected()
183+ if (identifier == cbPeripheral.identifier) {
184+ connectAction.reset()
185+ logger.info { message = " Disconnected" }
186+ }
189187 }.launchIn(scope)
190188
191189 try {
192190 _connection .value = centralManager.connectPeripheral(
191+ scope,
193192 this @CBPeripheralCoreBluetoothPeripheral,
194193 observers.characteristicChanges,
195194 logging,
@@ -208,7 +207,6 @@ internal class CBPeripheralCoreBluetoothPeripheral(
208207 logger.error(e) { message = " Failed to connect" }
209208 withContext(NonCancellable ) {
210209 centralManager.cancelPeripheralConnection(cbPeripheral)
211- _connection .value = null
212210 }
213211 throw e
214212 }
@@ -224,7 +222,7 @@ internal class CBPeripheralCoreBluetoothPeripheral(
224222 withContext(NonCancellable ) {
225223 centralManager.cancelPeripheralConnection(cbPeripheral)
226224 }
227- onDisconnected()
225+ logger.info { message = " Disconnected " }
228226 }
229227 }
230228
0 commit comments