Skip to content

Commit 60d6f67

Browse files
committed
Update direct traceroute handling to use two-way logic
1 parent 7f238d0 commit 60d6f67

File tree

3 files changed

+84
-112
lines changed

3 files changed

+84
-112
lines changed

Localizable.xcstrings

+1-11
Original file line numberDiff line numberDiff line change
@@ -14556,7 +14556,7 @@
1455614556
}
1455714557
},
1455814558
"mesh.log.traceroute.received.direct %@" : {
14559-
"extractionState" : "migrated",
14559+
"extractionState" : "manual",
1456014560
"localizations" : {
1456114561
"de" : {
1456214562
"stringUnit" : {
@@ -23077,16 +23077,6 @@
2307723077
},
2307823078
"Trace Route Log" : {
2307923079

23080-
},
23081-
"Trace route received directly by %@ with a SNR of %@ dB" : {
23082-
"localizations" : {
23083-
"en" : {
23084-
"stringUnit" : {
23085-
"state" : "new",
23086-
"value" : "Trace route received directly by %1$@ with a SNR of %2$@ dB"
23087-
}
23088-
}
23089-
}
2309023080
},
2309123081
"Trace Route Sent" : {
2309223082

Meshtastic/Helpers/BLEManager.swift

+81-91
Original file line numberDiff line numberDiff line change
@@ -834,45 +834,92 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
834834
if let routingMessage = try? RouteDiscovery(serializedBytes: decodedInfo.packet.decoded.payload) {
835835
let traceRoute = getTraceRoute(id: Int64(decodedInfo.packet.decoded.requestID), context: context)
836836
traceRoute?.response = true
837-
if routingMessage.route.count == 0 {
838-
// Routing messages snr values are snr * 4 stored as an int
839-
// If a traceroute snr value is unknown this field will contain INT8_MIN or -128
840-
// After converting to a float here, -32 is our unknown value.
841-
let snr = routingMessage.snrBack.count > 0 ? (Float(routingMessage.snrBack[0]) / 4) : -32
842-
traceRoute?.snr = snr
843-
let logString = String.localizedStringWithFormat("mesh.log.traceroute.received.direct %@".localized, String(snr))
844-
MeshLogger.log("🪧 \(logString)")
845-
} else {
846-
guard let connectedNode = getNodeInfo(id: Int64(connectedPeripheral.num), context: context) else {
847-
return
837+
guard let connectedNode = getNodeInfo(id: Int64(connectedPeripheral.num), context: context) else {
838+
return
839+
}
840+
var hopNodes: [TraceRouteHopEntity] = []
841+
let connectedHop = TraceRouteHopEntity(context: context)
842+
connectedHop.time = Date()
843+
connectedHop.num = connectedPeripheral.num
844+
connectedHop.name = connectedNode.user?.longName ?? "???"
845+
// If nil, set to unknown, INT8_MIN (-128) then divide by 4
846+
connectedHop.snr = Float(routingMessage.snrBack.last ?? -128) / 4
847+
if let mostRecent = traceRoute?.node?.positions?.lastObject as? PositionEntity, mostRecent.time! >= Calendar.current.date(byAdding: .hour, value: -24, to: Date())! {
848+
connectedHop.altitude = mostRecent.altitude
849+
connectedHop.latitudeI = mostRecent.latitudeI
850+
connectedHop.longitudeI = mostRecent.longitudeI
851+
traceRoute?.hasPositions = true
852+
}
853+
var routeString = "\(connectedNode.user?.longName ?? "???") --> "
854+
hopNodes.append(connectedHop)
855+
traceRoute?.hopsTowards = Int32(routingMessage.route.count)
856+
for (index, node) in routingMessage.route.enumerated() {
857+
var hopNode = getNodeInfo(id: Int64(node), context: context)
858+
if hopNode == nil && hopNode?.num ?? 0 > 0 && node != 4294967295 {
859+
hopNode = createNodeInfo(num: Int64(node), context: context)
848860
}
849-
var hopNodes: [TraceRouteHopEntity] = []
850-
let connectedHop = TraceRouteHopEntity(context: context)
851-
connectedHop.time = Date()
852-
connectedHop.num = connectedPeripheral.num
853-
connectedHop.name = connectedNode.user?.longName ?? "???"
854-
// If nil, set to unknown, INT8_MIN (-128) then divide by 4
855-
connectedHop.snr = Float(routingMessage.snrBack.last ?? -128) / 4
856-
if let mostRecent = traceRoute?.node?.positions?.lastObject as? PositionEntity, mostRecent.time! >= Calendar.current.date(byAdding: .hour, value: -24, to: Date())! {
857-
connectedHop.altitude = mostRecent.altitude
858-
connectedHop.latitudeI = mostRecent.latitudeI
859-
connectedHop.longitudeI = mostRecent.longitudeI
860-
traceRoute?.hasPositions = true
861+
let traceRouteHop = TraceRouteHopEntity(context: context)
862+
traceRouteHop.time = Date()
863+
if routingMessage.snrTowards.count >= index + 1 {
864+
traceRouteHop.snr = Float(routingMessage.snrTowards[index]) / 4
865+
} else {
866+
// If no snr in route, set unknown
867+
traceRouteHop.snr = -32
868+
}
869+
if let hn = hopNode, hn.hasPositions {
870+
if let mostRecent = hn.positions?.lastObject as? PositionEntity, mostRecent.time! >= Calendar.current.date(byAdding: .hour, value: -24, to: Date())! {
871+
traceRouteHop.altitude = mostRecent.altitude
872+
traceRouteHop.latitudeI = mostRecent.latitudeI
873+
traceRouteHop.longitudeI = mostRecent.longitudeI
874+
traceRoute?.hasPositions = true
875+
}
861876
}
862-
var routeString = "\(connectedNode.user?.longName ?? "???") --> "
863-
hopNodes.append(connectedHop)
864-
traceRoute?.hopsTowards = Int32(routingMessage.route.count)
865-
for (index, node) in routingMessage.route.enumerated() {
877+
traceRouteHop.num = hopNode?.num ?? 0
878+
if hopNode != nil {
879+
if decodedInfo.packet.rxTime > 0 {
880+
hopNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.packet.rxTime)))
881+
}
882+
}
883+
hopNodes.append(traceRouteHop)
884+
885+
let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized))
886+
let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : ""
887+
let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized
888+
routeString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> "
889+
}
890+
let destinationHop = TraceRouteHopEntity(context: context)
891+
destinationHop.name = traceRoute?.node?.user?.longName ?? "unknown".localized
892+
destinationHop.time = Date()
893+
// If nil, set to unknown, INT8_MIN (-128) then divide by 4
894+
destinationHop.snr = Float(routingMessage.snrTowards.last ?? -128) / 4
895+
destinationHop.num = traceRoute?.node?.num ?? 0
896+
if let mostRecent = traceRoute?.node?.positions?.lastObject as? PositionEntity, mostRecent.time! >= Calendar.current.date(byAdding: .hour, value: -24, to: Date())! {
897+
destinationHop.altitude = mostRecent.altitude
898+
destinationHop.latitudeI = mostRecent.latitudeI
899+
destinationHop.longitudeI = mostRecent.longitudeI
900+
traceRoute?.hasPositions = true
901+
}
902+
hopNodes.append(destinationHop)
903+
/// Add the destination node to the end of the route towards string and the beginning of the route back string
904+
routeString += "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)"
905+
traceRoute?.routeText = routeString
906+
907+
traceRoute?.hopsBack = Int32(routingMessage.routeBack.count)
908+
// Only if hopStart is set and there is an SNR entry
909+
if decodedInfo.packet.hopStart > 0 && routingMessage.snrBack.count > 0 {
910+
var routeBackString = "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> "
911+
for (index, node) in routingMessage.routeBack.enumerated() {
866912
var hopNode = getNodeInfo(id: Int64(node), context: context)
867913
if hopNode == nil && hopNode?.num ?? 0 > 0 && node != 4294967295 {
868914
hopNode = createNodeInfo(num: Int64(node), context: context)
869915
}
870916
let traceRouteHop = TraceRouteHopEntity(context: context)
871917
traceRouteHop.time = Date()
872-
if routingMessage.snrTowards.count >= index + 1 {
873-
traceRouteHop.snr = Float(routingMessage.snrTowards[index]) / 4
918+
traceRouteHop.back = true
919+
if routingMessage.snrBack.count >= index + 1 {
920+
traceRouteHop.snr = Float(routingMessage.snrBack[index]) / 4
874921
} else {
875-
// If no snr in route, set unknown
922+
// If no snr in route, set to unknown
876923
traceRouteHop.snr = -32
877924
}
878925
if let hn = hopNode, hn.hasPositions {
@@ -894,69 +941,12 @@ class BLEManager: NSObject, CBPeripheralDelegate, MqttClientProxyManagerDelegate
894941
let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized))
895942
let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : ""
896943
let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized
897-
routeString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> "
944+
routeBackString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> "
898945
}
899-
let destinationHop = TraceRouteHopEntity(context: context)
900-
destinationHop.name = traceRoute?.node?.user?.longName ?? "unknown".localized
901-
destinationHop.time = Date()
902946
// If nil, set to unknown, INT8_MIN (-128) then divide by 4
903-
destinationHop.snr = Float(routingMessage.snrTowards.last ?? -128) / 4
904-
destinationHop.num = traceRoute?.node?.num ?? 0
905-
if let mostRecent = traceRoute?.node?.positions?.lastObject as? PositionEntity, mostRecent.time! >= Calendar.current.date(byAdding: .hour, value: -24, to: Date())! {
906-
destinationHop.altitude = mostRecent.altitude
907-
destinationHop.latitudeI = mostRecent.latitudeI
908-
destinationHop.longitudeI = mostRecent.longitudeI
909-
traceRoute?.hasPositions = true
910-
}
911-
hopNodes.append(destinationHop)
912-
/// Add the destination node to the end of the route towards string and the beginning of the route back string
913-
routeString += "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) (\(destinationHop.snr != -32 ? String(destinationHop.snr) : "unknown ".localized)dB)"
914-
traceRoute?.routeText = routeString
915-
916-
traceRoute?.hopsBack = Int32(routingMessage.routeBack.count)
917-
// Only if hopStart is set and there is an SNR entry
918-
if decodedInfo.packet.hopStart > 0 && routingMessage.snrBack.count > 0 {
919-
var routeBackString = "\(traceRoute?.node?.user?.longName ?? "unknown".localized) \((traceRoute?.node?.num ?? 0).toHex()) --> "
920-
for (index, node) in routingMessage.routeBack.enumerated() {
921-
var hopNode = getNodeInfo(id: Int64(node), context: context)
922-
if hopNode == nil && hopNode?.num ?? 0 > 0 && node != 4294967295 {
923-
hopNode = createNodeInfo(num: Int64(node), context: context)
924-
}
925-
let traceRouteHop = TraceRouteHopEntity(context: context)
926-
traceRouteHop.time = Date()
927-
traceRouteHop.back = true
928-
if routingMessage.snrBack.count >= index + 1 {
929-
traceRouteHop.snr = Float(routingMessage.snrBack[index]) / 4
930-
} else {
931-
// If no snr in route, set to unknown
932-
traceRouteHop.snr = -32
933-
}
934-
if let hn = hopNode, hn.hasPositions {
935-
if let mostRecent = hn.positions?.lastObject as? PositionEntity, mostRecent.time! >= Calendar.current.date(byAdding: .hour, value: -24, to: Date())! {
936-
traceRouteHop.altitude = mostRecent.altitude
937-
traceRouteHop.latitudeI = mostRecent.latitudeI
938-
traceRouteHop.longitudeI = mostRecent.longitudeI
939-
traceRoute?.hasPositions = true
940-
}
941-
}
942-
traceRouteHop.num = hopNode?.num ?? 0
943-
if hopNode != nil {
944-
if decodedInfo.packet.rxTime > 0 {
945-
hopNode?.lastHeard = Date(timeIntervalSince1970: TimeInterval(Int64(decodedInfo.packet.rxTime)))
946-
}
947-
}
948-
hopNodes.append(traceRouteHop)
949-
950-
let hopName = hopNode?.user?.longName ?? (node == 4294967295 ? "Repeater" : String(hopNode?.num.toHex() ?? "unknown".localized))
951-
let mqttLabel = hopNode?.viaMqtt ?? false ? "MQTT " : ""
952-
let snrLabel = (traceRouteHop.snr != -32) ? String(traceRouteHop.snr) : "unknown ".localized
953-
routeBackString += "\(hopName) \(mqttLabel)(\(snrLabel)dB) --> "
954-
}
955-
// If nil, set to unknown, INT8_MIN (-128) then divide by 4
956-
let snrBackLast = Float(routingMessage.snrBack.last ?? -128) / 4
957-
routeBackString += "\(connectedNode.user?.longName ?? String(connectedNode.num.toHex())) (\(snrBackLast != -32 ? String(snrBackLast) : "unknown ".localized)dB)"
958-
traceRoute?.routeBackText = routeBackString
959-
}
947+
let snrBackLast = Float(routingMessage.snrBack.last ?? -128) / 4
948+
routeBackString += "\(connectedNode.user?.longName ?? String(connectedNode.num.toHex())) (\(snrBackLast != -32 ? String(snrBackLast) : "unknown ".localized)dB)"
949+
traceRoute?.routeBackText = routeBackString
960950
traceRoute?.hops = NSOrderedSet(array: hopNodes)
961951
traceRoute?.time = Date()
962952
do {

Meshtastic/Views/Nodes/TraceRouteLog.swift

+2-10
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct TraceRouteLog: View {
5454
.font(.caption)
5555
}
5656
} icon: {
57-
Image(systemName: route.response ? (route.hops?.count == 0 && route.response ? "person.line.dotted.person" : "point.3.connected.trianglepath.dotted") : "person.slash")
57+
Image(systemName: route.response ? (route.hopsTowards == 0 && route.response ? "person.line.dotted.person" : "point.3.connected.trianglepath.dotted") : "person.slash")
5858
.symbolRenderingMode(.hierarchical)
5959
}
6060
.swipeActions {
@@ -76,15 +76,7 @@ struct TraceRouteLog: View {
7676
Divider()
7777
ScrollView {
7878
if selectedRoute != nil {
79-
if selectedRoute?.response ?? false && selectedRoute?.hopsTowards ?? 0 == 0 {
80-
Label {
81-
Text("Trace route received directly by \(selectedRoute?.node?.user?.longName ?? "unknown".localized) with a SNR of \(String(format: "%.2f", selectedRoute?.snr ?? 0.0)) dB")
82-
} icon: {
83-
Image(systemName: "signpost.right.and.left")
84-
.symbolRenderingMode(.hierarchical)
85-
}
86-
.font(.title3)
87-
} else if selectedRoute?.response ?? false && selectedRoute?.hopsTowards ?? 0 > 0 {
79+
if selectedRoute?.response ?? false && selectedRoute?.hopsTowards ?? 0 >= 0 {
8880
Label {
8981
Text("Route: \(selectedRoute?.routeText ?? "unknown".localized)")
9082
} icon: {

0 commit comments

Comments
 (0)