meshtastic-map icon indicating copy to clipboard operation
meshtastic-map copied to clipboard

Neighbor info over LoRa deprecation, code for decoding traceroute as links (oriented graph) from this project db.

Open ServeurpersoCom opened this issue 1 year ago • 2 comments

Because neighbor info propagation on LoRa is deprecated on Meshtastic now (but still available via MQTT for direct neighbors), we must use Traceroute request frames to build the network graph topology.

Here’s my PHP code to use on the project database to get all links with SNR. The limitation is the last hop, as it’s from the receiver’s perspective.

This is the backend code I use on my network topology grapher (https://www.serveurperso.com/) – sharing it here in case it can help anyone port it to JavaScript. I added comments in English to clarify functionality. This code works in real-world scenarios.

$links = [];

// Query to fetch traceroute data with various metrics
$result = $MYSQLI->query(
    "SELECT UNIX_TIMESTAMP(updated_at) AS updated_at, `from`, `to`, route, route_back, snr_towards, snr_back, want_response FROM traceroutes ORDER BY updated_at ASC"
);

if ($result) {
    while ($row = $result->fetch_assoc()) {
        // Check if the entry is older than 168 hours (7 days), skip if so
        $updatedat = (int)$row["updated_at"];
        if ($now - $updatedat > 168 * 3600) {
            continue;
        }

        // Skip entries where 'want_response' indicates this is a request packet
        $wantresponse = (int)$row["want_response"];
        if ($wantresponse == 1) {
            continue;
        }

        // Retrieve 'from' and 'to' node IDs and confirm they are valid nodes in the filtered set
        $to = (int)$row["from"];
        $from = (int)$row["to"];
        if (!isset($filterednodes[$from]) || !isset($filterednodes[$to])) {
            continue;
        }

        // Decode route and SNR data
        $route = json_decode($row["route"], true);
        $route_back = json_decode($row["route_back"], true);
        $snr_towards = json_decode($row["snr_towards"], true);
        $snr_back = json_decode($row["snr_back"], true);

        // Case 1: Direct link without intermediate hops
        if (empty($route) && isset($snr_towards[0]) && $snr_towards[0] != -128) {
            // Remove any existing duplicate link and add a direct link with SNR
            foreach ($links as $key => $link) {
                if ($link["source"] == $from && $link["target"] == $to) {
                    unset($links[$key]);
                    break;
                }
            }
            $links[] = [
                "source" => $from,
                "target" => $to,
                "snr" => $snr_towards[0] / 4
            ];
        }

        // Case 2: Multi-hop route with forward SNR values
        if (!empty($route)) {
            $previousnode = $from;
            foreach ($route as $i => $nextnode) {
                if (!isset($filterednodes[$previousnode]) || !isset($filterednodes[$nextnode])) {
                    continue;
                }

                // Remove any existing duplicate link and add new link
                foreach ($links as $key => $link) {
                    if ($link["source"] == $previousnode && $link["target"] == $nextnode) {
                        unset($links[$key]);
                        break;
                    }
                }

                if (isset($snr_towards[$i]) && $snr_towards[$i] != -128) {
                    $links[] = [
                        "source" => $previousnode,
                        "target" => $nextnode,
                        "snr" => $snr_towards[$i] / 4
                    ];
                }

                $previousnode = $nextnode;
            }

            // Add final link to the destination if SNR is available
            if (isset($filterednodes[$previousnode]) && isset($filterednodes[$to]) && isset($snr_towards[count($route)]) && $snr_towards[count($route)] != -128) {
                foreach ($links as $key => $link) {
                    if ($link["source"] == $previousnode && $link["target"] == $to) {
                        unset($links[$key]);
                        break;
                    }
                }
                $links[] = [
                    "source" => $previousnode,
                    "target" => $to,
                    "snr" => $snr_towards[count($route)] / 4
                ];
            }
        }

        // Case 3: Multi-hop route with backward SNR values (route_back)
        if (!empty($route_back)) {
            $previousnode = $to;
            foreach ($route_back as $i => $nextnode) {
                if (!isset($filterednodes[$previousnode]) || !isset($filterednodes[$nextnode])) {
                    continue;
                }

                // Remove any existing duplicate link and add backward link
                foreach ($links as $key => $link) {
                    if ($link["source"] == $previousnode && $link["target"] == $nextnode) {
                        unset($links[$key]);
                        break;
                    }
                }

                if (isset($snr_back[$i]) && $snr_back[$i] != -128) {
                    $links[] = [
                        "source" => $previousnode,
                        "target" => $nextnode,
                        "snr" => $snr_back[$i] / 4
                    ];
                }

                $previousnode = $nextnode;
            }
        }
    }
    $result->free();
}

ServeurpersoCom avatar Nov 11 '24 19:11 ServeurpersoCom

oh that's interesting there's a different approach I've got, but might see if I can merge them together

sgtwilko avatar Feb 03 '25 08:02 sgtwilko

Let me know we can easily test this on clean datasets of the Paris mesh, there is 93 nodes and 543 link active here

ServeurpersoCom avatar Feb 16 '25 17:02 ServeurpersoCom

I've implemented something similar for my fork, https://map.sthlm-mesh.se. I'm not yet sure about its usefulness. Feel free to check it out, you need to enable it as a layer, and there is a setting for maximum age.

Roslund avatar Aug 10 '25 18:08 Roslund

I added traceroute link date, here is my complete backend file to make JSON. Easy to convert for other usecases with LLM

mesh.php.txt

ServeurpersoCom avatar Aug 10 '25 19:08 ServeurpersoCom