telepath-server
RPC server library for embedded targets (no_std, no alloc).
Target-side Telepath RPC server. Runs on the MCU in #![no_std] mode.
Receives COBS-framed postcard requests from the host, dispatches them to registered command handlers, and sends rzCOBS-framed postcard responses back.
Architecture
flowchart LR
T[Transport] -->|bytes| FA[FrameAccumulator]
FA -->|COBS frame| CD[cobs_decode]
CD -->|raw bytes| PD["postcard::from_bytes"]
PD -->|typed args| D[dispatch]
D -->|result| PS["postcard::to_slice"]
PS -->|raw bytes| CE[rzcobs_encode]
CE -->|rzCOBS frame| T
Key API
TelepathServer<T, N>
| Method | Description |
|---|---|
new(transport, commands) |
Create a server with a transport and a static command slice |
poll() |
Drain available bytes, process any complete frames; call in a loop |
dispatch(cmd_id, input, output) |
Manually dispatch a decoded payload (useful for testing) |
find_command(id) |
Look up a command by ID (linear scan over the static slice) |
T must implement transport::Transport. N is the internal buffer
size; use 512 or larger to accommodate max-payload frames.
transport::Transport trait
Both methods are non-blocking and return the number of bytes transferred.
CommandMetadata
For details on the generated invoke, args_schema, and ret_schema functions,
see telepath-macros § Signature contract.
Register commands by passing a &'static [CommandMetadata] to new().
Use telepath_server::commands() (linkme-collected at link time) to
pass all #[command]-annotated functions automatically.
ResourceRegistry
Type-keyed container for #[resource]-injected values. Re-exported as
telepath_server::ResourceRegistry. Each resource type may appear at most
once; registering a second value of the same type panics at runtime
(fail-fast to prevent silent shadowing). Resources are added via the
TelepathServer::resource(value) builder method — see Usage below.
Usage
use ;
// Resource args are injected from the server's ResourceRegistry, not over the wire.
let mut server = new
.resource; // register each #[resource] type before polling
loop
Note: The
#[command]macro generates a shim that callspostcard::from_bytes/postcard::to_slicedirectly. Your firmware crate must addpostcardas a direct dependency in itsCargo.tomlin addition totelepath-server.
Build
This crate targets both native (for tests) and thumbv7em-none-eabi (for firmware).
# Host tests
cargo test -p telepath-server
# Cross-compiled (requires the target to be added)
rustup target add thumbv7em-none-eabi
cargo build -p telepath-server --target thumbv7em-none-eabi