feat: add traceroute (#620)

This commit is contained in:
Andre K 2023-04-16 06:16:41 -03:00 committed by GitHub
parent 72c278c92c
commit da5f1d529d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 95 additions and 2 deletions

View file

@ -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

View file

@ -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