feat: Add retry logic for AAP L2CAP connection failures

Initial connect had no retry — a single failed L2CAP attempt was silently swallowed. Reconnect-on-disconnect used separate longer backoff delays.

Both paths now share the same retry schedule (3s,3s,3s,5s,5s,10s,10s) giving 7 retries over ~39s. Initial connect checks if another path already reconnected before each retry.
This commit is contained in:
darken
2026-03-31 19:17:09 +02:00
committed by Matthias Urhahn
parent fef6c97d2d
commit 04ea3d0cd8
2 changed files with 104 additions and 5 deletions
@@ -51,12 +51,31 @@ class AapAutoConnect @Inject constructor(
continue
}
log(TAG) { "AAP connecting to $address (${profile.label})" }
try {
log(TAG) { "AAP connecting to $address (${profile.label})" }
aapManager.connect(address, bonded.internal, profile.model)
log(TAG) { "AAP connected to $address" }
} catch (e: Exception) {
log(TAG, WARN) { "AAP connect failed for $address: ${e.message}" }
log(TAG, WARN) { "AAP initial connect failed for $address: ${e.message}" }
for ((attempt, delayMs) in RETRY_DELAYS.withIndex()) {
delay(delayMs)
val retryState = aapManager.allStates.value[address]
if (retryState != null && retryState.connectionState != AapPodState.ConnectionState.DISCONNECTED) {
log(TAG) { "AAP initial retry: $address already reconnected, stopping" }
break
}
try {
log(TAG) { "AAP initial retry ${attempt + 1} for $address after ${delayMs}ms" }
aapManager.connect(address, bonded.internal, profile.model)
log(TAG) { "AAP connected to $address on retry ${attempt + 1}" }
break
} catch (retryException: Exception) {
log(TAG, WARN) { "AAP initial retry ${attempt + 1} failed for $address: ${retryException.message}" }
}
}
}
}
}
@@ -69,9 +88,7 @@ class AapAutoConnect @Inject constructor(
return@onEach
}
val backoffDelays = longArrayOf(5_000, 10_000, 30_000, 60_000)
for ((attempt, delayMs) in backoffDelays.withIndex()) {
for ((attempt, delayMs) in RETRY_DELAYS.withIndex()) {
delay(delayMs)
// Check if still profiled
@@ -121,5 +138,6 @@ class AapAutoConnect @Inject constructor(
companion object {
private val TAG = logTag("Reaction", "AapAutoConnect")
internal val RETRY_DELAYS = longArrayOf(3_000, 3_000, 3_000, 5_000, 5_000, 10_000, 10_000)
}
}