Skip to content
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package app.aaps.pump.tandem.common.comm

import android.content.Context
import android.os.Handler
import android.os.Looper
import app.aaps.core.interfaces.logging.AAPSLogger
import app.aaps.core.interfaces.logging.LTag
import app.aaps.core.interfaces.resources.ResourceHelper
Expand Down Expand Up @@ -37,6 +39,7 @@ import com.jwoglom.pumpx2.pump.messages.response.currentStatus.ApiVersionRespons
import com.jwoglom.pumpx2.pump.messages.response.currentStatus.PumpVersionResponse
import com.jwoglom.pumpx2.pump.messages.response.currentStatus.TimeSinceResetResponse
import com.jwoglom.pumpx2.pump.messages.response.qualifyingEvent.QualifyingEvent
import com.welie.blessed.ConnectionPriority
import com.welie.blessed.ConnectionState
import com.welie.blessed.BluetoothPeripheral
import com.welie.blessed.HciStatus
Expand Down Expand Up @@ -79,6 +82,19 @@ class TandemPumpCommunicationManager(

var bluetoothHandler: TandemBluetoothHandler? = null

// Periodically re-asserts CONNECTION_PRIORITY_HIGH while the link is healthy (see
// CONNECTION_PRIORITY_REASSERT_INTERVAL_MS). Self-stops once the peripheral drops.
private val connectionPriorityHandler = Handler(Looper.getMainLooper())
private val connectionPriorityReassert = object : Runnable {
override fun run() {
if (isConnectionHealthy()) {
aapsLogger.debug(TAG, "Re-asserting connection priority HIGH")
peripheral.requestConnectionPriority(ConnectionPriority.HIGH)
connectionPriorityHandler.postDelayed(this, CONNECTION_PRIORITY_REASSERT_INTERVAL_MS)
}
}
}

// Thread-safe: added/removed on the TandemPumpOpQueue thread, read/added on the BLE callback
// (main) thread. newKeySet gives weakly-consistent iteration so find() can't throw CME.
val inFlightRequests: MutableSet<Message> = ConcurrentHashMap.newKeySet()
Expand All @@ -94,6 +110,12 @@ class TandemPumpCommunicationManager(
val COMMAND_TIMEOUT = 5 * 1000 // 5s (in ms) timeout for receiving pump command response
val HANDSHAKE_TIMEOUT = 30 * 1000L // 30s (in ms) timeout for handshake (pairing) connecting flow
val CONNECT_TIMEOUT = 60 * 1000L // 60s (in ms) timeout for complete connecting flow

// Re-assert CONNECTION_PRIORITY_HIGH on this cadence. The Mobi renegotiates down to its
// power-saving profile (interval=30ms, latency=29, timeout=2s) ~15s after connect, and that
// 2s supervision timeout causes the frequent CONNECTION_TIMEOUT drops. Holding HIGH
// (interval=15ms, latency=0, timeout=5s) widens the supervision window and reduces drops.
const val CONNECTION_PRIORITY_REASSERT_INTERVAL_MS = 10_000L
}


Expand Down Expand Up @@ -155,6 +177,8 @@ class TandemPumpCommunicationManager(

aapsLogger.info(TAG, "disconnect()")

stopConnectionPriorityReassert()

// Fully tear down the BLE handler: cancel any live peripheral
// connection, stop the central, and null the pumpx2 singleton so the
// next connect() builds a fresh handler. blessed's close() alone does
Expand All @@ -170,6 +194,21 @@ class TandemPumpCommunicationManager(
return connected
}

fun isConnectionHealthy(): Boolean {
return connected &&
::peripheral.isInitialized &&
peripheral.state == ConnectionState.CONNECTED
}

private fun scheduleConnectionPriorityReassert() {
connectionPriorityHandler.removeCallbacks(connectionPriorityReassert)
connectionPriorityHandler.postDelayed(connectionPriorityReassert, CONNECTION_PRIORITY_REASSERT_INTERVAL_MS)
}

private fun stopConnectionPriorityReassert() {
connectionPriorityHandler.removeCallbacks(connectionPriorityReassert)
}


private fun createBluetoothHandler(): TandemBluetoothHandler? {
if (bluetoothHandler != null) {
Expand Down Expand Up @@ -207,6 +246,7 @@ class TandemPumpCommunicationManager(
aapsLogger.info(TAG, "onPumpConnected: $peripheral")

super.onPumpConnected(peripheral)
scheduleConnectionPriorityReassert()
}


Expand Down