mirror of
https://github.com/meshtastic/Meshtastic-Android.git
synced 2026-02-22 01:59:01 -05:00
refactor: extract traceroute text from MeshService
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
package com.geeksville.mesh.model
|
||||
|
||||
import com.geeksville.mesh.MeshProtos
|
||||
import com.geeksville.mesh.MeshProtos.RouteDiscovery
|
||||
import com.geeksville.mesh.Portnums
|
||||
|
||||
val MeshProtos.MeshPacket.fullRouteDiscovery: RouteDiscovery?
|
||||
get() = with(decoded) {
|
||||
if (hasDecoded() && !wantResponse && portnum == Portnums.PortNum.TRACEROUTE_APP) {
|
||||
runCatching { RouteDiscovery.parseFrom(payload).toBuilder() }.getOrNull()?.apply {
|
||||
clearRoute()
|
||||
addAllRoute(listOf(to) + routeList + from)
|
||||
if (hopStart > 0 && snrBackList.size > 0) { // otherwise back route is invalid
|
||||
clearRouteBack()
|
||||
addAllRouteBack(listOf(from) + routeBackList + to)
|
||||
}
|
||||
}?.build()
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun formatTraceroutePath(nodesList: List<String>, snrList: List<Int>): String {
|
||||
// nodesList should include both origin and destination nodes
|
||||
// origin will not have an SNR value, but destination should
|
||||
val snrStr = if (snrList.size == nodesList.size - 1) {
|
||||
snrList
|
||||
} else {
|
||||
// use unknown SNR for entire route if snrList has invalid size
|
||||
List(nodesList.size - 1) { -128 }
|
||||
}.map { snr ->
|
||||
val str = if (snr == -128) "?" else "${snr / 4}"
|
||||
"⇊ $str dB"
|
||||
}
|
||||
|
||||
return nodesList.map { userName ->
|
||||
"■ $userName"
|
||||
}.flatMapIndexed { i, nodeStr ->
|
||||
if (i == 0) listOf(nodeStr) else listOf(snrStr[i - 1], nodeStr)
|
||||
}.joinToString("\n")
|
||||
}
|
||||
|
||||
private fun RouteDiscovery.getTracerouteResponse(
|
||||
getUser: (nodeNum: Int) -> String,
|
||||
): String = buildString {
|
||||
if (routeList.isNotEmpty()) {
|
||||
append("Route traced toward destination:\n\n")
|
||||
append(formatTraceroutePath(routeList.map(getUser), snrTowardsList))
|
||||
}
|
||||
if (routeBackList.isNotEmpty()) {
|
||||
append("\n\n")
|
||||
append("Route traced back to us:\n\n")
|
||||
append(formatTraceroutePath(routeBackList.map(getUser), snrBackList))
|
||||
}
|
||||
}
|
||||
|
||||
fun MeshProtos.MeshPacket.getTracerouteResponse(
|
||||
getUser: (nodeNum: Int) -> String,
|
||||
): String? = fullRouteDiscovery?.getTracerouteResponse(getUser)
|
||||
@@ -28,6 +28,7 @@ import com.geeksville.mesh.database.entity.NodeEntity
|
||||
import com.geeksville.mesh.database.entity.Packet
|
||||
import com.geeksville.mesh.database.entity.toNodeInfo
|
||||
import com.geeksville.mesh.model.DeviceVersion
|
||||
import com.geeksville.mesh.model.getTracerouteResponse
|
||||
import com.geeksville.mesh.repository.datastore.RadioConfigRepository
|
||||
import com.geeksville.mesh.repository.location.LocationRepository
|
||||
import com.geeksville.mesh.repository.network.MQTTRepository
|
||||
@@ -747,9 +748,9 @@ class MeshService : Service(), Logging {
|
||||
}
|
||||
|
||||
Portnums.PortNum.TRACEROUTE_APP_VALUE -> {
|
||||
if (data.wantResponse) return // ignore data from traceroute requests
|
||||
val parsed = MeshProtos.RouteDiscovery.parseFrom(data.payload)
|
||||
handleReceivedTraceroute(packet, parsed)
|
||||
radioConfigRepository.setTracerouteResponse(
|
||||
packet.getTracerouteResponse(::getUserName)
|
||||
)
|
||||
}
|
||||
|
||||
else -> debug("No custom processing needed for ${data.portnumValue}")
|
||||
@@ -906,51 +907,6 @@ class MeshService : Service(), Logging {
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("MagicNumber")
|
||||
private fun formatTraceroutePath(nodesList: List<Int>, snrList: List<Int>): String {
|
||||
// nodesList should include both origin and destination nodes
|
||||
// origin will not have an SNR value, but destination should
|
||||
val snrStr = if (snrList.size == nodesList.size - 1) {
|
||||
snrList
|
||||
} else {
|
||||
// use unknown SNR for entire route if snrList has invalid size
|
||||
List(nodesList.size - 1) { -128 }
|
||||
}.map { snr ->
|
||||
val str = if (snr == -128) "?" else "${snr / 4}"
|
||||
"⇊ $str dB"
|
||||
}
|
||||
|
||||
return nodesList.map { nodeId ->
|
||||
"■ ${getUserName(nodeId)}"
|
||||
}.flatMapIndexed { i, nodeStr ->
|
||||
if (i == 0) listOf(nodeStr) else listOf(snrStr[i - 1], nodeStr)
|
||||
}.joinToString("\n")
|
||||
}
|
||||
|
||||
private fun handleReceivedTraceroute(packet: MeshPacket, trace: MeshProtos.RouteDiscovery) {
|
||||
val nodesToward = mutableListOf<Int>()
|
||||
nodesToward.add(packet.to)
|
||||
nodesToward += trace.routeList
|
||||
nodesToward.add(packet.from)
|
||||
|
||||
val nodesBack = mutableListOf<Int>()
|
||||
if (packet.hopStart > 0 && trace.snrBackList.size > 0) { // otherwise back route is invalid
|
||||
nodesBack.add(packet.from)
|
||||
nodesBack += trace.routeBackList
|
||||
nodesBack.add(packet.to)
|
||||
}
|
||||
|
||||
radioConfigRepository.setTracerouteResponse(buildString {
|
||||
append("Route traced toward destination:\n\n")
|
||||
append(formatTraceroutePath(nodesToward, trace.snrTowardsList))
|
||||
if (nodesBack.size > 0) {
|
||||
append("\n\n")
|
||||
append("Route traced back to us:\n\n")
|
||||
append(formatTraceroutePath(nodesBack, trace.snrBackList))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// If apps try to send packets when our radio is sleeping, we queue them here instead
|
||||
private val offlineSentPackets = mutableListOf<DataPacket>()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user