Skip to content

Commit

Permalink
Promote identifier to property on Peripheral interface (#509)
Browse files Browse the repository at this point in the history
  • Loading branch information
twyatt authored Jun 26, 2023
1 parent 55a6b7d commit 9fe4bb8
Show file tree
Hide file tree
Showing 8 changed files with 40 additions and 30 deletions.
2 changes: 1 addition & 1 deletion core/api/core.api
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ public final class com/juul/kable/OutOfOrderGattCallbackException : java/lang/Il
public abstract interface class com/juul/kable/Peripheral {
public abstract fun connect (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun disconnect (Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
public abstract fun getIdentifier ()Ljava/lang/String;
public abstract fun getName ()Ljava/lang/String;
public abstract fun getServices ()Ljava/util/List;
public abstract fun getState ()Lkotlinx/coroutines/flow/StateFlow;
Expand Down Expand Up @@ -292,7 +293,6 @@ public final class com/juul/kable/PeripheralBuilder {
}

public final class com/juul/kable/PeripheralKt {
public static final fun getIdentifier (Lcom/juul/kable/Peripheral;)Ljava/lang/String;
public static final fun peripheral (Lkotlinx/coroutines/CoroutineScope;Landroid/bluetooth/BluetoothDevice;Lkotlin/jvm/functions/Function1;)Lcom/juul/kable/Peripheral;
public static final fun peripheral (Lkotlinx/coroutines/CoroutineScope;Lcom/juul/kable/Advertisement;Lkotlin/jvm/functions/Function1;)Lcom/juul/kable/Peripheral;
public static final fun peripheral (Lkotlinx/coroutines/CoroutineScope;Ljava/lang/String;Lkotlin/jvm/functions/Function1;)Lcom/juul/kable/Peripheral;
Expand Down
7 changes: 2 additions & 5 deletions core/src/androidMain/kotlin/Peripheral.kt
Original file line number Diff line number Diff line change
Expand Up @@ -103,11 +103,11 @@ internal class BluetoothDeviceAndroidPeripheral(

private val logger = Logger(logging, tag = "Kable/Peripheral", identifier = bluetoothDevice.address)

internal val platformIdentifier = bluetoothDevice.address

private val _state = MutableStateFlow<State>(State.Disconnected())
override val state: StateFlow<State> = _state.asStateFlow()

override val identifier: String = bluetoothDevice.address

private val job = SupervisorJob(parentCoroutineContext[Job]).apply {
invokeOnCompletion {
closeConnection()
Expand Down Expand Up @@ -463,9 +463,6 @@ private fun checkBluetoothAdapterState(

public actual typealias Identifier = String

public actual val Peripheral.identifier: Identifier
get() = (this as BluetoothDeviceAndroidPeripheral).platformIdentifier

public actual fun String.toIdentifier(): Identifier {
require(BluetoothAdapter.checkBluetoothAddress(this)) {
"MAC Address has invalid format: $this"
Expand Down
3 changes: 0 additions & 3 deletions core/src/appleMain/kotlin/Identifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,4 @@ import com.benasher44.uuid.uuidFrom

public actual typealias Identifier = Uuid

public actual val Peripheral.identifier: Identifier
get() = (this as CBPeripheralCoreBluetoothPeripheral).platformIdentifier.toUuid()

public actual fun String.toIdentifier(): Identifier = uuidFrom(this)
4 changes: 2 additions & 2 deletions core/src/appleMain/kotlin/Peripheral.kt
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ internal class CBPeripheralCoreBluetoothPeripheral(
private val _state = MutableStateFlow<State>(State.Disconnected())
override val state: StateFlow<State> = _state.asStateFlow()

private val observers = Observers<NSData>(this, logging, exceptionHandler = observationExceptionHandler)
override val identifier: Uuid = cbPeripheral.identifier.toUuid()

internal val platformIdentifier = cbPeripheral.identifier
private val observers = Observers<NSData>(this, logging, exceptionHandler = observationExceptionHandler)

init {
centralManager.delegate
Expand Down
11 changes: 0 additions & 11 deletions core/src/commonMain/kotlin/Identifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,4 @@ package com.juul.kable

public expect class Identifier

/**
* The identifier of the remote device
*
* This identifier is the identifier returned by the operating system for the address of the device.
* The value of the identifier will differ between operating system implementations. On iOS
* the identifier is a UUID. On Android the identifier is a MAC address. For security reasons
* the identifier is not a MAC address on iOS and may be a randomized MAC on Android. The identifier
* may also change.
*/
public expect val Peripheral.identifier: Identifier

public expect fun String.toIdentifier(): Identifier
32 changes: 32 additions & 0 deletions core/src/commonMain/kotlin/Peripheral.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

package com.juul.kable

import com.benasher44.uuid.Uuid
import com.juul.kable.WriteType.WithoutResponse
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.flow.Flow
Expand Down Expand Up @@ -61,6 +62,37 @@ public interface Peripheral {
*/
public val state: StateFlow<State>

/**
* Platform specific identifier for the remote peripheral. On some platforms, this can be used
* to "restore" a previously known peripheral for reconnection.
*
* On Android, this is a MAC address represented as a [String]. A [Peripheral] can be created
* from this MAC address using the `CoroutineScope.peripheral(String, PeripheralBuilderAction)`
* function unless the peripheral makes "use of a Bluetooth Smart feature known as 'LE Privacy'"
* (whereas the peripheral may provide a random MAC address, see
* [Bluetooth Technology Protecting Your Privacy](https://www.bluetooth.com/blog/bluetooth-technology-protecting-your-privacy/)
* for more details)).
*
* On Apple, this is a unique identifier represented as a [Uuid]. A [Peripheral] can be created
* from this identifier using the `CoroutineScope.peripheral(Uuid, PeripheralBuilderAction)`
* function. According to
* [The Ultimate Guide to Apple’s Core Bluetooth](https://punchthrough.com/core-bluetooth-basics/):
*
* > This UUID isn't guaranteed to stay the same across scanning sessions and should not be 100%
* > relied upon for peripheral re-identification. That said, we have observed it to be
* > relatively stable and reliable over the long term assuming a major device settings reset
* > has not occurred.
*
* If `CoroutineScope.peripheral(Uuid, PeripheralBuilderAction)` throws a
* [NoSuchElementException] then a scan will be necessary to obtain an [Advertisement] for
* [Peripheral] creation.
*
* On JavaScript, this is a unique identifier represented as a [String]. "Restoring" a
* peripheral from this identifier is not yet supported in Kable (as JavaScript requires user to
* [explicitly enable this feature](https://developer.mozilla.org/en-US/docs/Web/API/Bluetooth/getDevices)).
*/
public val identifier: Identifier

/**
* The peripheral name, as provided by the underlying bluetooth system. This value is system dependent
* and is not necessarily the Generic Access Profile (GAP) device name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,11 @@ internal class BluetoothDeviceWebBluetoothPeripheral(

private val ioLock = Mutex()

internal val platformIdentifier = bluetoothDevice.id

private val _state = MutableStateFlow<State>(State.Disconnected())
override val state: StateFlow<State> = _state.asStateFlow()

override val identifier: String = bluetoothDevice.id

private var _discoveredServices: List<DiscoveredService>? = null
private val discoveredServices: List<DiscoveredService>
get() = _discoveredServices
Expand Down
7 changes: 1 addition & 6 deletions core/src/jsMain/kotlin/Identifier.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,4 @@ package com.juul.kable

public actual typealias Identifier = String

public actual val Peripheral.identifier: Identifier
get() = (this as BluetoothDeviceWebBluetoothPeripheral).platformIdentifier

public actual fun String.toIdentifier(): Identifier {
return this
}
public actual fun String.toIdentifier(): Identifier = this

0 comments on commit 9fe4bb8

Please sign in to comment.