Skip to main content

Crate ssh_stamp

Crate ssh_stamp 

Source
Expand description

Platform-agnostic core of ssh-stamp.

Hosts the SSH state machine, configuration handling, and the platform::PlatformServices / serial::BufferedSerial traits that a per-MCU adapter crate (e.g. ssh-stamp-esp32) implements.

§Architecture

ssh-stamp is firmware that turns a microcontroller into an SSH-accessible serial bridge. Connect via SSH to the device, and your terminal session is bridged directly to the device’s UART.

The design separates platform-agnostic logic (this crate) from platform-specific implementations (port crates like ssh-stamp-esp32). All hardware access flows through traits defined in ssh_stamp_hal or through platform::PlatformServices.

§Crate structure

  • ssh_stamp_hal — hardware abstraction traits (WifiHal, NetworkProviderHal, OtaActions, etc.)
  • ssh_stamp_esp32 — ESP32 port: trait implementations, bootable binary, per-target UART pin assignments
  • ssh_stamp_esp32_boards — per-board pin mappings and the board catalog
  • ssh_stamp_ota — SFTP-based OTA update server (TLV header parsing, chunked flash writes, device reset; includes the packer host utility)

ssh-stamp-ota depends on ssh-stamp-hal for OtaActions and is in turn depended on by ssh-stamp for SFTP-based updates.

§Repository layout

Platform-agnostic crates live at the repository root. Everything specific to one chip manufacturer lives under boards/ssh-stamp-<manufacturer>/, one directory per manufacturer:

ssh-stamp/
├── src/                          ssh-stamp (this crate)
├── ssh-stamp-hal/                hardware abstraction traits
├── ssh-stamp-ota/                SFTP OTA server and `packer` tool
├── xtask/                        build, flash and test runner
└── boards/
    └── ssh-stamp-esp/            Espressif
        ├── ssh-stamp-esp32/          port crate: HAL impls and firmware binary
        ├── ssh-stamp-esp32-boards/   board support: `boards/*.toml` pin maps
        └── ssh-stamp-esp32-hil/      hardware-in-the-loop tests

A new manufacturer gets its own boards/ssh-stamp-<manufacturer>/ directory with the same three crates; see “Adding a new port” in ssh_stamp_hal.

§Key modules

§Hacking

§Architectural invariants

  • src/ is platform-agnostic. It must not import esp-hal, esp-radio, esp-storage, or any platform-specific crate. All hardware access goes through ssh-stamp-hal traits or PlatformServices.
  • Peripherals are owned by the state machine, not globals. UART is an exclusive resource consumed by the serial bridge once SSH attaches.
  • Dependency graph is acyclic: ssh-stamp-hal <- ssh-stamp <- ssh-stamp-<port>. ssh-stamp must not depend on any port crate.

§Adding a new SSH env var handler

Edit handle::session_env. Add a new match arm for the variable name. Follow the existing pattern: acquire the config lock, apply the change, set ctx.config_changed = true, and call a.succeed().

§Configuration

On first boot (first_login = true), the device generates a random SSID and WPA2 PSK (printed to the serial console) and accepts any SSH connection. The client provisions a public key via the SSH_STAMP_PUBKEY environment variable. Subsequent connections require that key.

WiFi SSID and PSK can be changed at any time via the SSH_STAMP_WIFI_SSID and SSH_STAMP_WIFI_PSK env vars. Changes are persisted to flash and the device performs a software reset.

The serial bridge line settings follow the same route through the SSH_STAMP_UART_BAUD, SSH_STAMP_UART_DATA_BITS, SSH_STAMP_UART_PARITY and SSH_STAMP_UART_STOP_BITS env vars, defaulting to 115200 8N1.

§Testing

Host-side OTA TLV tests:

cargo +stable test --package ssh-stamp-ota --target x86_64-unknown-linux-gnu

Manual testing requires a hardware target, a WiFi client, an SSH client, and a serial device connected to the UART pins for bridge testing.

§Build-time configuration

The heap and buffer sizes below are declared in build.rs via esp-config and overridable at build time with the matching environment variable. Note that these are build time config variables, they are not used at runtime.

OptionStabilityDefault valueAllowed values

SSH_STAMP_CONFIG_HEAP_SIZE

Global allocator heap size in bytes

⚠️ Unstable61440Integer in range 16384..263168

Modules§

app
Platform-agnostic application entry points.
can
CAN frame encoding/decoding for SSH tunnelling.
config
Configuration types and serialization.
errors
Application-level error types.
handle
SSH event handlers: authentication, channels, environment variables.
mem_probe
The benchmarking instrumentation, including checkpoints and replay. Timing is not related to the platform in any way, so it doesn’t need to live inside the binrary crate.
platform
Platform services abstraction.
serial
serve
SSH connection loop orchestration.
settings
Compile-time constants: default IP, WiFi character set, buffer sizes.
store

Macros§

bench_emit
Emits a structured benchmark line.