contact_sensor (0.1.0)
Published 2026-03-07 20:25:55 +00:00 by faicel
Installation
[registries.forgejo]
index = "sparse+ " # Sparse index
# index = " " # Git
[net]
git-fetch-with-cli = truecargo add contact_sensor@0.1.0 --registry forgejoAbout this package
Contact sensor logic with encryption for IoT security systems
Contact Sensor Library
Portable Rust no_std library for IoT contact sensors with encryption.
Overview
contact_sensor provides reusable business logic for contact sensors (door, window, etc.) with encrypted LoRa communication. This library is portable and runs on any microcontroller that supports embedded Rust.
Features
- Cryptography: Key derivation with HKDF-SHA256
- State machine: Robust system state management
- Testable: Automated tests on host target
- Portable:
no_std, works on any MCU - Flexible: Uses
embedded-halfor hardware abstraction
Installation
Add to your Cargo.toml:
[dependencies]
contact_sensor = { path = "../libs/contact_sensor" }
Usage
Module config: Key management
use contact_sensor::config;
// Get the master key
let master_key = config::get_master_key();
// Derive an installation key
let install_key = config::derive_install_key();
Module state: State machine
use contact_sensor::state::{StateMachine, SystemState};
// Create a new state machine
let mut sm = StateMachine::new(SystemState::NotInstalled);
// Transitions
sm.set_installed(); // NotInstalled → Installed
sm.set_alarm(); // Installed → Alarm
sm.clear_alarm(); // Alarm → Installed
// Check state
if sm.current().is_alarm_active() {
println!("Alarm active!");
}
Module alarm: Alarm control
use contact_sensor::alarm::AlarmController;
// With your specific HAL
let led = pins.pa21.into_push_pull_output();
let buzzer = pins.pa22.into_push_pull_output();
let mut alarm = AlarmController::new(led, buzzer);
// Activate alarm
alarm.activate().unwrap();
// Deactivate alarm
alarm.deactivate().unwrap();
// Toggle
alarm.toggle().unwrap();
Module timeout: Timeout handling
use contact_sensor::timeout::{with_timeout_and_retry, TimeoutResult};
let mut delay = hal::delay::Delay::new(core_peripherals.SYST, clocks);
let result = with_timeout_and_retry(
|| send_lora_message(),
1000, // timeout ms
3, // max retries
500, // retry delay ms
&mut delay
);
match result {
TimeoutResult::Success(value) => println!("Success!"),
TimeoutResult::Error => println!("Failed after retries"),
TimeoutResult::Timeout => println!("Timeout"),
}
Tests
Run tests on the host target:
# All tests
cargo test --features std
# Specific test suites
cargo test --test config_tests
cargo test --test state_tests
cargo test --test alarm_tests
cargo test --test timeout_tests
Result: 32 tests pass
- 7 tests for
config(cryptography) - 6 tests for
state(state machine) - 6 tests for
alarm(LED/buzzer control with embedded-hal-mock) - 8 tests for
timeout(timeout/retry handling with embedded-hal-mock) - 5 doctests
Modules
| Module | Description | Tests |
|---|---|---|
config |
Key management (HKDF-SHA256) | 7 |
state |
State machine (NotInstalled → Installed → Alarm) | 6 |
alarm |
Alarm control (LED + Buzzer, embedded-hal) | 6 |
timeout |
Timeout and retry handling (embedded-hal) | 8 |
Firmware integration
Example with RTIC (SAMD21)
// Cargo.toml
[dependencies]
contact_sensor = { path = "../libs/contact_sensor" }
atsamd-hal = "0.22.2"
rtic = "2.2.0"
// main.rs
use contact_sensor::{config, state};
#[rtic::app]
mod app {
use super::*;
#[shared]
struct Shared {
state_machine: state::StateMachine,
}
#[init]
fn init(cx: init::Context) -> (Shared, Local) {
// Use contact_sensor logic
let install_key = config::derive_install_key();
let state_machine = state::StateMachine::new(
state::SystemState::NotInstalled
);
(Shared { state_machine }, Local {})
}
}
Example with Embassy (ESP32)
use contact_sensor::{config, state};
use embassy_executor::Spawner;
#[embassy_executor::main]
async fn main(spawner: Spawner) {
let mut sm = state::StateMachine::new(state::SystemState::NotInstalled);
let key = config::derive_install_key();
// Your logic...
}
Architecture
┌─────────────────────────────────────────────┐
│ contact_sensor (portable lib) │
│ - config: Key management │
│ - state: State machine │
│ - alarm: Alarm (embedded-hal) │
└─────────────────────────────────────────────┘
▲
│ used by
│
┌─────────────────────────────────────────────┐
│ Specific firmware (SAMD21, ESP32, etc.) │
│ - RTIC / Embassy / bare-metal │
│ - Specific HAL │
│ - Hardware configuration │
└─────────────────────────────────────────────┘
Documentation
Generate full documentation:
cargo doc --no-default-features --features std --open
Security
Important: The MASTER_KEY is hardcoded for development. In production:
- Use a Secure Element (e.g. ATECC608A)
- Load from encrypted storage
- Never commit production keys
License
Personal Use Only — Non-Commercial (see LICENSE).
Author
Faicel - faicelbhk@gmail.com
Contributing
Contributions are welcome. This library is designed to be generic and reusable.
Dependencies
| ID | Version |
|---|---|
| embedded-hal | ^1.0 |
| hkdf | ^0.12 |
| sha2 | ^0.10 |
| embedded-hal-mock | ^0.11 |
Details
2026-03-07 20:25:55 +00:00
Assets (1)
Versions (1)
View all
Cargo
11
faicel <faicelbhk@gmail.com>
14 KiB
contact_sensor-0.1.0.crate
14 KiB
0.1.0
2026-03-07