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 0a4a15d94..fe12885a5 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 @@ -31,6 +31,7 @@ import com.geeksville.mesh.android.prefs.RadioPrefs import com.geeksville.mesh.concurrent.handledLaunch import com.geeksville.mesh.repository.bluetooth.BluetoothRepository import com.geeksville.mesh.repository.network.NetworkRepository +import com.geeksville.mesh.service.ConnectionState import com.geeksville.mesh.util.anonymize import com.geeksville.mesh.util.ignoreException import com.geeksville.mesh.util.toRemoteExceptions @@ -74,8 +75,8 @@ constructor( private val interfaceFactory: InterfaceFactory, ) : Logging { - private val _connectionState = MutableStateFlow(RadioServiceConnectionState()) - val connectionState = _connectionState.asStateFlow() + private val _connectionState = MutableStateFlow(ConnectionState.DISCONNECTED) + val connectionState: StateFlow = _connectionState.asStateFlow() private val _receivedData = MutableSharedFlow() val receivedData: SharedFlow = _receivedData @@ -86,7 +87,7 @@ constructor( private val logSends = false private val logReceives = false - private lateinit var sentPacketsLog: BinaryLogFile // inited in onCreate + private lateinit var sentPacketsLog: BinaryLogFile private lateinit var receivedPacketsLog: BinaryLogFile val mockInterfaceAddress: String by lazy { toInterfaceAddress(InterfaceId.MOCK, "") } @@ -103,9 +104,6 @@ constructor( */ private var isStarted = false - // true if our interface is currently connected to a device - private var isConnected = false - private fun initStateListeners() { bluetoothRepository.state .onEach { state -> @@ -195,11 +193,10 @@ constructor( } } - private fun broadcastConnectionChanged(isConnected: Boolean, isPermanent: Boolean) { - debug("Broadcasting connection=$isConnected") - + private fun broadcastConnectionChanged(newState: ConnectionState) { + debug("Broadcasting connection state change to $newState") processLifecycle.coroutineScope.launch(dispatchers.default) { - _connectionState.emit(RadioServiceConnectionState(isConnected, isPermanent)) + _connectionState.emit(newState) } } @@ -227,16 +224,15 @@ constructor( } fun onConnect() { - if (!isConnected) { - isConnected = true - broadcastConnectionChanged(isConnected = true, isPermanent = false) + if (_connectionState.value != ConnectionState.CONNECTED) { + broadcastConnectionChanged(ConnectionState.CONNECTED) } } fun onDisconnect(isPermanent: Boolean) { - if (isConnected) { - isConnected = false - broadcastConnectionChanged(isConnected = false, isPermanent = isPermanent) + val newTargetState = if (isPermanent) ConnectionState.DISCONNECTED else ConnectionState.DEVICE_SLEEP + if (_connectionState.value != newTargetState) { + broadcastConnectionChanged(newTargetState) } } diff --git a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioServiceConnectionState.kt b/app/src/main/java/com/geeksville/mesh/repository/radio/RadioServiceConnectionState.kt deleted file mode 100644 index a32465be4..000000000 --- a/app/src/main/java/com/geeksville/mesh/repository/radio/RadioServiceConnectionState.kt +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2025 Meshtastic LLC - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -package com.geeksville.mesh.repository.radio - -data class RadioServiceConnectionState( - val isConnected: Boolean = false, - val isPermanent: Boolean = false -) 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 a28f8f379..88bc52a40 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -79,7 +79,6 @@ import com.geeksville.mesh.repository.datastore.RadioConfigRepository import com.geeksville.mesh.repository.location.LocationRepository import com.geeksville.mesh.repository.network.MQTTRepository import com.geeksville.mesh.repository.radio.RadioInterfaceService -import com.geeksville.mesh.repository.radio.RadioServiceConnectionState import com.geeksville.mesh.telemetry import com.geeksville.mesh.user import com.geeksville.mesh.util.anonymize @@ -1373,19 +1372,18 @@ class MeshService : } } - private fun onRadioConnectionState(state: RadioServiceConnectionState) { - // sleep now disabled by default on ESP32, permanent is true unless light sleep enabled + private fun onRadioConnectionState(newState: ConnectionState) { + // Respect light sleep (lsEnabled) setting: if device reports sleep + // but lsEnabled is false, treat as disconnected. val isRouter = localConfig.device.role == ConfigProtos.Config.DeviceConfig.Role.ROUTER val lsEnabled = localConfig.power.isPowerSaving || isRouter - val connected = state.isConnected - val permanent = state.isPermanent || !lsEnabled - onConnectionChanged( - when { - connected -> ConnectionState.CONNECTED - permanent -> ConnectionState.DISCONNECTED - else -> ConnectionState.DEVICE_SLEEP - }, - ) + + val effectiveState = when (newState) { + ConnectionState.CONNECTED -> ConnectionState.CONNECTED + ConnectionState.DEVICE_SLEEP -> if (lsEnabled) ConnectionState.DEVICE_SLEEP else ConnectionState.DISCONNECTED + ConnectionState.DISCONNECTED -> ConnectionState.DISCONNECTED + } + onConnectionChanged(effectiveState) } private val packetHandlers: Map Unit)> by lazy {