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 rightLocalNode.LocalNode— per-identity application handle. ImplementsTransport(unicast / broadcast), owns PFS state, and exposes raw packet plus control-side subscriptions.BoundChannel— a channel bound to aLocalNode. ImplementsTransport(blind unicast / multicast). Available with thesoftware-cryptofeature.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-levelon_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§
Structs§
- Bound
Channel - A channel bound to a specific
LocalNode. ImplementsTransport. - Capabilities
- Channel
- A channel descriptor — holds the key, derived ID, and display name.
- Channel
Info Ref - Borrowing view of an inbound MAC event.
- Host
- Multi-identity orchestration layer for the node API.
- Local
Node - Per-identity application handle.
- Node
Identity Payload - Owned
Node Identity Payload - Peer
Connection - Relationship with one remote peer, bound to a transport context.
- Received
Packet Ref - Borrowed view of one accepted inbound packet together with parsed on-wire metadata.
- Route
Hops - 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.
- Send
Progress Ticket - Lightweight handle for observing the progress of an in-flight send.
- Send
Token - Identity-scoped send token.
- Snr
- Signal-to-noise ratio represented in centibels (0.1 dB units).
- Subscription
- Owned subscription guard.
Enums§
- AppEncode
Error - AppParse
Error - Host
Error - Error returned when a
Hostcannot make progress. - MacBackend
Error - Normalized wrapper around MAC-handle failures.
- Node
Error - Errors produced by node-layer operations.
- Node
Role - Owned
MacCommand - Packet
Family - 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.