Skip to content

Feature request: give AnnounceHandler access to the announce packet (interface, hops, RSSI/SNR) #84

Description

@mclueppers

The problem being solved

RNS::AnnounceHandler::received_announce(destination_hash, announced_identity, app_data) is the only way an application learns about announces, and it says nothing about how the announce arrived. Anything that wants to build a neighbour or peer list, show link quality per node, or keep per-interface statistics needs:

  • the receiving interface (LoRa vs. TCP vs. a specific peer interface),
  • the hop count,
  • RSSI/SNR for radio interfaces,
  • optionally the transport id and packet hash.

Transport::inbound() has all of this on the Packet at the moment it calls the handler — it has just validated the announce, updated the path table and copied the interface's RSSI/SNR onto the packet — but none of it reaches the callback.

Concrete case: an ESP32-S3 transport node (microReticulum 0.5.0, one LoRa and one TCP interface) that shows a "neighbours" page on its display and web UI. Every entry needs "heard via LoRa at −87 dBm, 1 hop" or "via Wi-Fi client 192.168.x.y". Today the firmware gets the announce twice: once from the handler (no metadata) and once by tapping the raw bytes in its interface implementation, where it re-parses the announce format and re-verifies the Ed25519 signature just to attach the metadata Transport already had.

Why existing functionality is insufficient

  • The three-argument callback is the whole public surface; Transport::_announce_handlers and the dispatch loop are internal.
  • Working around it means duplicating announce parsing and signature verification in application code (and keeping it in step with the library), or scraping the interface layer for raw packets, which reintroduces exactly the coupling the handler abstraction is meant to avoid.
  • Identity::recall() after the fact gives the identity and app data, but nothing about the receiving interface or signal quality — that information exists only on the packet.

Proposed solution

Add an overload that carries the packet, with a default implementation that forwards to the existing method, so current handlers keep working unchanged:

class AnnounceHandler {
public:
	// Existing (unchanged)
	virtual void received_announce(const Bytes& destination_hash, const Identity& announced_identity, const Bytes& app_data) = 0;

	// New: default forwards to the 3-argument form
	virtual void received_announce(const Bytes& destination_hash, const Identity& announced_identity, const Bytes& app_data, const Packet& packet) {
		received_announce(destination_hash, announced_identity, app_data);
	}
};

Transport::inbound() calls the four-argument form. A handler that wants the metadata overrides it and reads packet.receiving_interface(), packet.hops(), packet.rssi(), packet.snr(), packet.transport_id(), packet.packet_hash() — all existing Packet accessors, nothing new to maintain.

Possible alternatives

  • A dedicated AnnounceInfo struct (interface name, hops, rssi, snr, …) passed to a new callback. Cleaner-looking but it is a second copy of data the Packet already carries, and it needs extending every time someone wants one more field.
  • A separate "raw announce" callback registered on Transport. More API surface and it would still need the validated identity/app data to be useful, i.e. it would converge on the overload above.
  • Status quo: applications re-parse announces themselves (see above).

Expected impact on existing users

None. Existing AnnounceHandler subclasses implement the three-argument method and are called exactly as before through the default forwarding implementation. The examples (lora_announce, udp_announce) need no change.

Compatibility concerns

  • Additive API: one new virtual method with a default body; no protocol, storage or configuration changes.
  • The three-argument method stays pure virtual so existing subclasses are unaffected; a new handler that only wants the packet form still has to provide a (possibly empty) three-argument override. Making the three-argument one non-pure would be a follow-up if that turns out to be annoying.
  • The Packet reference is only valid for the duration of the callback (same lifetime rule as elsewhere in Transport::inbound()); handlers must copy what they need.

I have a small, focused PR ready (overload + Transport call site + README "Announce Handlers" section; tested on ESP32-S3 over LoRa and TCP, native test suite 182/182) and will link it to this issue.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions