Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import com.juul.kable.logs.Logging.DataProcessor.Operation.Write
import com.juul.kable.logs.detail
import kotlinx.coroutines.CancellationException
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.TimeoutCancellationException
import kotlinx.coroutines.cancel
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
Expand All @@ -28,6 +29,7 @@ import kotlinx.coroutines.flow.onEach
import kotlinx.coroutines.flow.onSubscription
import kotlinx.coroutines.flow.updateAndGet
import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withTimeout
import kotlinx.io.IOException
import platform.CoreBluetooth.CBCharacteristicWriteWithResponse
import platform.CoreBluetooth.CBCharacteristicWriteWithoutResponse
Expand All @@ -46,6 +48,7 @@ import platform.Foundation.NSUTF8StringEncoding
import platform.Foundation.dataUsingEncoding
import platform.darwin.UInt16
import kotlin.time.Duration
import kotlin.time.Duration.Companion.milliseconds
import platform.CoreBluetooth.CBCharacteristicWriteWithResponse as CBWithResponse
import platform.CoreBluetooth.CBCharacteristicWriteWithoutResponse as CBWithoutResponse

Expand All @@ -58,6 +61,8 @@ internal class CBPeripheralCoreBluetoothPeripheral(
private val forceCharacteristicEqualityByUuid: Boolean,
) : BasePeripheral(cbPeripheral.identifier.toUuid()), CoreBluetoothPeripheral {

private val writeWithoutResponseTimeout = 30.milliseconds
Comment thread
LuoPeiQin marked this conversation as resolved.
Outdated

private val central = CentralManager.Default

override val identifier: Identifier = cbPeripheral.identifier.toUuid()
Expand Down Expand Up @@ -213,7 +218,15 @@ internal class CBPeripheralCoreBluetoothPeripheral(
}
WithoutResponse -> connectionOrThrow().guard.withLock {
if (!canSendWriteWithoutResponse.updateAndGet { cbPeripheral.canSendWriteWithoutResponse }) {
canSendWriteWithoutResponse.first { it }
try {
withTimeout(writeWithoutResponseTimeout) {
canSendWriteWithoutResponse.first { it }
}
} catch (e: TimeoutCancellationException) {
logger.warn {
message = "Timed out waiting for canSendWriteWithoutResponse, proceeding with write attempt"
}
}
}
central.writeValue(cbPeripheral, data, platformCharacteristic, CBWithoutResponse)
}
Expand Down
1 change: 1 addition & 0 deletions kable-core/src/appleMain/kotlin/PeripheralDelegate.kt
Original file line number Diff line number Diff line change
Expand Up @@ -323,6 +323,7 @@ internal class PeripheralDelegate(
fun close(cause: Throwable?) {
_response.close(NotConnectedException(cause = cause))
characteristicChanges.emitBlocking(ObservationEvent.Disconnected)
canSendWriteWithoutResponse.value = true
}
}

Expand Down
Loading