From 41d0315b637fa8db66ccddd1a81adc8f9be4be73 Mon Sep 17 00:00:00 2001 From: andrekir Date: Sat, 6 May 2023 08:08:17 -0300 Subject: [PATCH] fix: handle deleted channels in ChannelSet DataStore adds `removeSettings` method to delete channels with `Role.DISABLED` --- .../datastore/ChannelSetRepository.kt | 26 +++++++++++++++---- .../geeksville/mesh/service/MeshService.kt | 24 ++++------------- 2 files changed, 26 insertions(+), 24 deletions(-) diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt index fcc17edd..74d0122b 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/ChannelSetRepository.kt @@ -7,7 +7,7 @@ import com.geeksville.mesh.ChannelProtos import com.geeksville.mesh.ConfigProtos import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.catch -import kotlinx.coroutines.flow.first +import kotlinx.coroutines.flow.firstOrNull import java.io.IOException import javax.inject.Inject @@ -40,14 +40,23 @@ class ChannelSetRepository @Inject constructor( } } - suspend fun addSettings(channel: ChannelProtos.Channel) { + /** + * Updates the ChannelSettings list with the provided channel and returns the index of the + * admin channel after the update (if not found, returns 0). + */ + suspend fun updateChannelSettings(channel: ChannelProtos.Channel): Int { channelSetStore.updateData { preference -> if (preference.settingsCount > channel.index) { - preference.toBuilder().setSettings(channel.index, channel.settings).build() + if (channel.role == ChannelProtos.Channel.Role.DISABLED) { + preference.toBuilder().removeSettings(channel.index).build() + } else { + preference.toBuilder().setSettings(channel.index, channel.settings).build() + } } else { - preference.toBuilder().addSettings(channel.settings).build() + preference.toBuilder().addSettings(channel.index, channel.settings).build() } } + return getAdminChannel() } suspend fun addAllSettings(channelSet: ChannelSet) { @@ -62,6 +71,13 @@ class ChannelSetRepository @Inject constructor( } } - suspend fun fetchInitialChannelSet() = channelSetStore.data.first() + /** + * Returns the index of the admin channel (or 0 if not found). + */ + private suspend fun getAdminChannel(): Int = fetchInitialChannelSet()?.settingsList + ?.indexOfFirst { it.name.lowercase() == "admin" } + ?.coerceAtLeast(0) ?: 0 + + suspend fun fetchInitialChannelSet() = channelSetStore.data.firstOrNull() } 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 29e35e7a..e25808b5 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -963,11 +963,8 @@ class MeshService : Service(), Logging { } } - private fun addChannelSettings(ch: ChannelProtos.Channel) { - if (ch.index == 0 || ch.settings.name.lowercase() == "admin") adminChannelIndex = ch.index - serviceScope.handledLaunch { - channelSetRepository.addSettings(ch) - } + private fun updateChannelSettings(ch: ChannelProtos.Channel) = serviceScope.handledLaunch { + adminChannelIndex = channelSetRepository.updateChannelSettings(ch) } private fun currentSecond() = (System.currentTimeMillis() / 1000).toInt() @@ -1207,7 +1204,7 @@ class MeshService : Service(), Logging { ch.toString() ) insertMeshLog(packetToSave) - if (ch.role != ChannelProtos.Channel.Role.DISABLED) addChannelSettings(ch) + if (ch.role != ChannelProtos.Channel.Role.DISABLED) updateChannelSettings(ch) } /** @@ -1407,13 +1404,6 @@ class MeshService : Service(), Logging { }.forEach(::requestConfig) } - private fun setChannel(ch: ChannelProtos.Channel) { - if (ch.index == 0 || ch.settings.name.lowercase() == "admin") adminChannelIndex = ch.index - sendToRadio(newMeshPacketTo(myNodeNum).buildAdminPacket(wantResponse = true) { - setChannel = ch - }) - } - /** * Start the modern (REV2) API configuration flow */ @@ -1725,17 +1715,13 @@ class MeshService : Service(), Logging { } override fun setChannel(payload: ByteArray?) = toRemoteExceptions { - with(ChannelProtos.Channel.parseFrom(payload)) { - if (index == 0 || settings.name.lowercase() == "admin") adminChannelIndex = index - } setRemoteChannel(myNodeNum, payload) } override fun setRemoteChannel(destNum: Int, payload: ByteArray?) = toRemoteExceptions { val channel = ChannelProtos.Channel.parseFrom(payload) - sendToRadio(newMeshPacketTo(destNum).buildAdminPacket(wantResponse = true) { - setChannel = channel - }) + sendToRadio(newMeshPacketTo(destNum).buildAdminPacket { setChannel = channel }) + if (destNum == myNodeNum) updateChannelSettings(channel) // Update our local copy } override fun getRemoteChannel(id: Int, destNum: Int, index: Int) = toRemoteExceptions {