Revert "chore(deps): update nordic.ble to v2.0.0-alpha13" (#4536)

This commit is contained in:
James Rich 2026-02-11 14:53:25 -06:00 committed by GitHub
parent 55b17857be
commit 28c364f935
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
16 changed files with 189 additions and 169 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025-2026 Meshtastic LLC
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.geeksville.mesh.repository.bluetooth
import android.annotation.SuppressLint
@ -46,9 +47,9 @@ import javax.inject.Inject
import javax.inject.Singleton
import kotlin.time.Duration.Companion.seconds
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.toKotlinUuid
/** Repository responsible for maintaining and updating the state of Bluetooth availability. */
@OptIn(ExperimentalUuidApi::class)
@Singleton
class BluetoothRepository
@Inject
@ -94,6 +95,7 @@ constructor(
fun isValid(bleAddress: String): Boolean = BluetoothAdapter.checkBluetoothAddress(bleAddress)
/** Starts a BLE scan for Meshtastic devices. The results are published to the [scannedDevices] flow. */
@OptIn(ExperimentalUuidApi::class)
@SuppressLint("MissingPermission")
fun startScan() {
if (isScanning.value) return
@ -104,7 +106,7 @@ constructor(
scanJob =
processLifecycle.coroutineScope.launch(dispatchers.default) {
centralManager
.scan(5.seconds) { ServiceUuid(BTM_SERVICE_UUID) }
.scan(5.seconds) { ServiceUuid(BTM_SERVICE_UUID.toKotlinUuid()) }
.distinctByPeripheral()
.map { it.peripheral }
.onStart { _isScanning.value = true }
@ -144,6 +146,7 @@ constructor(
refreshState()
}
@OptIn(ExperimentalUuidApi::class)
internal suspend fun updateBluetoothState() {
val hasPerms = application.hasBluetoothPermission()
val enabled = centralManager.state.value == Manager.State.POWERED_ON
@ -167,9 +170,11 @@ constructor(
}
/** Checks if a peripheral is one of ours, either by its advertised name or by the services it provides. */
@OptIn(ExperimentalUuidApi::class)
private fun isMatchingPeripheral(peripheral: Peripheral): Boolean {
val nameMatches = peripheral.name?.matches(Regex(BLE_NAME_PATTERN)) ?: false
val hasRequiredService = peripheral.services(listOf(BTM_SERVICE_UUID)).value?.isNotEmpty() ?: false
val hasRequiredService =
peripheral.services(listOf(BTM_SERVICE_UUID.toKotlinUuid())).value?.isNotEmpty() ?: false
return nameMatches || hasRequiredService
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2025-2026 Meshtastic LLC
* Copyright (c) 2025 Meshtastic LLC
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
package com.geeksville.mesh.repository.bluetooth
import android.content.Context
@ -27,7 +28,6 @@ import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import no.nordicsemi.kotlin.ble.client.android.CentralManager
import no.nordicsemi.kotlin.ble.client.android.native
import no.nordicsemi.kotlin.ble.environment.android.NativeAndroidEnvironment
import javax.inject.Singleton
@Module
@ -35,13 +35,8 @@ import javax.inject.Singleton
object BluetoothRepositoryModule {
@Provides
@Singleton
fun provideAndroidEnvironment(@ApplicationContext context: Context): NativeAndroidEnvironment =
NativeAndroidEnvironment.getInstance(context, isNeverForLocationFlagSet = true)
@Provides
@Singleton
fun provideCentralManager(environment: NativeAndroidEnvironment, coroutineScope: CoroutineScope): CentralManager =
CentralManager.native(environment, coroutineScope)
fun provideCentralManager(@ApplicationContext context: Context, coroutineScope: CoroutineScope): CentralManager =
CentralManager.native(context, coroutineScope)
@Provides
@Singleton

View file

@ -17,6 +17,7 @@
package com.geeksville.mesh.repository.radio
import com.geeksville.mesh.service.RadioNotConnectedException
import no.nordicsemi.kotlin.ble.client.exception.BluetoothUnavailableException
import no.nordicsemi.kotlin.ble.client.exception.ConnectionFailedException
import no.nordicsemi.kotlin.ble.client.exception.InvalidAttributeException
import no.nordicsemi.kotlin.ble.client.exception.OperationFailedException
@ -25,7 +26,6 @@ import no.nordicsemi.kotlin.ble.client.exception.ScanningException
import no.nordicsemi.kotlin.ble.client.exception.ValueDoesNotMatchException
import no.nordicsemi.kotlin.ble.core.ConnectionState
import no.nordicsemi.kotlin.ble.core.exception.BluetoothException
import no.nordicsemi.kotlin.ble.core.exception.BluetoothUnavailableException
import no.nordicsemi.kotlin.ble.core.exception.GattException
import no.nordicsemi.kotlin.ble.core.exception.ManagerClosedException

View file

@ -52,8 +52,9 @@ import no.nordicsemi.kotlin.ble.client.exception.InvalidAttributeException
import no.nordicsemi.kotlin.ble.core.CharacteristicProperty
import no.nordicsemi.kotlin.ble.core.ConnectionState
import no.nordicsemi.kotlin.ble.core.WriteType
import java.util.UUID
import kotlin.uuid.ExperimentalUuidApi
import kotlin.uuid.Uuid
import kotlin.uuid.toKotlinUuid
/**
* A [IRadioInterface] implementation for BLE devices using Nordic Kotlin BLE Library.
@ -66,7 +67,6 @@ import kotlin.uuid.Uuid
* @param service The [RadioInterfaceService] to use for handling radio events.
* @param address The BLE address of the device to connect to.
*/
@OptIn(ExperimentalUuidApi::class)
@SuppressLint("MissingPermission")
class NordicBleInterface
@AssistedInject
@ -251,22 +251,23 @@ constructor(
}
@Suppress("TooGenericExceptionCaught")
@OptIn(ExperimentalUuidApi::class)
private fun discoverServicesAndSetupCharacteristics(peripheral: Peripheral) {
connectionScope.launch {
peripheral
.services(listOf(BTM_SERVICE_UUID))
.services(listOf(BTM_SERVICE_UUID.toKotlinUuid()))
.onEach { services ->
val meshtasticService = services?.find { it.uuid == BTM_SERVICE_UUID }
val meshtasticService = services?.find { it.uuid == BTM_SERVICE_UUID.toKotlinUuid() }
if (meshtasticService != null) {
toRadioCharacteristic =
meshtasticService.characteristics.find { it.uuid == BTM_TORADIO_CHARACTER }
meshtasticService.characteristics.find { it.uuid == BTM_TORADIO_CHARACTER.toKotlinUuid() }
fromNumCharacteristic =
meshtasticService.characteristics.find { it.uuid == BTM_FROMNUM_CHARACTER }
meshtasticService.characteristics.find { it.uuid == BTM_FROMNUM_CHARACTER.toKotlinUuid() }
fromRadioCharacteristic =
meshtasticService.characteristics.find { it.uuid == BTM_FROMRADIO_CHARACTER }
meshtasticService.characteristics.find { it.uuid == BTM_FROMRADIO_CHARACTER.toKotlinUuid() }
logRadioCharacteristic =
meshtasticService.characteristics.find { it.uuid == BTM_LOGRADIO_CHARACTER }
meshtasticService.characteristics.find { it.uuid == BTM_LOGRADIO_CHARACTER.toKotlinUuid() }
if (
listOf(toRadioCharacteristic, fromNumCharacteristic, fromRadioCharacteristic).all {
@ -311,6 +312,7 @@ constructor(
// --- Notification Setup ---
@OptIn(ExperimentalUuidApi::class)
private suspend fun setupNotifications() {
retryCall { fromNumCharacteristic?.subscribe() }
?.onStart { Logger.d { "[$address] Subscribing to fromNumCharacteristic" } }
@ -449,12 +451,11 @@ constructor(
}
}
@OptIn(ExperimentalUuidApi::class)
object BleConstants {
const val BLE_NAME_PATTERN = "^.*_([0-9a-fA-F]{4})$"
val BTM_SERVICE_UUID: Uuid = Uuid.parse("6ba1b218-15a8-461f-9fa8-5dcae273eafd")
val BTM_TORADIO_CHARACTER: Uuid = Uuid.parse("f75c76d2-129e-4dad-a1dd-7866124401e7")
val BTM_FROMNUM_CHARACTER: Uuid = Uuid.parse("ed9da18c-a800-4f66-a670-aa7547e34453")
val BTM_FROMRADIO_CHARACTER: Uuid = Uuid.parse("2c55e69e-4993-11ed-b878-0242ac120002")
val BTM_LOGRADIO_CHARACTER: Uuid = Uuid.parse("5a3d6e49-06e6-4423-9944-e9de8cdf9547")
val BTM_SERVICE_UUID: UUID = UUID.fromString("6ba1b218-15a8-461f-9fa8-5dcae273eafd")
val BTM_TORADIO_CHARACTER: UUID = UUID.fromString("f75c76d2-129e-4dad-a1dd-7866124401e7")
val BTM_FROMNUM_CHARACTER: UUID = UUID.fromString("ed9da18c-a800-4f66-a670-aa7547e34453")
val BTM_FROMRADIO_CHARACTER: UUID = UUID.fromString("2c55e69e-4993-11ed-b878-0242ac120002")
val BTM_LOGRADIO_CHARACTER: UUID = UUID.fromString("5a3d6e49-06e6-4423-9944-e9de8cdf9547")
}