diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt index 0834c4e4d..0c1e0fc93 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/BluetoothInterface.kt @@ -35,13 +35,7 @@ import dagger.assisted.Assisted import dagger.assisted.AssistedInject import kotlinx.coroutines.CancellationException import kotlinx.coroutines.Job -import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.SharingStarted -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.flow.distinctUntilChanged -import kotlinx.coroutines.flow.stateIn import org.meshtastic.core.analytics.platform.PlatformAnalytics import org.meshtastic.core.model.util.anonymize import timber.log.Timber @@ -145,50 +139,6 @@ constructor( private lateinit var fromNum: BluetoothGattCharacteristic - /** - * RSSI flow, which polls the remote device for RSSI only when there are active subscribers. The polling stops - * automatically when the last collector stops. - */ - val rssiFlow: StateFlow = - callbackFlow { - // Initial read for faster UI update - safe?.asyncReadRemoteRssi { first -> first.getOrNull()?.let { trySend(it) } } - - // Launch the polling loop on the service scope - @Suppress("LoopWithTooManyJumpStatements", "MagicNumber") - val pollingJob = - service.serviceScope.handledLaunch { - service.isRssiPollingEnabled.collect { isEnabled -> - if (isEnabled) { - while (true) { - try { - delay(10000) // Poll every 10 seconds - safe?.asyncReadRemoteRssi { res -> res.getOrNull()?.let { trySend(it) } } - } catch (ex: CancellationException) { - break // Stop polling on cancellation - } catch (ex: Exception) { - Timber.d("RSSI polling error: ${ex.message}") - } - } - } - } - } - - // This block executes when the last collector stops. - awaitClose { - pollingJob.cancel() - // Clear the value when the flow is closed (no active subscribers). - trySend(null) - } - } - .distinctUntilChanged() - .stateIn( - scope = service.serviceScope, - // Keep the polling running for 5 seconds after the last collector disappears - started = SharingStarted.WhileSubscribed(stopTimeoutMillis = 5000), - initialValue = null, - ) - /** * If we think we are connected, but we don't hear anything from the device, we might be in a zombie state. This * function forces a read of a characteristic to see if we are really connected. diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt index 3ee7e26c7..10f69bbbe 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioInterfaceService.kt @@ -106,10 +106,6 @@ constructor( private var radioIf: IRadioInterface = NopInterface("") - // Expose current bluetooth RSSI (null if not connected or not BLE) - private val _bluetoothRssi = MutableStateFlow(null) - val bluetoothRssi: StateFlow = _bluetoothRssi.asStateFlow() - /** * true if we have started our interface * @@ -273,13 +269,6 @@ constructor( } radioIf = interfaceFactory.createInterface(address) - - // If the new interface is bluetooth, collect its RSSI flow - if (radioIf is BluetoothInterface) { - (radioIf as BluetoothInterface).rssiFlow.onEach { _bluetoothRssi.emit(it) }.launchIn(serviceScope) - } else { - _bluetoothRssi.value = null - } } } } @@ -306,7 +295,6 @@ constructor( if (r !is NopInterface) { onDisconnect(isPermanent = true) // Tell any clients we are now offline } - _bluetoothRssi.value = null } /** diff --git a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt index f3fb2b45f..81d64d0d7 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -299,7 +299,6 @@ class MeshService : Service() { serviceScope.handledLaunch { radioInterfaceService.connect() } radioInterfaceService.connectionState.onEach(::onRadioConnectionState).launchIn(serviceScope) radioInterfaceService.receivedData.onEach(::onReceiveFromRadio).launchIn(serviceScope) - radioInterfaceService.bluetoothRssi.onEach { serviceRepository.setBluetoothRssi(it) }.launchIn(serviceScope) radioConfigRepository.localConfigFlow.onEach { localConfig = it }.launchIn(serviceScope) radioConfigRepository.moduleConfigFlow.onEach { moduleConfig = it }.launchIn(serviceScope) radioConfigRepository.channelSetFlow.onEach { channelSet = it }.launchIn(serviceScope) diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt index fae9e9ca7..8334c7f51 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsScreen.kt @@ -109,7 +109,6 @@ fun ConnectionsScreen( val selectedDevice by scanModel.selectedNotNullFlow.collectAsStateWithLifecycle() val bluetoothState by connectionsViewModel.bluetoothState.collectAsStateWithLifecycle() val regionUnset = config.lora.region == ConfigProtos.Config.LoRaConfig.RegionCode.UNSET - val bluetoothRssi by connectionsViewModel.bluetoothRssi.collectAsStateWithLifecycle() val bondedBleDevices by scanModel.bleDevicesForUi.collectAsStateWithLifecycle() val scannedBleDevices by scanModel.scanResult.observeAsState(emptyMap()) @@ -196,7 +195,6 @@ fun ConnectionsScreen( node = node, onNavigateToNodeDetails = onNavigateToNodeDetails, onClickDisconnect = { scanModel.disconnect() }, - bluetoothRssi = bluetoothRssi, ) } } diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt index 3594e53e3..d899de13a 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/ConnectionsViewModel.kt @@ -64,9 +64,6 @@ constructor( val bluetoothState = bluetoothRepository.state - // Newly added: bluetooth RSSI stream (dBm, null if unavailable) - val bluetoothRssi = serviceRepository.bluetoothRssi - private val _hasShownNotPairedWarning = MutableStateFlow(uiPrefs.hasShownNotPairedWarning) val hasShownNotPairedWarning: StateFlow = _hasShownNotPairedWarning.asStateFlow() diff --git a/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt b/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt index 9ba83a894..930240923 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/connections/components/CurrentlyConnectedInfo.kt @@ -39,7 +39,6 @@ import androidx.compose.ui.unit.dp import org.meshtastic.core.database.model.Node import org.meshtastic.core.strings.R import org.meshtastic.core.ui.component.MaterialBatteryInfo -import org.meshtastic.core.ui.component.MaterialBluetoothSignalInfo import org.meshtastic.core.ui.component.NodeChip import org.meshtastic.core.ui.theme.AppTheme import org.meshtastic.core.ui.theme.StatusColors.StatusRed @@ -54,7 +53,6 @@ fun CurrentlyConnectedInfo( onNavigateToNodeDetails: (Int) -> Unit, onClickDisconnect: () -> Unit, modifier: Modifier = Modifier, - bluetoothRssi: Int? = null, ) { Column(modifier = modifier) { Row( @@ -63,9 +61,6 @@ fun CurrentlyConnectedInfo( verticalAlignment = Alignment.CenterVertically, ) { MaterialBatteryInfo(level = node.batteryLevel, voltage = node.voltage) - if (bluetoothRssi != null) { - MaterialBluetoothSignalInfo(rssi = bluetoothRssi) - } } Row(verticalAlignment = Alignment.CenterVertically, horizontalArrangement = Arrangement.spacedBy(8.dp)) { Column( @@ -122,7 +117,6 @@ private fun CurrentlyConnectedInfoPreview() { .setRelativeHumidity(60f) .build(), ), - bluetoothRssi = -75, // Example RSSI for signal preview onNavigateToNodeDetails = {}, onClickDisconnect = {}, ) diff --git a/core/service/src/main/kotlin/org/meshtastic/core/service/ServiceRepository.kt b/core/service/src/main/kotlin/org/meshtastic/core/service/ServiceRepository.kt index 1adad9bf9..03041c4d6 100644 --- a/core/service/src/main/kotlin/org/meshtastic/core/service/ServiceRepository.kt +++ b/core/service/src/main/kotlin/org/meshtastic/core/service/ServiceRepository.kt @@ -49,15 +49,6 @@ class ServiceRepository @Inject constructor() { _connectionState.value = connectionState } - // Current bluetooth link RSSI (dBm). Null if not connected or not a bluetooth interface. - private val _bluetoothRssi = MutableStateFlow(null) - val bluetoothRssi: StateFlow - get() = _bluetoothRssi - - fun setBluetoothRssi(rssi: Int?) { - _bluetoothRssi.value = rssi - } - private val _clientNotification = MutableStateFlow(null) val clientNotification: StateFlow get() = _clientNotification