mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-06-02 06:24:16 +02:00
fix(ble): stop BLE scan on background and downgrade connection priority (#5644)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -79,3 +79,10 @@ internal actual fun Peripheral.requestHighConnectionPriority(): Boolean {
|
||||
.onFailure { Logger.w(it) { "requestConnectionPriority(High) threw" } }
|
||||
.getOrDefault(false)
|
||||
}
|
||||
|
||||
internal actual fun Peripheral.requestBalancedConnectionPriority(): Boolean {
|
||||
val androidPeripheral = this as? AndroidPeripheral ?: return false
|
||||
return runCatching { androidPeripheral.requestConnectionPriority(AndroidPeripheral.Priority.Balanced) }
|
||||
.onFailure { Logger.w(it) { "requestConnectionPriority(Balanced) threw" } }
|
||||
.getOrDefault(false)
|
||||
}
|
||||
|
||||
@@ -78,6 +78,13 @@ interface BleConnection {
|
||||
* Default implementation returns `false` for platforms that don't support it.
|
||||
*/
|
||||
fun requestHighConnectionPriority(): Boolean = false
|
||||
|
||||
/**
|
||||
* Requests the platform to return to balanced BLE connection priority (default ~30–50 ms interval). Call after
|
||||
* latency-sensitive operations (initial config drain, DFU) to reduce ongoing battery draw. Default implementation
|
||||
* returns `false` for platforms that don't support it.
|
||||
*/
|
||||
fun requestBalancedConnectionPriority(): Boolean = false
|
||||
}
|
||||
|
||||
/** Represents a BLE service for commonMain. */
|
||||
|
||||
@@ -245,6 +245,8 @@ class KableBleConnection(private val scope: CoroutineScope, private val loggingC
|
||||
|
||||
override fun requestHighConnectionPriority(): Boolean = peripheral?.requestHighConnectionPriority() == true
|
||||
|
||||
override fun requestBalancedConnectionPriority(): Boolean = peripheral?.requestBalancedConnectionPriority() == true
|
||||
|
||||
/** Ensures the previous peripheral's GATT resources are fully released. */
|
||||
private suspend fun cleanUpPeripheral(tag: String) {
|
||||
withContext(NonCancellable) { safeClosePeripheral(tag) }
|
||||
|
||||
@@ -38,3 +38,9 @@ internal expect fun Peripheral.negotiatedMaxWriteLength(): Int?
|
||||
* no-op returning `false`. Used by latency-sensitive flows such as DFU firmware streaming.
|
||||
*/
|
||||
internal expect fun Peripheral.requestHighConnectionPriority(): Boolean
|
||||
|
||||
/**
|
||||
* Requests balanced BLE connection priority (default ~30–50 ms interval) to reduce battery draw after latency-sensitive
|
||||
* operations complete. On platforms without an equivalent API (JVM/iOS) this is a no-op.
|
||||
*/
|
||||
internal expect fun Peripheral.requestBalancedConnectionPriority(): Boolean
|
||||
|
||||
@@ -30,3 +30,5 @@ internal actual fun createPeripheral(address: String, builderAction: PeripheralB
|
||||
internal actual fun Peripheral.negotiatedMaxWriteLength(): Int? = null
|
||||
|
||||
internal actual fun Peripheral.requestHighConnectionPriority(): Boolean = false
|
||||
|
||||
internal actual fun Peripheral.requestBalancedConnectionPriority(): Boolean = false
|
||||
|
||||
@@ -33,4 +33,6 @@ internal actual fun Peripheral.negotiatedMaxWriteLength(): Int? = DEFAULT_JVM_MT
|
||||
|
||||
internal actual fun Peripheral.requestHighConnectionPriority(): Boolean = false
|
||||
|
||||
internal actual fun Peripheral.requestBalancedConnectionPriority(): Boolean = false
|
||||
|
||||
private const val DEFAULT_JVM_MTU = 512
|
||||
|
||||
+29
-9
@@ -78,6 +78,16 @@ private val HEARTBEAT_DRAIN_DELAY = 200.milliseconds
|
||||
private val SCAN_TIMEOUT = 5.seconds
|
||||
private val GATT_CLEANUP_TIMEOUT = 5.seconds
|
||||
|
||||
/**
|
||||
* Delay after onConnect before downgrading BLE connection priority to Balanced.
|
||||
*
|
||||
* The initial config drain (fromRadio burst) typically completes within 2–5 seconds on most devices, but slower radios
|
||||
* (ESP32 with large node databases, many channels, or dense position history) can take significantly longer. 30 seconds
|
||||
* provides generous margin while still ensuring we don't sustain the 7.5 ms connection interval indefinitely, which
|
||||
* significantly increases battery draw on both the phone and the radio.
|
||||
*/
|
||||
private val PRIORITY_DOWNGRADE_DELAY = 30.seconds
|
||||
|
||||
/**
|
||||
* A [RadioTransport] implementation for BLE devices using the common BLE abstractions (which are powered by Kable).
|
||||
*
|
||||
@@ -361,15 +371,7 @@ class BleRadioTransport(
|
||||
val maxLen = bleConnection.maximumWriteValueLength(BleWriteType.WITHOUT_RESPONSE)
|
||||
Logger.i { "[$address] BLE Radio Session Ready. Max write length (WITHOUT_RESPONSE): $maxLen bytes" }
|
||||
|
||||
// Ask the platform for a low-latency / high-throughput connection interval
|
||||
// (~7.5 ms on Android). The Meshtastic firmware happily accepts this and it
|
||||
// materially speeds up the initial config drain and any bulk fromRadio reads.
|
||||
if (bleConnection.requestHighConnectionPriority()) {
|
||||
Logger.d { "[$address] Requested high BLE connection priority" }
|
||||
// Wait for the connection parameter update to succeed before starting the heavy traffic
|
||||
// in onConnect(). Otherwise, the Android BLE stack may disconnect with GATT 147.
|
||||
delay(1.seconds)
|
||||
}
|
||||
requestHighPriorityAndScheduleDowngrade()
|
||||
|
||||
this@BleRadioTransport.callback.onConnect()
|
||||
}
|
||||
@@ -398,6 +400,24 @@ class BleRadioTransport(
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Requests high BLE connection priority for the initial config burst, then schedules a downgrade to balanced
|
||||
* priority after [PRIORITY_DOWNGRADE_DELAY] to conserve battery.
|
||||
*/
|
||||
private suspend fun CoroutineScope.requestHighPriorityAndScheduleDowngrade() {
|
||||
if (bleConnection.requestHighConnectionPriority()) {
|
||||
Logger.d { "[$address] Requested high BLE connection priority" }
|
||||
// Wait for the connection parameter update before starting heavy traffic.
|
||||
delay(1.seconds)
|
||||
}
|
||||
launch {
|
||||
delay(PRIORITY_DOWNGRADE_DELAY)
|
||||
if (bleConnection.requestBalancedConnectionPriority()) {
|
||||
Logger.d { "[$address] Downgraded to balanced BLE connection priority" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Volatile private var radioService: MeshtasticRadioProfile? = null
|
||||
|
||||
// --- RadioTransport Implementation ---
|
||||
|
||||
Reference in New Issue
Block a user