wireless_bridge (0.4.0-rc.0)
Installation
[registries.forgejo]
index = "sparse+ " # Sparse index
# index = " " # Git
[net]
git-fetch-with-cli = truecargo add wireless_bridge@0.4.0-rc.0 --registry forgejoAbout this package
wireless_bridge
Embedded LoRa–gRPC bridge for Linux (e.g. Raspberry Pi): receives LoRa frames from sensors, derives and caches keys, validates install/status messages (Sigil protocol), and forwards data to a gRPC backend. Optional ATECC608A secure element for device keys and CA verification.
Features
- LoRa (SX1278) over SPI: receiver with DIO0 interrupt, messaging via Sigil (models, encryption, init, keys).
- gRPC client to a local install/bridge service (e.g.
localhost:50051). - SQLite (via
db_handler) for keys and sensor data; key cache with expiration and periodic cleanup. - ATECC608A (optional): device keypair (slot 0), CA public key (slot 8), signature (slot 9), hardware RNG; host-side ECDSA verification when
ATECC_CA_PUBKEY_PATHis set. - Master secret: loaded from ATECC608A (slot, see
LORA_MASTER_SECRET_ATECC_SLOT), orLORA_MASTER_SECRET(base64), or/etc/bridge/master.key/./master.key; used to derive install/validation keys.
Prerequisites
- Rust (stable), and for cross-compilation: cross or
rustup target add armv7-unknown-linux-musleabihf. - Linux (the binary is built for Linux only; SPI, I2C, GPIO via
linux-embedded-halandgpio-cdev). - Hardware: LoRa module (SX1278) on SPI, optional ATECC608A on I2C. Protobufs are compiled at build time (
proto/).
Hardware (Raspberry Pi / SX1278)
| Raspberry Pi Pin | LoRa Module Pin |
|---|---|
| GPIO10 (MOSI) | MOSI |
| GPIO9 (MISO) | MISO |
| GPIO11 (SCK) | SCK |
| GPIO8 (CE0) | NSS |
| GPIO27 | RESET |
| GPIO17 | DIO0 |
| GND | GND |
| 3.3V | VCC |
SPI device is /dev/spidev0.0 by default. I2C for ATECC608A: /dev/i2c-1, address 0x60.
Build
# Native (Linux)
cargo build --release
# Cross-compile for Raspberry Pi (armv7)
rustup target add armv7-unknown-linux-musleabihf
cross build --release --target=armv7-unknown-linux-musleabihf
Binary: target/<target>/release/wireless_bridge.
Run
The bridge expects a master secret and (optionally) a config path. Example:
# Preferred: master secret from ATECC608A (slot 10, 32 bytes provisioned)
export LORA_MASTER_SECRET_ATECC_SLOT=10
# Or: master secret from env or file
# export LORA_MASTER_SECRET="<base64-32-bytes>"
export RUST_LOG=debug # optional: debug, info, warn, error
# Optional overrides (defaults shown)
# CONFIG_FILE=/path/to/config.json
# LORA_ATECC_I2C_PATH=/dev/i2c-1
# LORA_DIO_CHIP=/dev/gpiochip0
# LORA_DIO_LINE=13
# ATECC_CA_PUBKEY_PATH=/path/to/ca_public_key.bin
./wireless_bridge
- Master secret: prefer ATECC608A (
LORA_MASTER_SECRET_ATECC_SLOT, e.g.10) with 32 bytes provisioned in that slot; otherwise setLORA_MASTER_SECRET(base64) or use/etc/bridge/master.key(see Security / Master secret). - ATECC608A: optional; if not present, the bridge runs without the secure element. If present, device pubkey (slot 0), CA pubkey (slot 8 or file), and signature (slot 9) are used for validation and RNG.
Environment variables
| Variable | Description | Default |
|---|---|---|
LORA_MASTER_SECRET_ATECC_SLOT |
ATECC608A slot number (32 bytes). If set, master secret is read from this slot first (recommended). | — |
LORA_MASTER_SECRET |
Master secret, base64 (32 bytes). | — (or /etc/bridge/master.key, then ./master.key) |
CONFIG_FILE |
Path to application/config JSON (e.g. DB path). | — |
RUST_LOG |
Log level: error, warn, info, debug, trace. |
— |
LORA_ATECC_I2C_PATH |
I2C device for ATECC608A. | /dev/i2c-1 |
LORA_DIO_CHIP |
GPIO chip for LoRa DIO0. | /dev/gpiochip0 |
LORA_DIO_LINE |
GPIO line for LoRa DIO0. | 13 |
ATECC_CA_PUBKEY_PATH |
Optional path to CA public key file (64 or 65 bytes). | — (else CA from ATECC slot 8) |
Project structure
bridge/
├── proto/ # Protobuf definitions (status, install, bridge)
├── src/
│ ├── main.rs # Entry point (Linux only)
│ ├── app (inline) # SPI/GPIO/LoRa init, gRPC client, LoRa handler loop
│ ├── cache/ # Key cache (LRU, expiration)
│ ├── errors/ # Error types
│ ├── grpc/ # gRPC generated stubs and common protos
│ ├── handler/ # gRPC and LoRa handlers
│ ├── model_adapter/ # Sensor type and status mapping
│ ├── proxy/ # Proxy utilities
│ ├── radio/ # Radio (LoRa) abstraction
│ ├── random/ # Hardware RNG (ATECC608A)
│ ├── security/ # Master secret, ATECC608A integration
│ └── warpper/ # GPIO and DIO interrupt
├── tests/ # Integration and unit tests
├── scripts/ # tests.sh, build.sh, deploy.sh, runbridge.sh
├── build.rs # Compiles proto files (tonic-prost-build)
├── Cargo.toml
└── LICENSE
Tests
./scripts/tests.sh
# or
CONFIG_FILE=/path/to/config_test.json cargo test -- --test-threads=1 --nocapture
Tests use a config path for the database layer when required; see scripts/tests.sh and test code for details.
Dependencies (registries)
The crate depends on private Forgejo packages: tools, lora, db_handler, sigil, atecc608x. Configure the Forgejo registry in .cargo/config.toml and authenticate (e.g. cargo login --registry forgejo) before building.
License
Personal Use Only — Non-Commercial. See LICENSE for full terms and disclaimers.
Dependencies
| ID | Version |
|---|---|
| P256 | ^0.13 |
| anyhow | ^1.0.102 |
| atecc608x | =0.2.0-rc.4 |
| base64 | ^0.22 |
| chacha20poly1305 | ^0.10.1 |
| chrono | ^0.4.38 |
| db_handler | =0.1 |
| embedded-hal | ^1.0.0 |
| env_logger | ^0.11 |
| getrandom | ^0.4.2 |
| hex | ^0.4 |
| hkdf | ^0.12 |
| log | ^0.4.27 |
| lora | =0.3.0-rc.0 |
| lru | ^0.16.3 |
| prost | ^0.14.3 |
| sha2 | ^0.10 |
| sigil | =0.4.0-rc.0 |
| sqlx | ^0.8.6 |
| tokio | ^1.50.0 |
| tonic | ^0.14.5 |
| tonic-prost | ^0.14.5 |
| tools | =0.3.0-rc.0 |
| async-std | ^1.13.1 |
| futures-util | ^0.3.17 |
| indoc | ^2.0.6 |
| tempfile | ^3.27.0 |
| tokio | ^1.7 |
| tonic-prost-build | ^0.14.5 |
| gpio-cdev | ^0.6.0 |
| linux-embedded-hal | ^0.4.0 |