Skip to content

Commit

Permalink
Use kotlin Uuid
Browse files Browse the repository at this point in the history
fixes #748
  • Loading branch information
ykws committed Sep 21, 2024
1 parent a337f22 commit f8b8761
Show file tree
Hide file tree
Showing 44 changed files with 177 additions and 80 deletions.
1 change: 0 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-t
kotlinx-io = { module = "org.jetbrains.kotlinx:kotlinx-io-core", version = "0.5.4" }
tuulbox-collections = { module = "com.juul.tuulbox:collections", version.ref = "tuulbox" }
tuulbox-coroutines = { module = "com.juul.tuulbox:coroutines", version.ref = "tuulbox" }
uuid = { module = "com.benasher44:uuid", version = "0.8.4" }
wrappers-bom = { module = "org.jetbrains.kotlin-wrappers:kotlin-wrappers-bom", version = "1.0.0-pre.810" }
wrappers-web = { module = "org.jetbrains.kotlin-wrappers:kotlin-web" }

Expand Down
1 change: 0 additions & 1 deletion kable-core/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ kotlin {
sourceSets {
commonMain.dependencies {
api(libs.kotlinx.coroutines.core)
api(libs.uuid)
api(project(":kable-exceptions"))
implementation(libs.datetime)
implementation(libs.tuulbox.collections)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable

import android.bluetooth.BluetoothAdapter.STATE_OFF
Expand All @@ -16,7 +18,6 @@ import android.bluetooth.BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE
import android.bluetooth.BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE
import android.bluetooth.BluetoothGattDescriptor.ENABLE_INDICATION_VALUE
import android.bluetooth.BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE
import com.benasher44.uuid.uuidFrom
import com.juul.kable.AndroidPeripheral.Priority
import com.juul.kable.AndroidPeripheral.Type
import com.juul.kable.State.Disconnected
Expand Down Expand Up @@ -51,8 +52,11 @@ import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.cancellation.CancellationException
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
import kotlin.uuid.toKotlinUuid

private val clientCharacteristicConfigUuid = uuidFrom(CLIENT_CHARACTERISTIC_CONFIG_UUID)
private val clientCharacteristicConfigUuid = Uuid.parse(CLIENT_CHARACTERISTIC_CONFIG_UUID)

// Number of service discovery attempts to make if no services are discovered.
// https://github.com/JuulLabs/kable/issues/295
Expand Down Expand Up @@ -424,7 +428,7 @@ private val Priority.intValue: Int
}

private val PlatformCharacteristic.configDescriptor: PlatformDescriptor?
get() = descriptors.firstOrNull { clientCharacteristicConfigUuid == it.uuid }
get() = descriptors.firstOrNull { clientCharacteristicConfigUuid == it.uuid.toKotlinUuid() }

private val PlatformCharacteristic.supportsNotify: Boolean
get() = properties and PROPERTY_NOTIFY != 0
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable

import android.bluetooth.le.ScanCallback
Expand All @@ -23,6 +25,8 @@ import kotlinx.coroutines.channels.trySendBlocking
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
import kotlinx.coroutines.flow.filter
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.toJavaUuid

internal class BluetoothLeScannerAndroidScanner(
private val filters: List<FilterPredicate>,
Expand Down Expand Up @@ -142,7 +146,7 @@ private fun FilterPredicate.toNativeScanFilter(): ScanFilter =
is Name.Exact -> setDeviceName(filter.exact)
is Address -> setDeviceAddress(filter.address)
is ManufacturerData -> setManufacturerData(filter.id, filter.data, filter.dataMask)
is Service -> setServiceUuid(ParcelUuid(filter.uuid))
is Service -> setServiceUuid(ParcelUuid(filter.uuid.toJavaUuid()))
else -> throw AssertionError("Unsupported filter element")
}
}
Expand Down
21 changes: 12 additions & 9 deletions kable-core/src/androidMain/kotlin/Profile.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
@file:JvmName("ProfileAndroid")
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable

import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattDescriptor
import android.bluetooth.BluetoothGattService
import com.benasher44.uuid.Uuid
import com.juul.kable.Characteristic.Properties
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
import kotlin.uuid.toKotlinUuid

@Suppress("ACTUAL_WITHOUT_EXPECT") // https://youtrack.jetbrains.com/issue/KT-37316
internal actual typealias PlatformService = BluetoothGattService
Expand All @@ -24,7 +27,7 @@ public actual data class DiscoveredService internal constructor(
public actual val characteristics: List<DiscoveredCharacteristic> =
service.characteristics.map(::DiscoveredCharacteristic)

actual override val serviceUuid: Uuid get() = service.uuid
actual override val serviceUuid: Uuid get() = service.uuid.toKotlinUuid()
val instanceId: Int get() = service.instanceId
}

Expand All @@ -35,8 +38,8 @@ public actual data class DiscoveredCharacteristic internal constructor(
public actual val descriptors: List<DiscoveredDescriptor> =
characteristic.descriptors.map(::DiscoveredDescriptor)

actual override val serviceUuid: Uuid get() = characteristic.service.uuid
actual override val characteristicUuid: Uuid get() = characteristic.uuid
actual override val serviceUuid: Uuid get() = characteristic.service.uuid.toKotlinUuid()
actual override val characteristicUuid: Uuid get() = characteristic.uuid.toKotlinUuid()
val instanceId: Int get() = characteristic.instanceId
public actual val properties: Properties get() = Properties(characteristic.properties)
}
Expand All @@ -45,12 +48,12 @@ public actual data class DiscoveredDescriptor internal constructor(
internal actual val descriptor: PlatformDescriptor,
) : Descriptor {

actual override val serviceUuid: Uuid get() = descriptor.characteristic.service.uuid
actual override val characteristicUuid: Uuid get() = descriptor.characteristic.uuid
actual override val descriptorUuid: Uuid get() = descriptor.uuid
actual override val serviceUuid: Uuid get() = descriptor.characteristic.service.uuid.toKotlinUuid()
actual override val characteristicUuid: Uuid get() = descriptor.characteristic.uuid.toKotlinUuid()
actual override val descriptorUuid: Uuid get() = descriptor.uuid.toKotlinUuid()
}

internal fun PlatformCharacteristic.toLazyCharacteristic() = LazyCharacteristic(
serviceUuid = service.uuid,
characteristicUuid = uuid,
serviceUuid = service.uuid.toKotlinUuid(),
characteristicUuid = uuid.toKotlinUuid(),
)
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,14 @@ import android.bluetooth.le.ScanResult
import android.os.Build.VERSION
import android.os.Build.VERSION_CODES
import android.os.ParcelUuid
import com.benasher44.uuid.Uuid
import com.juul.kable.PlatformAdvertisement.BondState
import kotlinx.parcelize.Parcelize
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
import kotlin.uuid.toJavaUuid
import kotlin.uuid.toKotlinUuid

@OptIn(ExperimentalUuidApi::class)
@Parcelize
internal class ScanResultAndroidAdvertisement(
private val scanResult: ScanResult,
Expand Down Expand Up @@ -65,10 +69,10 @@ internal class ScanResultAndroidAdvertisement(
get() = scanResult.scanRecord?.txPowerLevel

override val uuids: List<Uuid>
get() = scanResult.scanRecord?.serviceUuids?.map { it.uuid } ?: emptyList()
get() = scanResult.scanRecord?.serviceUuids?.map { it.uuid.toKotlinUuid() } ?: emptyList()

override fun serviceData(uuid: Uuid): ByteArray? =
scanResult.scanRecord?.serviceData?.get(ParcelUuid(uuid))
scanResult.scanRecord?.serviceData?.get(ParcelUuid(uuid.toJavaUuid()))

override fun manufacturerData(companyIdentifierCode: Int): ByteArray? =
scanResult.scanRecord?.getManufacturerSpecificData(companyIdentifierCode)
Expand Down
13 changes: 8 additions & 5 deletions kable-core/src/androidMain/kotlin/logs/LogMessage.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
@file:JvmName("AndroidLogMessage")
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable.logs

import android.bluetooth.BluetoothGattCharacteristic
import android.bluetooth.BluetoothGattDescriptor
import com.juul.kable.gatt.GattStatus
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.toKotlinUuid

internal actual val LOG_INDENT: String? = null

Expand All @@ -14,15 +17,15 @@ internal fun LogMessage.detail(status: GattStatus) {

internal fun LogMessage.detail(characteristic: BluetoothGattCharacteristic) {
detail(
characteristic.service.uuid,
characteristic.uuid,
characteristic.service.uuid.toKotlinUuid(),
characteristic.uuid.toKotlinUuid(),
)
}

internal fun LogMessage.detail(descriptor: BluetoothGattDescriptor) {
detail(
descriptor.characteristic.service.uuid,
descriptor.characteristic.uuid,
descriptor.uuid,
descriptor.characteristic.service.uuid.toKotlinUuid(),
descriptor.characteristic.uuid.toKotlinUuid(),
descriptor.uuid.toKotlinUuid(),
)
}
4 changes: 3 additions & 1 deletion kable-core/src/appleMain/kotlin/AdvertisementData.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
package com.juul.kable

import com.benasher44.uuid.Uuid
import platform.CoreBluetooth.CBAdvertisementDataLocalNameKey
import platform.CoreBluetooth.CBAdvertisementDataManufacturerDataKey
import platform.CoreBluetooth.CBAdvertisementDataServiceUUIDsKey
import platform.CoreBluetooth.CBUUID
import platform.Foundation.NSData
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

@OptIn(ExperimentalUuidApi::class)
internal value class AdvertisementData(private val source: Map<String, Any>) {

val serviceUuids: List<Uuid>?
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.juul.kable

import com.benasher44.uuid.Uuid
import platform.CoreBluetooth.CBAdvertisementDataIsConnectable
import platform.CoreBluetooth.CBAdvertisementDataLocalNameKey
import platform.CoreBluetooth.CBAdvertisementDataManufacturerDataKey
Expand All @@ -12,7 +11,10 @@ import platform.CoreBluetooth.CBUUID
import platform.Foundation.NSData
import platform.Foundation.NSNumber
import kotlin.experimental.ExperimentalNativeApi
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

@OptIn(ExperimentalUuidApi::class)
internal class CBPeripheralCoreBluetoothAdvertisement(
override val rssi: Int,
val data: Map<String, Any>,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.juul.kable

import com.benasher44.uuid.Uuid
import com.juul.kable.CentralManagerDelegate.ConnectionEvent
import com.juul.kable.CentralManagerDelegate.ConnectionEvent.DidConnect
import com.juul.kable.CentralManagerDelegate.ConnectionEvent.DidDisconnect
Expand Down Expand Up @@ -87,7 +86,10 @@ import platform.Foundation.dataUsingEncoding
import platform.darwin.UInt16
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.cancellation.CancellationException
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

@OptIn(ExperimentalUuidApi::class)
internal class CBPeripheralCoreBluetoothPeripheral(
parentCoroutineContext: CoroutineContext,
internal val cbPeripheral: CBPeripheral,
Expand Down
4 changes: 3 additions & 1 deletion kable-core/src/appleMain/kotlin/CentralManager.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.juul.kable

import com.benasher44.uuid.Uuid
import com.juul.kable.logs.Logging
import kotlinx.atomicfu.atomic
import kotlinx.coroutines.CoroutineScope
Expand All @@ -14,9 +13,12 @@ import platform.CoreBluetooth.CBPeripheral
import platform.CoreBluetooth.CBService
import platform.CoreBluetooth.CBUUID
import platform.Foundation.NSData
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

private const val DISPATCH_QUEUE_LABEL = "central"

@OptIn(ExperimentalUuidApi::class)
public class CentralManager internal constructor(
options: Map<Any?, *>?,
) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable

import com.benasher44.uuid.Uuid
import com.juul.kable.CentralManagerDelegate.Response.DidDiscoverPeripheral
import com.juul.kable.Filter.Service
import com.juul.kable.UnmetRequirementReason.BluetoothDisabled
Expand All @@ -18,6 +19,8 @@ import platform.CoreBluetooth.CBManagerStatePoweredOff
import platform.CoreBluetooth.CBManagerStatePoweredOn
import platform.CoreBluetooth.CBManagerStateUnauthorized
import platform.CoreBluetooth.CBManagerStateUnsupported
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

internal class CentralManagerCoreBluetoothScanner(
central: CentralManager,
Expand Down
8 changes: 5 additions & 3 deletions kable-core/src/appleMain/kotlin/Identifier.kt
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable

import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

public actual typealias Identifier = Uuid

public actual fun String.toIdentifier(): Identifier = uuidFrom(this)
public actual fun String.toIdentifier(): Identifier = Uuid.parse(this)
2 changes: 2 additions & 0 deletions kable-core/src/appleMain/kotlin/Peripheral.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.juul.kable

import kotlinx.coroutines.CoroutineScope
import platform.CoreBluetooth.CBPeripheral
import kotlin.uuid.ExperimentalUuidApi

public actual fun CoroutineScope.peripheral(
advertisement: Advertisement,
Expand All @@ -11,6 +12,7 @@ public actual fun CoroutineScope.peripheral(
return peripheral(advertisement.cbPeripheral, builderAction)
}

@OptIn(ExperimentalUuidApi::class)
public fun CoroutineScope.peripheral(
identifier: Identifier,
builderAction: PeripheralBuilderAction = {},
Expand Down
4 changes: 3 additions & 1 deletion kable-core/src/appleMain/kotlin/PlatformAdvertisement.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package com.juul.kable

import com.benasher44.uuid.Uuid
import platform.Foundation.NSData
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

public actual interface PlatformAdvertisement : Advertisement {
@OptIn(ExperimentalUuidApi::class)
public fun serviceDataAsNSData(uuid: Uuid): NSData?
public val manufacturerDataAsNSData: NSData?
public fun manufacturerDataAsNSData(companyIdentifierCode: Int): NSData?
Expand Down
5 changes: 4 additions & 1 deletion kable-core/src/appleMain/kotlin/Profile.kt
Original file line number Diff line number Diff line change
@@ -1,10 +1,13 @@
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable

import com.benasher44.uuid.Uuid
import com.juul.kable.Characteristic.Properties
import platform.CoreBluetooth.CBCharacteristic
import platform.CoreBluetooth.CBDescriptor
import platform.CoreBluetooth.CBService
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

@Suppress("ACTUAL_WITHOUT_EXPECT") // https://youtrack.jetbrains.com/issue/KT-37316
internal actual typealias PlatformService = CBService
Expand Down
4 changes: 3 additions & 1 deletion kable-core/src/appleMain/kotlin/ScannerBuilder.kt
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package com.juul.kable

import com.benasher44.uuid.Uuid
import com.juul.kable.logs.Logging
import com.juul.kable.logs.LoggingBuilder
import platform.CoreBluetooth.CBCentralManagerScanOptionAllowDuplicatesKey
import platform.CoreBluetooth.CBCentralManagerScanOptionSolicitedServiceUUIDsKey
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

@OptIn(ExperimentalUuidApi::class)
public actual class ScannerBuilder {

@Deprecated(
Expand Down
12 changes: 7 additions & 5 deletions kable-core/src/appleMain/kotlin/Uuid.kt
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable

import com.benasher44.uuid.Uuid
import com.benasher44.uuid.uuidFrom
import platform.CoreBluetooth.CBUUID
import platform.Foundation.NSUUID
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid

internal fun Uuid.toNSUUID(): NSUUID = NSUUID(toString())
internal fun Uuid.toCBUUID(): CBUUID = CBUUID.UUIDWithString(toString())
internal fun CBUUID.toUuid(): Uuid = when (UUIDString.length) {
4 -> uuidFrom("0000$UUIDString-0000-1000-8000-00805F9B34FB")
else -> uuidFrom(UUIDString)
4 -> Uuid.parse("0000$UUIDString-0000-1000-8000-00805F9B34FB")
else -> Uuid.parse(UUIDString)
}

internal fun NSUUID.toUuid(): Uuid = uuidFrom(UUIDString)
internal fun NSUUID.toUuid(): Uuid = Uuid.parse(UUIDString)
3 changes: 3 additions & 0 deletions kable-core/src/appleMain/kotlin/logs/LogMessage.kt
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
@file:OptIn(ExperimentalUuidApi::class)

package com.juul.kable.logs

import com.juul.kable.logs.Logging.DataProcessor.Operation
Expand All @@ -8,6 +10,7 @@ import platform.CoreBluetooth.CBDescriptor
import platform.CoreBluetooth.CBService
import platform.Foundation.NSData
import platform.Foundation.NSError
import kotlin.uuid.ExperimentalUuidApi

internal actual val LOG_INDENT: String? = " "

Expand Down
Loading

0 comments on commit f8b8761

Please sign in to comment.