kopia lustrzana https://github.com/meshtastic/Meshtastic-Android
Merge 4c979a3117
into 25fe0a1e05
commit
ab9f738c43
|
@ -103,7 +103,7 @@ class NodeRepository @Inject constructor(
|
||||||
).mapLatest { list -> list.map { it.toModel() } }.flowOn(dispatchers.io).conflate()
|
).mapLatest { list -> list.map { it.toModel() } }.flowOn(dispatchers.io).conflate()
|
||||||
|
|
||||||
suspend fun upsert(node: NodeEntity) = withContext(dispatchers.io) {
|
suspend fun upsert(node: NodeEntity) = withContext(dispatchers.io) {
|
||||||
nodeInfoDao.upsertCheckKeyMatch(node)
|
nodeInfoDao.upsert(node)
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun installNodeDB(mi: MyNodeEntity, nodes: List<NodeEntity>) = withContext(dispatchers.io) {
|
suspend fun installNodeDB(mi: MyNodeEntity, nodes: List<NodeEntity>) = withContext(dispatchers.io) {
|
||||||
|
@ -116,6 +116,10 @@ class NodeRepository @Inject constructor(
|
||||||
nodeInfoDao.putAll(nodes)
|
nodeInfoDao.putAll(nodes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun clearNodeDB() = withContext(dispatchers.io) {
|
||||||
|
nodeInfoDao.clearNodeInfo()
|
||||||
|
}
|
||||||
|
|
||||||
suspend fun deleteNode(num: Int) = withContext(dispatchers.io) {
|
suspend fun deleteNode(num: Int) = withContext(dispatchers.io) {
|
||||||
nodeInfoDao.deleteNode(num)
|
nodeInfoDao.deleteNode(num)
|
||||||
nodeInfoDao.deleteMetadata(num)
|
nodeInfoDao.deleteMetadata(num)
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
|
|
||||||
package com.geeksville.mesh.database.dao
|
package com.geeksville.mesh.database.dao
|
||||||
|
|
||||||
import android.util.Log
|
|
||||||
import androidx.room.Dao
|
import androidx.room.Dao
|
||||||
import androidx.room.Insert
|
import androidx.room.Insert
|
||||||
import androidx.room.MapColumn
|
import androidx.room.MapColumn
|
||||||
|
@ -25,13 +24,14 @@ import androidx.room.OnConflictStrategy
|
||||||
import androidx.room.Query
|
import androidx.room.Query
|
||||||
import androidx.room.Transaction
|
import androidx.room.Transaction
|
||||||
import androidx.room.Upsert
|
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.MetadataEntity
|
||||||
import com.geeksville.mesh.database.entity.MyNodeEntity
|
import com.geeksville.mesh.database.entity.MyNodeEntity
|
||||||
import com.geeksville.mesh.database.entity.NodeEntity
|
import com.geeksville.mesh.database.entity.NodeEntity
|
||||||
import com.geeksville.mesh.database.entity.NodeWithRelations
|
import com.geeksville.mesh.database.entity.NodeWithRelations
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
|
||||||
private const val TAG = "NodeInfoDao"
|
|
||||||
@Suppress("TooManyFunctions")
|
@Suppress("TooManyFunctions")
|
||||||
@Dao
|
@Dao
|
||||||
interface NodeInfoDao {
|
interface NodeInfoDao {
|
||||||
|
@ -108,21 +108,39 @@ interface NodeInfoDao {
|
||||||
): Flow<List<NodeWithRelations>>
|
): Flow<List<NodeWithRelations>>
|
||||||
|
|
||||||
@Upsert
|
@Upsert
|
||||||
fun upsert(node: NodeEntity)
|
fun upsert(node: NodeEntity) {
|
||||||
|
val found = getNodeByNum(node.num)?.node
|
||||||
fun upsertCheckKeyMatch(node: NodeEntity) {
|
found?.let {
|
||||||
val existingNode = getNodeByNum(node.num)
|
val keyMatch = !it.hasPKC || it.user.publicKey == node.user.publicKey
|
||||||
if (existingNode != null && existingNode.user.publicKey != node.user.publicKey) {
|
it.user = if (keyMatch) {
|
||||||
Log.w(TAG, "Node ${node.num} has changed its public key")
|
node.user
|
||||||
val user =
|
} else {
|
||||||
node.user.toBuilder().setPublicKey(NodeEntity.ERROR_BYTE_STRING).build()
|
node.user.copy {
|
||||||
node.user = user
|
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<NodeEntity>) {
|
fun putAll(nodes: List<NodeEntity>) {
|
||||||
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")
|
@Query("DELETE FROM nodes")
|
||||||
|
@ -137,6 +155,13 @@ interface NodeInfoDao {
|
||||||
@Query("DELETE FROM metadata WHERE num=:num")
|
@Query("DELETE FROM metadata WHERE num=:num")
|
||||||
fun deleteMetadata(num: Int)
|
fun deleteMetadata(num: Int)
|
||||||
|
|
||||||
@Query("SELECT * FROM nodes WHERE num = :num")
|
@Query("SELECT * FROM nodes WHERE num=:num")
|
||||||
fun getNodeByNum(num: Int): NodeEntity?
|
@Transaction
|
||||||
|
fun getNodeByNum(num: Int): NodeWithRelations?
|
||||||
|
|
||||||
|
@Upsert
|
||||||
|
fun doUpsert(node: NodeEntity)
|
||||||
|
|
||||||
|
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||||
|
fun doPutAll(nodes: List<NodeEntity>)
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,6 +89,10 @@ class RadioConfigRepository @Inject constructor(
|
||||||
nodeDB.insertMetadata(MetadataEntity(fromNum, metadata))
|
nodeDB.insertMetadata(MetadataEntity(fromNum, metadata))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun clearNodeDB() {
|
||||||
|
nodeDB.clearNodeDB()
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Flow representing the [ChannelSet] data store.
|
* Flow representing the [ChannelSet] data store.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -904,9 +904,13 @@ class MeshService : Service(), Logging {
|
||||||
val newNode = (it.isUnknownUser && p.hwModel != MeshProtos.HardwareModel.UNSET)
|
val newNode = (it.isUnknownUser && p.hwModel != MeshProtos.HardwareModel.UNSET)
|
||||||
|
|
||||||
val keyMatch = !it.hasPKC || it.user.publicKey == p.publicKey
|
val keyMatch = !it.hasPKC || it.user.publicKey == p.publicKey
|
||||||
it.user = if (keyMatch) p else p.copy {
|
it.user = if (keyMatch) {
|
||||||
warn("Public key mismatch from $longName ($shortName)")
|
p
|
||||||
publicKey = it.errorByteString
|
} else {
|
||||||
|
p.copy {
|
||||||
|
warn("Public key mismatch from $longName ($shortName)")
|
||||||
|
publicKey = NodeEntity.ERROR_BYTE_STRING
|
||||||
|
}
|
||||||
}
|
}
|
||||||
it.longName = p.longName
|
it.longName = p.longName
|
||||||
it.shortName = p.shortName
|
it.shortName = p.shortName
|
||||||
|
|
|
@ -304,17 +304,27 @@ class RadioConfigViewModel @Inject constructor(
|
||||||
"Request reboot error"
|
"Request reboot error"
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun requestFactoryReset(destNum: Int) = request(
|
private fun requestFactoryReset(destNum: Int) {
|
||||||
destNum,
|
request(
|
||||||
{ service, packetId, dest -> service.requestFactoryReset(packetId, dest) },
|
destNum,
|
||||||
"Request factory reset error"
|
{ service, packetId, dest -> service.requestFactoryReset(packetId, dest) },
|
||||||
)
|
"Request factory reset error"
|
||||||
|
)
|
||||||
|
if (destNum == myNodeNum) {
|
||||||
|
viewModelScope.launch { radioConfigRepository.clearNodeDB() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun requestNodedbReset(destNum: Int) = request(
|
private fun requestNodedbReset(destNum: Int) {
|
||||||
destNum,
|
request(
|
||||||
{ service, packetId, dest -> service.requestNodedbReset(packetId, dest) },
|
destNum,
|
||||||
"Request NodeDB reset error"
|
{ service, packetId, dest -> service.requestNodedbReset(packetId, dest) },
|
||||||
)
|
"Request NodeDB reset error"
|
||||||
|
)
|
||||||
|
if (destNum == myNodeNum) {
|
||||||
|
viewModelScope.launch { radioConfigRepository.clearNodeDB() }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private fun sendAdminRequest(destNum: Int) {
|
private fun sendAdminRequest(destNum: Int) {
|
||||||
val route = radioConfigState.value.route
|
val route = radioConfigState.value.route
|
||||||
|
|
Ładowanie…
Reference in New Issue