2024-11-26 08:38:12 -03:00
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2024 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 <https://www.gnu.org/licenses/>.
|
|
|
|
|
*/
|
|
|
|
|
|
2020-02-17 13:34:52 -08:00
|
|
|
package com.geeksville.mesh.model
|
|
|
|
|
|
2024-02-06 20:03:15 -03:00
|
|
|
import androidx.lifecycle.Lifecycle
|
|
|
|
|
import androidx.lifecycle.coroutineScope
|
2024-10-25 07:50:34 -03:00
|
|
|
import com.geeksville.mesh.DataPacket
|
|
|
|
|
import com.geeksville.mesh.MeshProtos
|
2023-10-20 18:31:13 -03:00
|
|
|
import com.geeksville.mesh.database.dao.NodeInfoDao
|
2024-10-02 06:18:30 -03:00
|
|
|
import com.geeksville.mesh.database.entity.MyNodeEntity
|
2024-09-16 17:57:30 -03:00
|
|
|
import com.geeksville.mesh.database.entity.NodeEntity
|
2023-10-20 18:31:13 -03:00
|
|
|
import kotlinx.coroutines.Dispatchers
|
2023-09-05 08:19:26 -03:00
|
|
|
import kotlinx.coroutines.flow.MutableStateFlow
|
2023-10-20 18:31:13 -03:00
|
|
|
import kotlinx.coroutines.flow.StateFlow
|
2024-02-06 20:03:15 -03:00
|
|
|
import kotlinx.coroutines.flow.launchIn
|
|
|
|
|
import kotlinx.coroutines.flow.onEach
|
2023-10-20 18:31:13 -03:00
|
|
|
import kotlinx.coroutines.withContext
|
|
|
|
|
import javax.inject.Inject
|
|
|
|
|
import javax.inject.Singleton
|
|
|
|
|
|
|
|
|
|
@Singleton
|
|
|
|
|
class NodeDB @Inject constructor(
|
2024-02-06 20:03:15 -03:00
|
|
|
processLifecycle: Lifecycle,
|
2023-10-20 18:31:13 -03:00
|
|
|
private val nodeInfoDao: NodeInfoDao,
|
|
|
|
|
) {
|
2024-02-06 20:03:15 -03:00
|
|
|
// hardware info about our local device (can be null)
|
2024-10-02 06:18:30 -03:00
|
|
|
private val _myNodeInfo = MutableStateFlow<MyNodeEntity?>(null)
|
|
|
|
|
val myNodeInfo: StateFlow<MyNodeEntity?> get() = _myNodeInfo
|
2020-02-17 13:34:52 -08:00
|
|
|
|
2024-02-06 20:03:15 -03:00
|
|
|
// our node info
|
2024-09-21 15:45:10 -03:00
|
|
|
private val _ourNodeInfo = MutableStateFlow<NodeEntity?>(null)
|
|
|
|
|
val ourNodeInfo: StateFlow<NodeEntity?> get() = _ourNodeInfo
|
2020-02-25 10:48:54 -08:00
|
|
|
|
2023-09-05 08:19:26 -03:00
|
|
|
// The unique userId of our node
|
2024-02-06 20:03:15 -03:00
|
|
|
private val _myId = MutableStateFlow<String?>(null)
|
2023-10-20 18:31:13 -03:00
|
|
|
val myId: StateFlow<String?> get() = _myId
|
2022-04-22 17:22:06 -03:00
|
|
|
|
2024-09-16 17:57:30 -03:00
|
|
|
// A map from nodeNum to NodeEntity
|
|
|
|
|
private val _nodeDBbyNum = MutableStateFlow<Map<Int, NodeEntity>>(mapOf())
|
|
|
|
|
val nodeDBbyNum: StateFlow<Map<Int, NodeEntity>> get() = _nodeDBbyNum
|
2023-10-20 18:31:13 -03:00
|
|
|
|
2024-10-25 07:50:34 -03:00
|
|
|
fun getUser(nodeNum: Int): MeshProtos.User = getUser(DataPacket.nodeNumToDefaultId(nodeNum))
|
|
|
|
|
|
|
|
|
|
fun getUser(userId: String): MeshProtos.User =
|
|
|
|
|
nodeDBbyNum.value.values.find { it.user.id == userId }?.user
|
|
|
|
|
?: MeshProtos.User.newBuilder()
|
2024-10-25 18:54:01 -05:00
|
|
|
.setId(userId)
|
2024-10-25 07:50:34 -03:00
|
|
|
.setLongName("Meshtastic ${userId.takeLast(n = 4)}")
|
|
|
|
|
.setShortName(userId.takeLast(n = 4))
|
|
|
|
|
.setHwModel(MeshProtos.HardwareModel.UNSET)
|
|
|
|
|
.build()
|
2024-02-06 20:03:15 -03:00
|
|
|
|
|
|
|
|
init {
|
|
|
|
|
nodeInfoDao.getMyNodeInfo().onEach { _myNodeInfo.value = it }
|
|
|
|
|
.launchIn(processLifecycle.coroutineScope)
|
|
|
|
|
|
2024-03-20 08:40:32 -03:00
|
|
|
nodeInfoDao.nodeDBbyNum().onEach {
|
|
|
|
|
_nodeDBbyNum.value = it
|
2024-09-21 15:45:10 -03:00
|
|
|
val ourNodeInfo = it.values.firstOrNull()
|
2024-03-20 08:40:32 -03:00
|
|
|
_ourNodeInfo.value = ourNodeInfo
|
|
|
|
|
_myId.value = ourNodeInfo?.user?.id
|
|
|
|
|
}.launchIn(processLifecycle.coroutineScope)
|
2024-02-06 20:03:15 -03:00
|
|
|
}
|
|
|
|
|
|
2024-05-27 09:56:26 -03:00
|
|
|
fun getNodes(
|
|
|
|
|
sort: NodeSortOption = NodeSortOption.LAST_HEARD,
|
|
|
|
|
filter: String = "",
|
|
|
|
|
includeUnknown: Boolean = true,
|
|
|
|
|
) = nodeInfoDao.getNodes(
|
|
|
|
|
sort = sort.sqlValue,
|
|
|
|
|
filter = filter,
|
|
|
|
|
includeUnknown = includeUnknown,
|
|
|
|
|
)
|
|
|
|
|
|
2024-09-16 17:57:30 -03:00
|
|
|
suspend fun upsert(node: NodeEntity) = withContext(Dispatchers.IO) {
|
2024-02-06 20:03:15 -03:00
|
|
|
nodeInfoDao.upsert(node)
|
2022-04-22 17:22:06 -03:00
|
|
|
}
|
2023-09-05 08:19:26 -03:00
|
|
|
|
2024-10-02 06:18:30 -03:00
|
|
|
suspend fun installNodeDB(mi: MyNodeEntity, nodes: List<NodeEntity>) = withContext(Dispatchers.IO) {
|
2024-09-13 18:38:04 -03:00
|
|
|
nodeInfoDao.clearMyNodeInfo()
|
2024-10-02 06:18:30 -03:00
|
|
|
nodeInfoDao.setMyNodeInfo(mi) // set MyNodeEntity first
|
2024-09-13 18:38:04 -03:00
|
|
|
nodeInfoDao.clearNodeInfo()
|
2024-09-13 00:19:21 -03:00
|
|
|
nodeInfoDao.putAll(nodes)
|
2023-09-05 08:19:26 -03:00
|
|
|
}
|
2024-06-03 10:21:38 -03:00
|
|
|
|
|
|
|
|
suspend fun deleteNode(num: Int) = withContext(Dispatchers.IO) {
|
|
|
|
|
nodeInfoDao.deleteNode(num)
|
|
|
|
|
}
|
2023-09-05 08:19:26 -03:00
|
|
|
}
|