Open Lightwood13 opened 4 months ago
I'll have a look, thank you for creating the issue.
@philips77 Have you had a chance to check this topic? I have similar problem, if writeCharacteristic
is called after disconnect
, none of the done
,fail
or invalid
callbacks are called, what's more, the syncLock
underneath is never released, blocking the thread indefinitely.
I didn't have time, sorry.
Hi guys, @Lightwood13 , @dees91 , have you found any solution for this issue?
@32penkin I'm using a workaround like this
suspend fun writeCharacteristic(
characteristic: BluetoothGattCharacteristic,
data: ByteArray,
timeout: Duration
): Unit = withTimeoutOrNull(timeout) {
suspendCancellableCoroutine { continuation ->
writeCharacteristic(
characteristic,
data,
WRITE_TYPE_DEFAULT
)
.done {
if (!continuation.isCancelled) {
continuation.resume(Unit)
}
}
.fail { _, status ->
if (!continuation.isCancelled) {
continuation.resumeWithException(
BLERequestException("Write request failed with status $status")
)
}
}
.enqueue()
}
} ?: throw BLERequestException("Write request timed out")
class BLERequestException(message: String?) : Exception(message)
Here, instead of using library's .suspend()
method of WriteRequest
, that isn't cancellable, I'm manually suspending execution with suspendCancellableCoroutine
and then call .enqueue()
inside. If the write request doesn't succeed or fail within given timeout, the withTimeoutOrNull
function will cancel the block inside it and return null, so we can handle this case. This method doesn't address the issue with lost resources and the thread that gets blocked indefinitely if request doesn't finish as @dees91 mentioned, but at least it allows to safely use writeCharacteristic
from your code without it hanging.
Hi, I think I found a bug in
writeCharacteristic
method. If BLE device disconnects right before the call to writeCharacteristic, then it never returns success or failure.Example to reproduce:
This example prints in the logs
Disconnect request successful
, but write request neither succeeds nor fails. I've also noticed the same behavior when BLE device disconnects because of poor signal and the code is trying to write characteristic at the same time.When
writeCharacteristic
is used from kotlin with.suspend()
like this:it just hangs, never returning or throwing anything. Also, because
WriteRequest
is not cancellable when suspended, this coroutine can't be cancelled, so wrapping it inwithTimeout
doesn't help.