track rssi correctly

This commit is contained in:
callebtc
2025-07-14 00:13:45 +02:00
parent 06a9ec6268
commit 193918d81a
6 changed files with 146 additions and 2 deletions
@@ -13,6 +13,7 @@ import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.*
import kotlinx.coroutines.Job
/**
* Manages GATT client operations, scanning, and client-side connections
@@ -31,6 +32,9 @@ class BluetoothGattClientManager(
// Use exact same UUIDs as iOS version
private val SERVICE_UUID = UUID.fromString("F47B5E2D-4A9E-4C5A-9B3F-8E1D2C3A4B5C")
private val CHARACTERISTIC_UUID = UUID.fromString("A1B2C3D4-E5F6-4A5B-8C9D-0E1F2A3B4C5D")
// RSSI monitoring constants
private const val RSSI_UPDATE_INTERVAL = 5000L // 5 seconds
}
// Core Bluetooth components
@@ -48,6 +52,9 @@ class BluetoothGattClientManager(
private var isCurrentlyScanning = false
private val scanRateLimit = 5000L // Minimum 5 seconds between scan start attempts
// RSSI monitoring state
private var rssiMonitoringJob: Job? = null
// State management
private var isActive = false
@@ -78,6 +85,9 @@ class BluetoothGattClientManager(
} else {
startScanning()
}
// Start RSSI monitoring
startRSSIMonitoring()
}
return true
@@ -91,6 +101,7 @@ class BluetoothGattClientManager(
connectionScope.launch {
stopScanning()
stopRSSIMonitoring()
Log.i(TAG, "GATT client manager stopped")
}
}
@@ -106,6 +117,41 @@ class BluetoothGattClientManager(
}
}
/**
* Start periodic RSSI monitoring for all client connections
*/
private fun startRSSIMonitoring() {
rssiMonitoringJob?.cancel()
rssiMonitoringJob = connectionScope.launch {
while (isActive) {
try {
// Request RSSI from all client connections
val connectedDevices = connectionTracker.getConnectedDevices()
connectedDevices.values.filter { it.isClient && it.gatt != null }.forEach { deviceConn ->
try {
Log.d(TAG, "Requesting RSSI from ${deviceConn.device.address}")
deviceConn.gatt?.readRemoteRssi()
} catch (e: Exception) {
Log.w(TAG, "Failed to request RSSI from ${deviceConn.device.address}: ${e.message}")
}
}
delay(RSSI_UPDATE_INTERVAL)
} catch (e: Exception) {
Log.w(TAG, "Error in RSSI monitoring: ${e.message}")
delay(RSSI_UPDATE_INTERVAL)
}
}
}
}
/**
* Stop RSSI monitoring
*/
private fun stopRSSIMonitoring() {
rssiMonitoringJob?.cancel()
rssiMonitoringJob = null
}
/**
* Start scanning with rate limiting
*/
@@ -230,6 +276,9 @@ class BluetoothGattClientManager(
return
}
// Store RSSI from scan results for later use (especially for server connections)
connectionTracker.updateScanRSSI(deviceAddress, rssi)
// Power-aware RSSI filtering
if (rssi < powerManager.getRSSIThreshold()) {
Log.d(TAG, "Skipping device $deviceAddress due to weak signal: $rssi < ${powerManager.getRSSIThreshold()}")
@@ -381,6 +430,21 @@ class BluetoothGattClientManager(
Log.w(TAG, "Client: Packet data: ${value.joinToString(" ") { "%02x".format(it) }}")
}
}
override fun onReadRemoteRssi(gatt: BluetoothGatt, rssi: Int, status: Int) {
val deviceAddress = gatt.device.address
if (status == BluetoothGatt.GATT_SUCCESS) {
Log.d(TAG, "Client: RSSI updated for $deviceAddress: $rssi dBm")
// Update the connection tracker with new RSSI value
connectionTracker.getDeviceConnection(deviceAddress)?.let { deviceConn ->
val updatedConn = deviceConn.copy(rssi = rssi)
connectionTracker.updateDeviceConnection(deviceAddress, updatedConn)
}
} else {
Log.w(TAG, "Client: Failed to read RSSI for $deviceAddress, status: $status")
}
}
}
try {