Skip to content

Commit 1fce4e2

Browse files
authored
Add maximumWriteValueLength to Peripheral (#809)
1 parent 64f054e commit 1fce4e2

6 files changed

Lines changed: 32 additions & 0 deletions

File tree

kable-core/api/android/kable-core.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ public abstract interface class com/juul/kable/Peripheral : kotlinx/coroutines/C
319319
public abstract fun getName ()Ljava/lang/String;
320320
public abstract fun getServices ()Lkotlinx/coroutines/flow/StateFlow;
321321
public abstract fun getState ()Lkotlinx/coroutines/flow/StateFlow;
322+
public abstract fun maximumWriteValueLengthForType (Lcom/juul/kable/WriteType;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
322323
public abstract fun observe (Lcom/juul/kable/Characteristic;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
323324
public abstract fun read (Lcom/juul/kable/Characteristic;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
324325
public abstract fun read (Lcom/juul/kable/Descriptor;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;

kable-core/api/jvm/kable-core.api

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ public abstract interface class com/juul/kable/Peripheral : kotlinx/coroutines/C
235235
public abstract fun getName ()Ljava/lang/String;
236236
public abstract fun getServices ()Lkotlinx/coroutines/flow/StateFlow;
237237
public abstract fun getState ()Lkotlinx/coroutines/flow/StateFlow;
238+
public abstract fun maximumWriteValueLengthForType (Lcom/juul/kable/WriteType;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
238239
public abstract fun observe (Lcom/juul/kable/Characteristic;Lkotlin/jvm/functions/Function1;)Lkotlinx/coroutines/flow/Flow;
239240
public abstract fun read (Lcom/juul/kable/Characteristic;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
240241
public abstract fun read (Lcom/juul/kable/Descriptor;Lkotlin/coroutines/Continuation;)Ljava/lang/Object;

kable-core/src/androidMain/kotlin/BluetoothDeviceAndroidPeripheral.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ import kotlin.time.Duration
4747
// https://github.com/JuulLabs/kable/issues/295
4848
private const val DISCOVER_SERVICES_RETRIES = 5
4949

50+
private const val DEFAULT_ATT_MTU = 23
51+
private const val ATT_MTU_HEADER_SIZE = 3
52+
5053
internal class BluetoothDeviceAndroidPeripheral(
5154
private val bluetoothDevice: BluetoothDevice,
5255
private val autoConnectPredicate: () -> Boolean,
@@ -163,6 +166,9 @@ internal class BluetoothDeviceAndroidPeripheral(
163166
.requestConnectionPriority(priority.intValue)
164167
}
165168

169+
override suspend fun maximumWriteValueLengthForType(writeType: WriteType): Int =
170+
(mtu.value ?: DEFAULT_ATT_MTU) - ATT_MTU_HEADER_SIZE
171+
166172
@ExperimentalApi // Experimental until Web Bluetooth advertisements APIs are stable.
167173
override suspend fun rssi(): Int =
168174
connectionOrThrow().execute<OnReadRemoteRssi> {

kable-core/src/appleMain/kotlin/CBPeripheralCoreBluetoothPeripheral.kt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@ import kotlinx.coroutines.flow.onSubscription
2727
import kotlinx.coroutines.flow.updateAndGet
2828
import kotlinx.coroutines.sync.withLock
2929
import kotlinx.io.IOException
30+
import platform.CoreBluetooth.CBCharacteristicWriteWithResponse
31+
import platform.CoreBluetooth.CBCharacteristicWriteWithoutResponse
3032
import platform.CoreBluetooth.CBDescriptor
3133
import platform.CoreBluetooth.CBManagerState
3234
import platform.CoreBluetooth.CBManagerStatePoweredOn
@@ -144,6 +146,14 @@ internal class CBPeripheralCoreBluetoothPeripheral(
144146
)
145147
}
146148

149+
override suspend fun maximumWriteValueLengthForType(writeType: WriteType): Int {
150+
val type = when (writeType) {
151+
WithResponse -> CBCharacteristicWriteWithResponse
152+
WithoutResponse -> CBCharacteristicWriteWithoutResponse
153+
}
154+
return cbPeripheral.maximumWriteValueLengthForType(type).toInt()
155+
}
156+
147157
@ExperimentalApi // Experimental until Web Bluetooth advertisements APIs are stable.
148158
@Throws(CancellationException::class, IOException::class)
149159
override suspend fun rssi(): Int = connectionOrThrow().execute<DidReadRssi> {

kable-core/src/commonMain/kotlin/Peripheral.kt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,15 @@ public interface Peripheral : CoroutineScope {
153153
*/
154154
public val services: StateFlow<List<DiscoveredService>?>
155155

156+
/**
157+
* Return the current ATT MTU size, minus the size of the ATT headers (3 bytes).
158+
*
159+
* On Android, this will be the default (23 - 3) unless you called [requestMtu] when connecting.
160+
* For iOS, this is automatically negotiated, and can also vary depending on the writeType.
161+
* On JavaScript, this will return the default (23 - 3) every time as there is no ATT MTU property available.
162+
*/
163+
public suspend fun maximumWriteValueLengthForType(writeType: WriteType): Int
164+
156165
/**
157166
* On JavaScript, requires Chrome 79+ with the
158167
* `chrome://flags/#enable-experimental-web-platform-features` flag enabled.

kable-core/src/jsMain/kotlin/BluetoothDeviceWebBluetoothPeripheral.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,8 @@ import kotlin.coroutines.resumeWithException
3232
import kotlin.time.Duration
3333

3434
private const val ADVERTISEMENT_RECEIVED = "advertisementreceived"
35+
private const val DEFAULT_ATT_MTU = 23
36+
private const val ATT_MTU_HEADER_SIZE = 3
3537

3638
internal class BluetoothDeviceWebBluetoothPeripheral(
3739
private val bluetoothDevice: BluetoothDevice,
@@ -114,6 +116,9 @@ internal class BluetoothDeviceWebBluetoothPeripheral(
114116
)
115117
}
116118

119+
override suspend fun maximumWriteValueLengthForType(writeType: WriteType): Int =
120+
DEFAULT_ATT_MTU - ATT_MTU_HEADER_SIZE
121+
117122
/**
118123
* Per [Web Bluetooth / Scanning Sample][https://googlechrome.github.io/samples/web-bluetooth/scan.html]:
119124
*

0 commit comments

Comments
 (0)