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 eef931d4b..4a1bc94f9 100644 --- a/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/database/NodeRepository.kt @@ -103,7 +103,7 @@ class NodeRepository @Inject constructor( ).mapLatest { list -> list.map { it.toModel() } }.flowOn(dispatchers.io).conflate() suspend fun upsert(node: NodeEntity) = withContext(dispatchers.io) { - nodeInfoDao.upsertCheckKeyMatch(node) + nodeInfoDao.upsert(node) } suspend fun installNodeDB(mi: MyNodeEntity, nodes: List) = withContext(dispatchers.io) { @@ -116,6 +116,10 @@ class NodeRepository @Inject constructor( nodeInfoDao.putAll(nodes) } + suspend fun clearNodeDB() = withContext(dispatchers.io) { + nodeInfoDao.clearNodeInfo() + } + suspend fun deleteNode(num: Int) = withContext(dispatchers.io) { nodeInfoDao.deleteNode(num) nodeInfoDao.deleteMetadata(num) diff --git a/app/src/main/java/com/geeksville/mesh/database/dao/NodeInfoDao.kt b/app/src/main/java/com/geeksville/mesh/database/dao/NodeInfoDao.kt index 0f41091f8..3dd438a94 100644 --- a/app/src/main/java/com/geeksville/mesh/database/dao/NodeInfoDao.kt +++ b/app/src/main/java/com/geeksville/mesh/database/dao/NodeInfoDao.kt @@ -17,7 +17,6 @@ package com.geeksville.mesh.database.dao -import android.util.Log import androidx.room.Dao import androidx.room.Insert import androidx.room.MapColumn @@ -25,13 +24,14 @@ import androidx.room.OnConflictStrategy import androidx.room.Query import androidx.room.Transaction import androidx.room.Upsert +import com.geeksville.mesh.android.BuildUtils.warn +import com.geeksville.mesh.copy import com.geeksville.mesh.database.entity.MetadataEntity import com.geeksville.mesh.database.entity.MyNodeEntity import com.geeksville.mesh.database.entity.NodeEntity import com.geeksville.mesh.database.entity.NodeWithRelations import kotlinx.coroutines.flow.Flow -private const val TAG = "NodeInfoDao" @Suppress("TooManyFunctions") @Dao interface NodeInfoDao { @@ -108,21 +108,39 @@ interface NodeInfoDao { ): Flow> @Upsert - fun upsert(node: NodeEntity) - - fun upsertCheckKeyMatch(node: NodeEntity) { - val existingNode = getNodeByNum(node.num) - if (existingNode != null && existingNode.user.publicKey != node.user.publicKey) { - Log.w(TAG, "Node ${node.num} has changed its public key") - val user = - node.user.toBuilder().setPublicKey(NodeEntity.ERROR_BYTE_STRING).build() - node.user = user + fun upsert(node: NodeEntity) { + val found = getNodeByNum(node.num)?.node + found?.let { + val keyMatch = !it.hasPKC || it.user.publicKey == node.user.publicKey + it.user = if (keyMatch) { + node.user + } else { + node.user.copy { + warn("Public key mismatch from $longName ($shortName)") + publicKey = NodeEntity.ERROR_BYTE_STRING + } + } } - upsert(node) + doUpsert(node) } - @Transaction + + @Insert(onConflict = OnConflictStrategy.REPLACE) fun putAll(nodes: List) { - nodes.forEach { upsertCheckKeyMatch(it) } + nodes.forEach { node -> + val found = getNodeByNum(node.num)?.node + found?.let { + val keyMatch = !it.hasPKC || it.user.publicKey == node.user.publicKey + it.user = if (keyMatch) { + node.user + } else { + node.user.copy { + warn("Public key mismatch from $longName ($shortName)") + publicKey = NodeEntity.ERROR_BYTE_STRING + } + } + } + } + doPutAll(nodes) } @Query("DELETE FROM nodes") @@ -137,6 +155,13 @@ interface NodeInfoDao { @Query("DELETE FROM metadata WHERE num=:num") fun deleteMetadata(num: Int) - @Query("SELECT * FROM nodes WHERE num = :num") - fun getNodeByNum(num: Int): NodeEntity? + @Query("SELECT * FROM nodes WHERE num=:num") + @Transaction + fun getNodeByNum(num: Int): NodeWithRelations? + + @Upsert + fun doUpsert(node: NodeEntity) + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun doPutAll(nodes: List) } diff --git a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt index 35cec7091..a081a9f68 100644 --- a/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt +++ b/app/src/main/java/com/geeksville/mesh/repository/datastore/RadioConfigRepository.kt @@ -89,6 +89,10 @@ class RadioConfigRepository @Inject constructor( nodeDB.insertMetadata(MetadataEntity(fromNum, metadata)) } + suspend fun clearNodeDB() { + nodeDB.clearNodeDB() + } + /** * Flow representing the [ChannelSet] data store. */ 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 59e4659f8..1c42f9dc8 100644 --- a/app/src/main/java/com/geeksville/mesh/service/MeshService.kt +++ b/app/src/main/java/com/geeksville/mesh/service/MeshService.kt @@ -904,9 +904,13 @@ class MeshService : Service(), Logging { val newNode = (it.isUnknownUser && p.hwModel != MeshProtos.HardwareModel.UNSET) val keyMatch = !it.hasPKC || it.user.publicKey == p.publicKey - it.user = if (keyMatch) p else p.copy { - warn("Public key mismatch from $longName ($shortName)") - publicKey = it.errorByteString + it.user = if (keyMatch) { + p + } else { + p.copy { + warn("Public key mismatch from $longName ($shortName)") + publicKey = NodeEntity.ERROR_BYTE_STRING + } } it.longName = p.longName it.shortName = p.shortName diff --git a/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfigViewModel.kt b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfigViewModel.kt index 4bd7be2a0..e01fd7523 100644 --- a/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfigViewModel.kt +++ b/app/src/main/java/com/geeksville/mesh/ui/radioconfig/RadioConfigViewModel.kt @@ -304,17 +304,27 @@ class RadioConfigViewModel @Inject constructor( "Request reboot error" ) - private fun requestFactoryReset(destNum: Int) = request( - destNum, - { service, packetId, dest -> service.requestFactoryReset(packetId, dest) }, - "Request factory reset error" - ) + private fun requestFactoryReset(destNum: Int) { + request( + destNum, + { service, packetId, dest -> service.requestFactoryReset(packetId, dest) }, + "Request factory reset error" + ) + if (destNum == myNodeNum) { + viewModelScope.launch { radioConfigRepository.clearNodeDB() } + } + } - private fun requestNodedbReset(destNum: Int) = request( - destNum, - { service, packetId, dest -> service.requestNodedbReset(packetId, dest) }, - "Request NodeDB reset error" - ) + private fun requestNodedbReset(destNum: Int) { + request( + destNum, + { service, packetId, dest -> service.requestNodedbReset(packetId, dest) }, + "Request NodeDB reset error" + ) + if (destNum == myNodeNum) { + viewModelScope.launch { radioConfigRepository.clearNodeDB() } + } + } private fun sendAdminRequest(destNum: Int) { val route = radioConfigState.value.route