mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-04-20 22:23:37 +00:00
feat: add traceroute (#620)
This commit is contained in:
parent
72c278c92c
commit
da5f1d529d
8 changed files with 95 additions and 2 deletions
|
|
@ -56,6 +56,7 @@ class NodeDB(private val ui: UIViewModel) {
|
|||
private val _nodes = MutableLiveData<Map<String, NodeInfo>>(mapOf(*(if (seedWithTestNodes) testNodes else listOf()).map { it.user!!.id to it }
|
||||
.toTypedArray()))
|
||||
val nodes: LiveData<Map<String, NodeInfo>> get() = _nodes
|
||||
val nodesByNum get() = nodes.value?.values?.associateBy { it.num }
|
||||
|
||||
fun setNodes(nodes: Map<String, NodeInfo>) {
|
||||
_nodes.value = nodes
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@ import com.geeksville.mesh.util.positionToMeter
|
|||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.combine
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
|
|
@ -44,6 +45,7 @@ import kotlinx.coroutines.flow.mapLatest
|
|||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
import kotlinx.coroutines.withTimeoutOrNull
|
||||
import org.osmdroid.bonuspack.kml.KmlDocument
|
||||
import org.osmdroid.views.MapView
|
||||
import org.osmdroid.views.overlay.FolderOverlay
|
||||
|
|
@ -172,6 +174,44 @@ class UIViewModel @Inject constructor(
|
|||
.filterValues { it.data.waypoint!!.expire > System.currentTimeMillis() / 1000 }
|
||||
}.asLiveData()
|
||||
|
||||
private val _packetResponse = MutableStateFlow<MeshLog?>(null)
|
||||
val packetResponse: StateFlow<MeshLog?> = _packetResponse
|
||||
|
||||
/**
|
||||
* Called immediately after activity observes packetResponse
|
||||
*/
|
||||
fun clearPacketResponse() {
|
||||
_packetResponse.tryEmit(null)
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the packet response to a given [packetId] or null after [timeout] milliseconds
|
||||
*/
|
||||
private suspend fun getResponseBy(packetId: Int, timeout: Long) = withContext(Dispatchers.IO) {
|
||||
withTimeoutOrNull(timeout) {
|
||||
var packet: MeshLog? = null
|
||||
while (packet == null) {
|
||||
packet = _meshLog.value.lastOrNull { it.meshPacket?.decoded?.requestId == packetId }
|
||||
if (packet == null) delay(1000)
|
||||
}
|
||||
packet
|
||||
}
|
||||
}
|
||||
|
||||
fun requestTraceroute(destNum: Int) = viewModelScope.launch {
|
||||
meshService?.let { service ->
|
||||
try {
|
||||
val packetId = service.packetId
|
||||
val waitFactor = (service.nodes.count { it.isOnline } - 1)
|
||||
.coerceAtMost(config.lora.hopLimit)
|
||||
service.requestTraceroute(packetId, destNum)
|
||||
_packetResponse.emit(getResponseBy(packetId, 20000L * waitFactor))
|
||||
} catch (ex: RemoteException) {
|
||||
errormsg("Request traceroute error: ${ex.message}")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun generatePacketId(): Int? {
|
||||
return try {
|
||||
meshService?.packetId
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue