refactor: Replace Nordic, use Kable backend for Desktop and Android with BLE support#4818
refactor: Replace Nordic, use Kable backend for Desktop and Android with BLE support#4818jamesarich merged 81 commits intomainfrom
Conversation
…ort-term. Add Kable backend only for jvmMain in core:ble first (desktop BLE enablement)'
…bstraction' as complete
…dic types' as complete
…to use Abstraction' as complete
…DI graph' as complete
…Desktop via Kable
…ssion in Kable connection flow
…ow initialization
…ss-platform Identifier builder
…ions to simplify Kable integration
This commit removes the documentation and metadata associated with the `android_kable_migration_20260314` track, as the migration from Nordic to Kable on Android has been completed. Specific changes include: - Deleted track index, specification (`spec.md`), and implementation plan (`plan.md`). - Removed `metadata.json` for the migration track. Signed-off-by: James Rich <[email protected]>
…tion from Nordic to Kable for the BLE transport
…able's experimental rssi function
… on active connections
…d simplify active instance tracking
This commit enhances the BLE connection stability by implementing more robust retry mechanisms, particularly for Android, and refining the handling of bonded vs. scanned devices. Specific changes include: - **Connection Logic**: Improved `KableBleConnection` to dynamically toggle `autoConnect` on Android. It now retries connections with `autoConnect = true` if an initial direct connection fails, resolving common GATT 133 errors. - **Retry Mechanisms**: Added explicit delays and logging to `BleRadioInterface` connection and scan attempts to allow the BLE stack to settle between operations. - **Platform Configuration**: Updated `platformConfig` to support dynamic `autoConnect` providers and suppressed magic number/lint warnings for MTU and delay constants. - **Dependency Clean up**: Removed unused `BluetoothRepository` from `BleRadioInterfaceSpec` and cleaned up unnecessary Koin module imports. - **Code Quality**: Standardized formatting, added `@Suppress` annotations for handled exceptions and magic numbers, and improved logging across `DirectBleDevice`, `KableBleConnection`, and `AndroidBluetoothRepository`. Signed-off-by: James Rich <[email protected]>
…bility
This commit enhances the reliability of Bluetooth Low Energy (BLE) connections by implementing a reconnection loop in `BleRadioInterface` and adding failure suppression for characteristic observations in `KableBleConnection`.
Specific changes include:
- **`BleRadioInterface`**:
- Wrapped the connection logic in a `while(isActive)` loop to automatically attempt reconnection when a link is dropped.
- Added a suspension point that waits for a `Disconnected` state before triggering a retry.
- Introduced a 5-second delay after connection failures to prevent rapid retry loops.
- Refactored `connectionState` monitoring to ensure `isFullyConnected` is reset correctly upon disconnection.
- **`KableBleConnection`**:
- Configured an `observationExceptionHandler` for Kable `Peripheral` instances to suppress and log observation failures, preventing them from crashing the connection flow.
- Ensured existing peripherals are properly disconnected and closed before creating a new one.
Signed-off-by: James Rich <[email protected]>
This commit applies code formatting, adds missing copyright headers, and suppresses lint warnings across several modules to improve code quality and maintainability.
Specific changes include:
- **`core:ble`**: Added a comment to `DirectBleDevice.bond()` to clarify its implementation and applied formatting to `KableBleConnection.kt`.
- **`feature:firmware`**:
- Applied formatting and suppressed `MagicNumber` and `TooGenericExceptionCaught` warnings in `KableNordicDfuHandler.kt`.
- Added missing copyright headers to `KableNordicDfuHandlerTest.kt`.
- Cleaned up imports and formatting in `BleOtaTransport.kt` and `BleOtaTransportTest.kt`.
- **`feature:settings`**: Removed a stale comment in `PositionConfigItemList.kt`.
- **`app`**: Refactored `BleRadioInterface` and its spec for better readability and updated its unit tests with consistent formatting.
- **`core:ui`**: Cleaned up unused imports in `TimeTickWithLifecycle.kt`.
- **`core:ble` (Android)**: Suppressed generic exception warnings and improved error handling in `AndroidBluetoothRepository.kt`.
Signed-off-by: James Rich <[email protected]>
This commit corrects a formatting issue in the import section of `BleRadioInterface.kt`. Specific changes: - Fixed an issue where `kotlinx.coroutines.flow.onEach` and `kotlinx.coroutines.isActive` imports were merged onto a single line. Signed-off-by: James Rich <[email protected]>
Codecov Report❌ Patch coverage is Additional details and impacted files@@ Coverage Diff @@
## main #4818 +/- ##
==========================================
+ Coverage 12.18% 13.10% +0.92%
==========================================
Files 531 535 +4
Lines 17578 17653 +75
Branches 2630 2646 +16
==========================================
+ Hits 2142 2314 +172
+ Misses 15131 15023 -108
- Partials 305 316 +11 ☔ View full report in Codecov by Sentry. |
Signed-off-by: James Rich <[email protected]>
There was a problem hiding this comment.
Pull request overview
This PR completes a broad refactor to migrate Meshtastic’s BLE stack from Nordic’s libraries to the Kable multiplatform BLE backend, wiring the new abstractions through Android and Desktop, updating DI/build configuration, and adjusting tests/docs accordingly.
Changes:
- Introduces Kable-based BLE implementations in
core:ble(scanner/connection/profile) and updates Desktop to support BLE connections. - Migrates Android BLE transport to use the shared
BleScanner/BleConnectionabstractions (and removes Nordic usages/deps in touched modules). - Updates/relocates tests and documentation to reflect the new BLE architecture.
Reviewed changes
Copilot reviewed 81 out of 82 changed files in this pull request and generated 13 comments.
Show a summary per file
| File | Description |
|---|---|
| gradle/libs.versions.toml | Adds Kable version + library alias to the version catalog. |
| feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/radio/component/PositionConfigItemList.kt | Removes Nordic permission wrapper usage in UI. |
| feature/settings/src/androidMain/kotlin/org/meshtastic/feature/settings/radio/component/DeviceConfigItemList.kt | Replaces Nordic receiver helper with explicit receiver lifecycle via DisposableEffect. |
| feature/settings/build.gradle.kts | Removes Nordic Android Common Library deps from this module. |
| feature/firmware/src/androidUnitTest/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransportTest.kt | Deletes Nordic-mock-based unit test (migration cleanup). |
| feature/firmware/src/androidUnitTest/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransportServiceDiscoveryTest.kt | Deletes Nordic-mock-based unit tests (migration cleanup). |
| feature/firmware/src/androidUnitTest/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransportNordicMockTest.kt | Deletes Nordic-mock-based unit test (migration cleanup). |
| feature/firmware/src/androidUnitTest/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransportMtuTest.kt | Deletes Nordic-mock-based unit test (migration cleanup). |
| feature/firmware/src/androidUnitTest/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransportErrorTest.kt | Deletes Nordic-mock-based unit test (migration cleanup). |
| feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransport.kt | Ports BLE OTA transport to Kable-based BLE abstractions. |
| feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/NordicDfuHandler.kt | Removes Nordic DFU handler implementation. |
| feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/KableNordicDfuHandler.kt | Adds a new (Kable-intended) DFU handler. |
| feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/FirmwareDfuService.kt | Removes Nordic DFU foreground service implementation. |
| feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/AndroidFirmwareUpdateManager.kt | Switches injected DFU handler type to the new handler. |
| feature/firmware/src/androidMain/AndroidManifest.xml | Removes DFU service declaration. |
| feature/firmware/src/androidHostTest/kotlin/org/meshtastic/feature/firmware/ota/UnifiedOtaProtocolTest.kt | Adds host tests for OTA protocol parsing/formatting. |
| feature/firmware/src/androidHostTest/kotlin/org/meshtastic/feature/firmware/ota/Esp32OtaUpdateHandlerTest.kt | Updates host test to use CommonUri + platform URI conversion. |
| feature/firmware/src/androidHostTest/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransportTest.kt | Adds host tests for Kable-based BLE OTA transport behavior. |
| feature/firmware/src/androidHostTest/kotlin/org/meshtastic/feature/firmware/KableNordicDfuHandlerTest.kt | Adds host test coverage around new DFU handler wiring. |
| feature/firmware/src/androidHostTest/kotlin/org/meshtastic/feature/firmware/FirmwareRetrieverTest.kt | Updates tests to match refactored firmware extraction APIs. |
| feature/firmware/build.gradle.kts | Adds Kable core; rewires tests to androidHostTest deps. |
| feature/firmware/README.md | Updates docs to reference Kable-based BLE OTA transport. |
| feature/connections/src/commonMain/kotlin/org/meshtastic/feature/connections/ui/components/CurrentlyConnectedInfo.kt | Adjusts RSSI polling error logging/loop behavior. |
| docs/kmp-status.md | Updates KMP status docs to indicate Kable BLE. |
| docs/decisions/ble-strategy.md | Updates the BLE strategy decision to reflect full Kable migration. |
| desktop/src/main/kotlin/org/meshtastic/desktop/radio/DesktopRadioInterfaceService.kt | Adds BLE support to Desktop radio interface service. |
| desktop/src/main/kotlin/org/meshtastic/desktop/radio/DesktopBleInterface.kt | Renames/migrates Desktop BLE transport to Kable-based abstractions. |
| desktop/src/main/kotlin/org/meshtastic/desktop/di/DesktopKoinModule.kt | Adds core BLE module + injects BLE deps into Desktop radio service. |
| core/ui/src/androidMain/kotlin/org/meshtastic/core/ui/component/TimeTickWithLifecycle.kt | Removes Nordic receiver helper and registers receiver directly. |
| core/ui/build.gradle.kts | Removes Nordic common core dependency. |
| core/network/src/androidUnitTest/kotlin/org/meshtastic/core/network/radio/NordicBleInterfaceTest.kt | Deletes Nordic BLE interface tests. |
| core/network/src/androidUnitTest/kotlin/org/meshtastic/core/network/radio/NordicBleInterfaceRetryTest.kt | Deletes Nordic BLE retry tests. |
| core/network/src/androidUnitTest/kotlin/org/meshtastic/core/network/radio/BleRadioInterfaceTest.kt | Adds tests for new BLE radio interface path. |
| core/ble/src/test/kotlin/org/meshtastic/core/ble/BluetoothRepositoryTest.kt | Removes Nordic-mock-based BLE repository tests. |
| core/ble/src/test/kotlin/org/meshtastic/core/ble/BleScannerTest.kt | Removes Nordic-mock-based scanner tests. |
| core/ble/src/jvmMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt | Adds JVM/desktop Kable peripheral setup actuals. |
| core/ble/src/jvmMain/kotlin/org/meshtastic/core/ble/KableBluetoothRepository.kt | Adds Desktop BluetoothRepository implementation. |
| core/ble/src/commonTest/kotlin/org/meshtastic/core/ble/MeshtasticRadioProfileTest.kt | Adds common tests for profile abstraction via a fake. |
| core/ble/src/commonTest/kotlin/org/meshtastic/core/ble/KableStateMappingTest.kt | Adds tests for mapping Kable state to app connection state. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/MeshtasticRadioProfile.kt | Moves/defines MeshtasticRadioProfile in core:ble namespace. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableStateMapping.kt | Adds Kable State → BleConnectionState mapping helper. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt | Adds expect declarations for platform-specific peripheral setup. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableMeshtasticRadioProfile.kt | Implements Meshtastic BLE GATT profile using Kable. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleScanner.kt | Implements BleScanner via Kable Scanner. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleDevice.kt | Implements BleDevice wrapper over Kable Advertisement. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleConnectionFactory.kt | Replaces Android/Nordic connection factory with Kable factory. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleConnection.kt | Implements BleConnection on top of Kable Peripheral. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/DirectBleDevice.kt | Adds address-only BleDevice implementation for bonded-list flows. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/BleServiceExtensions.kt | Adds helper to convert BleService into MeshtasticRadioProfile. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/BleScanner.kt | Extends scan API to accept an address filter. |
| core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/ActiveBleConnection.kt | Adds global active-peripheral tracker. |
| core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/di/CoreBleAndroidModule.kt | Removes Nordic environment/central manager provisioning. |
| core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/KablePlatformSetup.kt | Adds Android Kable peripheral setup (autoConnect, MTU request). |
| core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/AndroidBluetoothRepository.kt | Reworks Android BluetoothRepository to avoid Nordic environment. |
| core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/AndroidBleScanner.kt | Removes Nordic-based Android scanner implementation. |
| core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/AndroidBleDevice.kt | Removes Nordic-based Android device wrapper. |
| core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/AndroidBleConnection.kt | Removes Nordic-based Android connection implementation. |
| core/ble/build.gradle.kts | Removes Nordic deps, adds Kable core, rewires test source set. |
| core/ble/README.md | Updates module docs to describe Kable-based architecture. |
| conductor/tracks.md | Minor doc formatting update. |
| conductor/tech-stack.md | Adds Kable to the tech stack docs. |
| conductor/product.md | Updates product architecture goals to include core:ble. |
| conductor/archive/desktop_ble_kable_20260314/spec.md | Adds archived spec documentation for the migration track. |
| conductor/archive/desktop_ble_kable_20260314/plan.md | Adds archived plan documentation for the migration track. |
| conductor/archive/desktop_ble_kable_20260314/metadata.json | Adds archived metadata for the migration track. |
| conductor/archive/desktop_ble_kable_20260314/index.md | Adds archived index for the migration track. |
| conductor/archive/android_kable_migration_20260314/spec.md | Adds archived Android migration spec. |
| conductor/archive/android_kable_migration_20260314/plan.md | Adds archived Android migration plan. |
| conductor/archive/android_kable_migration_20260314/metadata.json | Adds archived Android migration metadata. |
| conductor/archive/android_kable_migration_20260314/index.md | Adds archived Android migration index. |
| app/src/main/kotlin/org/meshtastic/app/repository/radio/MeshtasticRadioServiceImpl.kt | Removes Nordic-specific radio service implementation. |
| app/src/main/kotlin/org/meshtastic/app/repository/radio/InterfaceFactory.kt | Switches Bluetooth spec wiring to new BLE spec type. |
| app/src/main/kotlin/org/meshtastic/app/repository/radio/BleRadioInterfaceSpec.kt | Replaces Nordic spec with Kable-based BLE spec. |
| app/src/main/kotlin/org/meshtastic/app/repository/radio/BleRadioInterfaceFactory.kt | Renames factory + returns new BLE transport implementation. |
| app/src/main/kotlin/org/meshtastic/app/repository/radio/BleRadioInterface.kt | Adds new Kable-backed BLE radio transport implementation. |
| app/src/main/kotlin/org/meshtastic/app/repository/radio/AndroidRadioInterfaceService.kt | Updates type checks from Nordic interface to new BLE interface. |
| app/src/main/kotlin/org/meshtastic/app/di/AppKoinModule.kt | Removes old DI module include; adds CoroutineDispatchers provider. |
| app/src/main/kotlin/org/meshtastic/app/MeshUtilApplication.kt | Removes Nordic AndroidEnvironment teardown call. |
| app/src/main/kotlin/org/meshtastic/app/MainActivity.kt | Removes Nordic environment CompositionLocal provider. |
| app/detekt-baseline.xml | Updates baseline (but currently contains merge conflict marker). |
| app/build.gradle.kts | Removes Nordic deps + Nordic mock test deps. |
| README.md | Updates top-level docs to describe Kable BLE stack. |
Comments suppressed due to low confidence (1)
feature/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/ota/BleOtaTransport.kt:82
scanForOtaDevice()relies onBleScanner.scan(timeout=...)to terminate, but the new Kable scanner implementation returns a Flow that runs until cancelled. As written,.firstOrNull { ... }can hang indefinitely when no device is found. Wrap the scan collection inwithTimeoutOrNull(SCAN_TIMEOUT)(or otherwise enforce the timeout) so connect() can fail/retry predictably.
You can also share your feedback on Copilot code review. Take the survey.
core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/AndroidBluetoothRepository.kt
Show resolved
Hide resolved
...ure/firmware/src/androidMain/kotlin/org/meshtastic/feature/firmware/KableNordicDfuHandler.kt
Outdated
Show resolved
Hide resolved
core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleScanner.kt
Show resolved
Hide resolved
core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleConnection.kt
Show resolved
Hide resolved
core/ble/src/commonMain/kotlin/org/meshtastic/core/ble/KableBleConnection.kt
Show resolved
Hide resolved
core/ui/src/androidMain/kotlin/org/meshtastic/core/ui/component/TimeTickWithLifecycle.kt
Outdated
Show resolved
Hide resolved
core/ble/src/androidMain/kotlin/org/meshtastic/core/ble/AndroidBluetoothRepository.kt
Show resolved
Hide resolved
Signed-off-by: James Rich <[email protected]>
This pull request removes all dependencies on Nordic Semiconductor's BLE libraries and interfaces, replacing them with the multiplatform Kable BLE library. The codebase and documentation are updated to reflect this migration, and all related configuration, code, and test references to Nordic BLE are removed. Additionally, new dependency injection and lint configuration changes are introduced to support the updated BLE stack.
BLE Stack Migration and Dependency Cleanup:
README.mdto reflect this change.app/build.gradle.kts, including both implementation and test dependencies. [1] [2]MainActivity.ktandMeshUtilApplication.kt. [1] [2] [3] [4] [5]AndroidRadioInterfaceService.ktto use the newBleRadioInterfaceinstead of the removedNordicBleInterface.Dependency Injection and Module Updates:
CoreDiModulefrom the Koin module configuration and added a newCoroutineDispatchersprovider for dependency injection. [1] [2] [3]Lint and Baseline Updates:
detekt-baseline.xmlto remove issues related to the old Nordic BLE interface and add new lint issues relevant to the current codebase.