diff --git a/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt b/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt index 5b9bc9887..f595a06e6 100644 --- a/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt @@ -118,16 +118,8 @@ constructor( suspend fun upsert(node: NodeEntity) = withContext(dispatchers.io) { nodeInfoDao.upsert(node) } - suspend fun installMyNodeInfo(mi: MyNodeEntity) = withContext(dispatchers.io) { - nodeInfoDao.clearMyNodeInfo() - nodeInfoDao.setMyNodeInfo(mi) - nodeInfoDao.clearNodeInfo() - } - - suspend fun installNodeDb(nodes: List) = withContext(dispatchers.io) { - nodeInfoDao.clearNodeInfo() - nodeInfoDao.putAll(nodes) - } + suspend fun installConfig(mi: MyNodeEntity, nodes: List) = + withContext(dispatchers.io) { nodeInfoDao.installConfig(mi, nodes) } suspend fun clearNodeDB() = withContext(dispatchers.io) { nodeInfoDao.clearNodeInfo() } 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 a9bca546f..f92d285c1 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -77,9 +77,6 @@ import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job import kotlinx.coroutines.delay -import kotlinx.coroutines.flow.MutableStateFlow -import kotlinx.coroutines.flow.StateFlow -import kotlinx.coroutines.flow.asStateFlow import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flatMapLatest @@ -217,7 +214,6 @@ class MeshService : val absoluteMinDeviceVersion = DeviceVersion(BuildConfig.ABS_MIN_FW_VERSION) private var configNonce = 1 - private const val CONFIG_WAIT_MS = 250L } private var previousSummary: String? = null @@ -323,9 +319,6 @@ class MeshService : override fun onCreate() { super.onCreate() - - _lastAddress.value = meshPrefs.deviceAddress ?: NO_DEVICE_SELECTED - info("Creating mesh service") serviceNotifications.initChannels() // Switch to the IO thread @@ -1406,6 +1399,7 @@ class MeshService : } else { ConnectionState.DISCONNECTED } + ConnectionState.DISCONNECTED -> ConnectionState.DISCONNECTED } onConnectionChanged(effectiveState) @@ -1415,31 +1409,41 @@ class MeshService : PayloadVariantCase.entries.associateWith { variant: PayloadVariantCase -> when (variant) { PayloadVariantCase.PACKET -> { proto: MeshProtos.FromRadio -> handleReceivedMeshPacket(proto.packet) } + PayloadVariantCase.CONFIG_COMPLETE_ID -> { proto: MeshProtos.FromRadio -> handleConfigComplete(proto.configCompleteId) } + PayloadVariantCase.MY_INFO -> { proto: MeshProtos.FromRadio -> handleMyInfo(proto.myInfo) } PayloadVariantCase.NODE_INFO -> { proto: MeshProtos.FromRadio -> handleNodeInfo(proto.nodeInfo) } + PayloadVariantCase.CHANNEL -> { proto: MeshProtos.FromRadio -> handleChannel(proto.channel) } PayloadVariantCase.CONFIG -> { proto: MeshProtos.FromRadio -> handleDeviceConfig(proto.config) } + PayloadVariantCase.MODULECONFIG -> { proto: MeshProtos.FromRadio -> handleModuleConfig(proto.moduleConfig) } + PayloadVariantCase.QUEUESTATUS -> { proto: MeshProtos.FromRadio -> packetHandler.handleQueueStatus((proto.queueStatus)) } + PayloadVariantCase.METADATA -> { proto: MeshProtos.FromRadio -> handleMetadata(proto.metadata) } PayloadVariantCase.MQTTCLIENTPROXYMESSAGE -> { proto: MeshProtos.FromRadio -> handleMqttProxyMessage(proto.mqttClientProxyMessage) } + PayloadVariantCase.DEVICEUICONFIG -> { proto: MeshProtos.FromRadio -> handleDeviceUiConfig(proto.deviceuiConfig) } + PayloadVariantCase.FILEINFO -> { proto: MeshProtos.FromRadio -> handleFileInfo(proto.fileInfo) } PayloadVariantCase.CLIENTNOTIFICATION -> { proto: MeshProtos.FromRadio -> handleClientNotification(proto.clientNotification) } + PayloadVariantCase.LOG_RECORD -> { proto: MeshProtos.FromRadio -> handleLogReord(proto.logRecord) } + PayloadVariantCase.REBOOTED -> { proto: MeshProtos.FromRadio -> handleRebooted(proto.rebooted) } PayloadVariantCase.XMODEMPACKET -> { proto: MeshProtos.FromRadio -> handleXmodemPacket(proto.xmodemPacket) @@ -1818,25 +1822,15 @@ class MeshService : } else { myNodeInfo = newMyNodeInfo } - serviceScope.handledLaunch { - delay(CONFIG_WAIT_MS) - radioInterfaceService.keepAlive() - delay(CONFIG_WAIT_MS) - } // This was our config request if (newNodes.isEmpty()) { errormsg("Did not receive a valid node info") } else { newNodes.forEach(::installNodeInfo) - newNodes.clear() // Just to save RAM ;-) - - serviceScope.handledLaunch { - nodeRepository.installMyNodeInfo(myNodeInfo!!) - nodeRepository.installNodeDb(nodeDBbyNodeNum.values.toList()) - } + newNodes.clear() + serviceScope.handledLaunch { nodeRepository.installConfig(myNodeInfo!!, nodeDBbyNodeNum.values.toList()) } haveNodeDB = true // we now have nodes from real hardware - sendAnalytics() onHasSettings() onNodeDBChanged() @@ -2004,10 +1998,6 @@ class MeshService : rememberReaction(packet.copy { from = myNodeNum }) } - private val _lastAddress: MutableStateFlow = MutableStateFlow(null) - val lastAddress: StateFlow - get() = _lastAddress.asStateFlow() - fun clearDatabases() = serviceScope.handledLaunch { debug("Clearing nodeDB") nodeRepository.clearNodeDB() @@ -2015,28 +2005,14 @@ class MeshService : private fun updateLastAddress(deviceAddr: String?) { debug("setDeviceAddress: Passing through device change to radio service: ${deviceAddr.anonymize}") - when (deviceAddr) { - null, - "", - -> { - debug("SetDeviceAddress: No previous device address, setting new one") - _lastAddress.value = deviceAddr - meshPrefs.deviceAddress = deviceAddr - } - - lastAddress.value, - NO_DEVICE_SELECTED, - -> { - debug("SetDeviceAddress: Device address is the none or same, ignoring") - } - - else -> { - debug("SetDeviceAddress: Device address changed from $lastAddress to $deviceAddr") - _lastAddress.value = deviceAddr - meshPrefs.deviceAddress = deviceAddr - clearDatabases() - clearNotifications() - } + if (deviceAddr == meshPrefs.deviceAddress || deviceAddr == NO_DEVICE_SELECTED) { + debug("SetDeviceAddress: Device address is the none or same, ignoring") + return + } else { + debug("SetDeviceAddress: Device address changed from ${meshPrefs.deviceAddress} to $deviceAddr") + meshPrefs.deviceAddress = deviceAddr + clearDatabases() + clearNotifications() } } @@ -2050,13 +2026,7 @@ class MeshService : override fun setDeviceAddress(deviceAddr: String?) = toRemoteExceptions { debug("Passing through device change to radio service: ${deviceAddr.anonymize}") updateLastAddress(deviceAddr) - val res = radioInterfaceService.setDeviceAddress(deviceAddr) - if (res) { - discardNodeDB() - } else { - serviceBroadcasts.broadcastConnection() - } - res + radioInterfaceService.setDeviceAddress(deviceAddr) } // Note: bound methods don't get properly exception caught/logged, so do that with a diff --git a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt index a5d98e876..ea1a13ba0 100644 --- a/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt +++ b/core/database/src/main/kotlin/org/meshtastic/core/database/dao/NodeInfoDao.kt @@ -221,4 +221,11 @@ interface NodeInfoDao { @Query("UPDATE nodes SET notes = :notes WHERE num = :num") fun setNodeNotes(num: Int, notes: String) + + @Transaction + fun installConfig(mi: MyNodeEntity, nodes: List) { + clearMyNodeInfo() + setMyNodeInfo(mi) + putAll(nodes.map { getVerifiedNodeForUpsert(it) }) + } } diff --git a/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt index a268bd6bd..a0499a7e6 100644 --- a/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt +++ b/core/prefs/src/main/kotlin/org/meshtastic/core/prefs/mesh/MeshPrefs.kt @@ -34,7 +34,7 @@ interface MeshPrefs { @Singleton class MeshPrefsImpl @Inject constructor(@MeshSharedPreferences private val prefs: SharedPreferences) : MeshPrefs { - override var deviceAddress: String? by NullableStringPrefDelegate(prefs, "device_address", null) + override var deviceAddress: String? by NullableStringPrefDelegate(prefs, "device_address", NO_DEVICE_SELECTED) override fun shouldProvideNodeLocation(nodeNum: Int?): Boolean = prefs.getBoolean(provideLocationKey(nodeNum), false) @@ -45,3 +45,5 @@ class MeshPrefsImpl @Inject constructor(@MeshSharedPreferences private val prefs private fun provideLocationKey(nodeNum: Int?) = "provide-location-$nodeNum" } + +private const val NO_DEVICE_SELECTED = "n"