A
no_std,no_alloccrate for talking to AWS IoT services from embedded devices.
rustot is a pure-Rust, async-first implementation of the device-side AWS IoT
service protocols. It is designed for resource-constrained MCUs (think
embassy + ESP32 / nRF / STM32) but also runs unchanged on std targets via
tokio for testing.
The crate aims for parity with the equivalent surface area of the Amazon FreeRTOS AWS IoT Device SDK, spelt in idiomatic Rust.
| Module | AWS service | Description |
|---|---|---|
jobs |
Jobs | Receive remote operations, report progress, drive a job state machine. |
commands |
Commands | One-shot, cloud-to-device instructions with optional progress reporting and ack handshake. |
shadows |
Device Shadow | Synchronise reported / desired state with the cloud. Supports classic and named shadows, plus a multi-shadow manager. |
provisioning |
Fleet Provisioning | Provisioning by claim — exchange a bootstrap certificate for a per-device certificate. |
defender_metrics |
Device Defender | Publish device-side security metrics. |
transfer |
OTA on top of Jobs | Generic file transfer (Transfer::perform) and OTA firmware updates (Transfer::perform_ota) with self-test / image-state hooks, over MQTT or HTTP. The OTA path is wire-compatible with the Amazon FreeRTOS afr_ota job-document format produced by the CreateOTAUpdate control-plane API. |
no_std,no_alloc— every API usesheapless, borrowed&str, and caller-provided buffers. No dynamic allocation in the hot path.- Backend-agnostic MQTT — service modules are written against the
crate::mqtt::MqttClienttrait. Pick one backend per build:mqtt_mqttrust— bare-metal / embassymqtt_rumqttc— std + tokio (testing, gateways)mqtt_greengrass— AWS Greengrass IPC
- Async, with no executor lock-in — futures +
embassy-timefor timeouts. Works withembassy-executor,tokio, or any other. - Generic over user types — services that carry a payload (Jobs job
documents, Commands request payloads, Shadow state) are parameterised by a
user
Serialize/Deserializetype. Bring your own enum.
Requires nightly Rust. The crate uses generic_const_exprs for compile-time
topic-length sizing.
rustup toolchain install nightly
rustup override set nightly # in the project directory| Feature | Default | Effect |
|---|---|---|
transfer_mqtt |
yes | Enable MQTT-based file transfer / OTA. |
transfer_http |
no | Enable HTTP-based file transfer (no client). |
transfer_http_reqwest |
no | HTTP transfer via reqwest (std-only). |
metric_cbor |
yes | Defender Metrics: CBOR payloads (else JSON). |
provision_cbor |
yes | Fleet Provisioning: CBOR payloads (else JSON). |
commands_cbor |
yes | Commands: CBOR payloads (else JSON). |
shadows_kv_persist |
yes | Field-level shadow persistence to a KV store. |
sequential_storage |
no | Flash-backed KV store via sequential-storage. |
shadows_builders |
no | Generate bon builder methods on shadow structs. |
shadows_multi |
no | Runtime-named shadows with wildcard subscriptions (requires std). |
| Feature | When to use |
|---|---|
mqtt_mqttrust |
no_std embedded device with a mqttrust client. Default. |
mqtt_rumqttc |
std host (e.g. integration tests, gateways) using rumqttc. |
mqtt_greengrass |
Running inside an AWS Greengrass nucleus via IPC. |
| Feature | Effect |
|---|---|
std |
Enable std-only paths (file-backed KV, tokio-based test infra). |
defmt |
Derive defmt::Format on public types and route logs through defmt. |
log |
Route logs through the log crate. |
Each service module ships its own README with workflow, topic table, and a worked example:
Integration tests under tests/ (ota_mqtt.rs, provisioning.rs,
shadows.rs, …) double as end-to-end usage examples against real AWS IoT.
Unit tests run in-tree:
cargo test --libIntegration tests under tests/ exercise real AWS IoT endpoints. They expect
a tests/secrets/identity.pfx (or claim_identity.pfx for provisioning) and
environment variables (THING_NAME, AWS_HOSTNAME, …); see each test's
header for specifics.
Contributions, suggestions, bug reports, and reviews are highly appreciated.
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in the work by you, as defined in the Apache-2.0 license, shall be dual licensed as above, without any additional terms or conditions.