Skip to main content

Module region

Module region 

Source
Expand description

Regional parameters: what a LoRaWAN radio may do, and where.

A LoRa radio takes a spreading factor and a bandwidth. A region is what decides which of those are legal where the device is standing, what a data rate number means, how much payload fits, and which frequencies a gateway is listening on. Without it a caller has to already know their own channel plan, which is the difference between a stack that works on one continent and one that works anywhere.

The tables come from the LoRa Alliance RP002-1.0.5 Regional Parameters specification, and the tests assert the values the document prints rather than round-tripping the implementation against itself.

§These tables report; they never enforce

Nothing here refuses to transmit, and no call gates on a duty cycle. ChannelPlan::duty_cycle_permille says what the region specifies and LinkSettings::min_off_time_us says what that costs; the decision stays with the caller.

That is deliberate rather than squeamish. Most of what a regional plan encodes is physics and coordination rather than permission: the bands differ because each regulator left different spectrum unlicensed, a duty cycle is what stops an unlicensed band collapsing under everyone talking at once, and the plan doubles as a description of what a radio front end tuned for that band can physically do. But a node in a disaster zone may be operating under emergency spectrum provisions, or somewhere the question has stopped being meaningful, and a library that refused to transmit there would be harmful exactly where it is needed most. So the tables inform, the arithmetic costs it out, and the operator decides.

§A named region is a convenience, not the only way in

Region is a shortcut to a ChannelPlan, which is an ordinary struct of borrowed tables. A private deployment holding licensed spectrum, or bespoke emergency work, builds its own plan from parts it owns and everything here still applies to it. The tables are borrowed rather than owned so the crate allocates nothing: the published plans point at constants, and a plan built at runtime points at whatever storage its caller chose.

§Examples

use pamoja_lora::region::{Modulation, Region};

let plan = Region::Eu868.plan();

// DR5 in Europe is SF7 at 125 kHz.
let dr5 = plan.uplink_data_rate(5).expect("EU868 defines DR5");
assert_eq!(
    dr5.modulation,
    Modulation::LoRa { spreading_factor: 7, bandwidth_hz: 125_000 }
);

// Talking straight to a gateway it carries 242 bytes of application payload,
// and 222 if it may sit behind a repeater, which costs 20 bytes to encapsulate.
assert_eq!(plan.max_payload(5, false).expect("DR5 carries payload").application, 242);
assert_eq!(plan.max_payload(5, true).expect("DR5 carries payload").application, 222);

// The airtime math already in this crate takes it from here.
let settings = plan.link_settings(5).expect("DR5 is a LoRa data rate");
assert!(settings.airtime_us(51) > 0);

Structs§

Beacon
The Class B beacon settings a region broadcasts on.
ChannelBlock
A run of evenly spaced channels, which is how the plans define them.
ChannelPlan
A complete regional channel plan.
ChannelPlanBuilder
Assembles a OwnedChannelPlan a table at a time.
DataRate
One data rate: how it is modulated and how fast it carries bits.
MaxPayload
The largest payload a data rate carries.
OwnedChannelPlan
A channel plan that owns its tables.
SubBand
A stretch of spectrum with its own transmit limits.

Enums§

Modulation
How a data rate puts bits on the air.
PayloadTable
Which of a plan’s payload tables an entry belongs to.
PlanError
Why a plan could not be built.
Region
A named regional channel plan.