@@ -15,6 +15,7 @@ import com.juul.kable.logs.Logging.DataProcessor.Operation.Write
1515import com.juul.kable.logs.detail
1616import kotlinx.coroutines.CancellationException
1717import kotlinx.coroutines.CoroutineScope
18+ import kotlinx.coroutines.TimeoutCancellationException
1819import kotlinx.coroutines.cancel
1920import kotlinx.coroutines.flow.Flow
2021import kotlinx.coroutines.flow.MutableStateFlow
@@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.onEach
2829import kotlinx.coroutines.flow.onSubscription
2930import kotlinx.coroutines.flow.updateAndGet
3031import kotlinx.coroutines.sync.withLock
32+ import kotlinx.coroutines.withTimeout
3133import kotlinx.io.IOException
3234import platform.CoreBluetooth.CBCharacteristicWriteWithResponse
3335import platform.CoreBluetooth.CBCharacteristicWriteWithoutResponse
@@ -56,6 +58,7 @@ internal class CBPeripheralCoreBluetoothPeripheral(
5658 private val logging : Logging ,
5759 private val disconnectTimeout : Duration ,
5860 private val forceCharacteristicEqualityByUuid : Boolean ,
61+ private val writeWithoutResponseTimeout : Duration ,
5962) : BasePeripheral(cbPeripheral.identifier.toUuid()), CoreBluetoothPeripheral {
6063
6164 private val central = CentralManager .Default
@@ -213,7 +216,15 @@ internal class CBPeripheralCoreBluetoothPeripheral(
213216 }
214217 WithoutResponse -> connectionOrThrow().guard.withLock {
215218 if (! canSendWriteWithoutResponse.updateAndGet { cbPeripheral.canSendWriteWithoutResponse }) {
216- canSendWriteWithoutResponse.first { it }
219+ try {
220+ withTimeout(writeWithoutResponseTimeout) {
221+ canSendWriteWithoutResponse.first { it }
222+ }
223+ } catch (e: TimeoutCancellationException ) {
224+ logger.warn {
225+ message = " Timed out waiting for canSendWriteWithoutResponse, proceeding with write attempt"
226+ }
227+ }
217228 }
218229 central.writeValue(cbPeripheral, data, platformCharacteristic, CBWithoutResponse )
219230 }
0 commit comments