Crate umsh_node

Crate umsh_node 

Source
Expand description

Application-facing node layer built on top of umsh-mac.

Note: This reference implementation is a work in progress and was developed with the assistance of an LLM. It should be considered experimental.

umsh-node sits between the radio-facing MAC coordinator in umsh-mac and the application. Where umsh-mac thinks in raw frames, keys, replay windows, and transmit queues, umsh-node provides composable abstractions for sending and receiving messages, tracking in-flight sends, and managing channel membership.

The receive boundary is intentionally low-level: raw subscriptions get a ReceivedPacketRef that stays close to the accepted on-wire packet. Payload-specific helpers such as those in the umsh-text crate live one layer up and are built on top of those raw packet callbacks.

This crate requires alloc (heap allocation for String, Vec, etc.). It is otherwise no_std compatible.

§Architecture overview

┌──────────────────────────────────────────────────────────────┐
│  Application                                                 │
│  Host · LocalNode · PeerConnection · BoundChannel            │
┌──────────────────────┴───────────────────────────────────────┐
│  Host                                                        │
│    ├── drives the shared MAC/runtime event loop              │
│    └── owns multiple LocalNode handles                       │
└──────────────────────┬───────────────────────────────────────┘
                       │
┌──────────────────────┴───────────────────────────────────────┐
│  LocalNode<M>                                                │
│    ├── sends down through MacBackend                         │
│    ├── owns per-identity PFS state                           │
│    └── dispatches node/peer callback subscriptions           │
└──────────────────────┬───────────────────────────────────────┘
                       │  MacBackend trait
┌──────────────────────┴───────────────────────────────────────┐
│  MacHandle → Mac<P>  (no_std, heapless)                      │
└──────────────────────────────────────────────────────────────┘

§Key types

  • Host — preferred multi-identity driver. Owns the shared MAC event loop and routes inbound traffic to the right LocalNode.
  • LocalNode — per-identity application handle. Implements Transport (unicast / broadcast), owns PFS state, and exposes raw packet plus control-side subscriptions.
  • BoundChannel — a channel bound to a LocalNode. Implements Transport (blind unicast / multicast). Available with the software-crypto feature.
  • PeerConnection — relationship with one remote peer, generic over transport context, with peer-scoped callback subscriptions.
  • Transport — shared send interface (send / send_all).
  • SendProgressTicket — lightweight polling handle for observing in-flight send progress (was_transmitted, was_acked, is_finished).
  • Subscription — owned callback registration that auto-unsubscribes on drop.
  • ReceivedPacketRef — borrowed receive view passed into low-level on_receive(...) handlers and wrappers, including local RX observations such as RSSI, SNR, LQI, and receive timestamp.
  • MacBackend — pluggable MAC backend trait for testability.

§Control payload types

[umsh_text::OwnedTextMessage], OwnedNodeIdentityPayload, and OwnedMacCommand are optional heap-allocated conveniences for callers that need to retain parsed payloads across task boundaries. Most receive-side code should prefer the borrowed views from the payload crates and ReceivedPacketRef.

§MAC abstraction

MacBackend exposes the public send/configure surface of the MAC coordinator. Safe PFS session management is available with software-crypto and builds on that public surface directly.

MacHandle implements MacBackend, and test code can provide a fake implementation to drive the node layer deterministically.

§Typical usage

For most applications, register callbacks and then let Host::run own the shared MAC event loop:

let mut host = Host::new(mac_handle);
let node = host.add_node(identity_id);
let peer = node.peer(peer_key)?;
let chat = umsh_text::UnicastTextChatWrapper::from_peer(&peer);

let _messages = chat.on_text(|packet, text| {
    println!(
        "peer says: {} (hops={})",
        text.body,
        packet.flood_hops().map(|h| h.remaining()).unwrap_or(0),
    );
});

let _ticket = chat.send_text("hello", &SendOptions::default()).await?;
host.run().await?;

If you need to multiplex UMSH progress with another async source such as user input, use Host::pump_once as a single wake-driven step. It already waits on radio activity and protocol deadlines; you should not add a manual poll/sleep loop around it.

loop {
    tokio::select! {
        line = stdin.next_line() => { /* handle input */ }
        result = host.pump_once() => result?,
    }
}

If you need protocol fidelity instead of a payload wrapper, subscribe directly on the node or peer and inspect the raw packet view:

let _raw = peer.on_receive(|packet| {
    if packet.packet_family() == umsh::mac::PacketFamily::Unicast {
        println!(
            "from={:?} encrypted={} mic_len={}",
            packet.from_key(),
            packet.encrypted(),
            packet.mic_len(),
        );
    }
    false
});

Re-exports§

pub use mac_command::CommandId;
pub use mac_command::MacCommand;

Modules§

identity_payload
mac_command

Structs§

BoundChannel
A channel bound to a specific LocalNode. Implements Transport.
Capabilities
Channel
A channel descriptor — holds the key, derived ID, and display name.
ChannelInfoRef
Borrowing view of an inbound MAC event.
Host
Multi-identity orchestration layer for the node API.
LocalNode
Per-identity application handle.
NodeIdentityPayload
OwnedNodeIdentityPayload
PeerConnection
Relationship with one remote peer, bound to a transport context.
ReceivedPacketRef
Borrowed view of one accepted inbound packet together with parsed on-wire metadata.
RouteHops
Iterator over packed two-byte route hops from a source-route or trace-route option.
RxMetadata
Local physical-layer observations captured when a frame was received.
SendProgressTicket
Lightweight handle for observing the progress of an in-flight send.
SendToken
Identity-scoped send token.
Snr
Signal-to-noise ratio represented in centibels (0.1 dB units).
Subscription
Owned subscription guard.

Enums§

AppEncodeError
AppParseError
HostError
Error returned when a Host cannot make progress.
MacBackendError
Normalized wrapper around MAC-handle failures.
NodeError
Errors produced by node-layer operations.
NodeRole
OwnedMacCommand
PacketFamily
Coarser grouping of on-wire packet types.
PfsStatus

Traits§

MacBackend
Pluggable backend that the node layer delegates to for MAC operations.
Transport
A context through which UMSH frames can be sent.

Functions§

expect_payload_type
parse_mac_command_payload
parse_node_identity_payload
split_payload_type