pamoja_lora/lib.rs
1#![cfg_attr(not(any(test, feature = "std")), no_std)]
2
3//! LoRa link math for the pamoja SDK.
4//!
5//! LoRa is the SDK's answer to reach: kilometers of range on license-free bands at
6//! tiny power. That reach comes with a hard constraint, though. A LoRa transmission
7//! occupies the channel for a duration fixed by the radio settings, and the regional
8//! regulations a deployment lives under cap how much of the time a node may transmit,
9//! typically around one percent. A node that ignores this is both illegal and, since
10//! transmitting is the most expensive thing it does, wasteful of its battery.
11//!
12//! This crate provides the arithmetic that keeps a long-range node honest, with no
13//! radio and no floating point:
14//!
15//! - [`LinkSettings`] - the spreading factor, bandwidth, coding rate, and frame
16//! options of a link, with [`airtime_us`](LinkSettings::airtime_us) for a payload's
17//! exact time on air and [`min_off_time_us`](LinkSettings::min_off_time_us) for the
18//! silence a duty-cycle limit then forces.
19//! - [`budget`] - the link budget, in hundredths of a decibel: EIRP, free-space loss,
20//! the first Fresnel zone, receiver sensitivity from the noise floor and the
21//! demodulator SNR, the margin a path leaves, and the transmit power a regional
22//! ceiling or 47 CFR 15.247 allows through an antenna.
23//!
24//! The time-on-air calculation is the published LoRa formula, evaluated with exact
25//! integer arithmetic, so the same numbers a deployment planner uses are available on
26//! the node itself. It pairs naturally with the metered-link batch encoding in
27//! `pamoja-codec` - pack a batch, then ask what it costs to send - and with the
28//! duty-cycling in `pamoja-power`.
29//!
30//! The crate drives no radio. It is the arithmetic a radio driver and a deployment
31//! plan both work from.
32//!
33//! # Examples
34//!
35//! ```
36//! use pamoja_lora::LinkSettings;
37//!
38//! let link = LinkSettings::new(12, 125_000); // SF12, 125 kHz: maximum range
39//! let airtime = link.airtime_us(20); // time on air of a 20-byte payload
40//!
41//! // At a 1% duty cycle, the node must then stay quiet for ninety-nine times as long.
42//! assert_eq!(link.min_off_time_us(20, 10), airtime * 99);
43//! ```
44
45#[cfg(feature = "alloc")]
46extern crate alloc;
47
48mod link;
49
50pub mod budget;
51pub mod region;
52
53pub use link::LinkSettings;