5 releases (breaking)
|0.11.0||Sep 25, 2023|
|0.10.0||Apr 25, 2023|
|0.9.0||Apr 17, 2023|
|0.8.0||Aug 26, 2022|
|0.7.1||Apr 26, 2022|
#152 in Hardware support
402 downloads per month
The device stack supports two modes, both designed for concurrency in non-threaded environments:
- A state machine implementation based off an article by Ana Hobden.
- An async-await implementation that can be used with async radio interfaces.
State machine implementation
There are two super-states that the Device can be in:
- NoSession: default state upon initialization
- Session: achieved after successful OTAA
A state machine diagram is provided in
The following LoRaWAN features are implemented:
- Class A device behavior
- Over-the-Air Activation (OTAA) and Activation by Personalization (ABP)
- Regional support for US915, and EU868
- Supports CFList in JoinAccept for EU868
- the stack starts deriving a new session when the FCnt maxes out the 32-bit counter; new session may also be created by any time by the user, as long the stack is not mid-transmit
- MAC commands are minimally mocked, as a ADRReq is responded with an ADRResp, but not much is done with the actual payload
The following design features are implemented:
- a radio abstraction layer by the following traits defined here:
radio::PhyRxTx + Timings
radio::PhyRxTxtrait enables a state machine design by the implementor
- a pass through for the LoRaWAN crypto abstraction provided by the lorawan crate, paving the way for secure elements and other hardware peripherals
- RX windows for data and join accepts are implemented by
Timeoutswhich are passed by Response up to the user, minimizing borrowing or owning of such bindings by the library
- Timeouts can be adjusted by the radio abstraction layer thanks to the
This is a work in progress and the notable limitations are:
- Class A behavior only, not B or C
- no retries on Joins or Confirmed packets and the user is instead given NoAck and NoJoinAccept responses
The async implementation uses the async-await capabilities of Rust to drive the state machine. It differs from the state machine implementation in the following ways:
- Join, send and send_recv are all async methods that can be awaited until the state transition is complete.
- When a session is expired, a SessionExpired error will be returned when attempting to send data. A new call to join must be made to establish a new session.
- The radio implementation is fully async
- A trait for an asynchronous timer is defined and must be implemented to use the async stack
- Uses the RngCore trait for random number generation
In terms of features, the async stack supports the same set of features as the state machine driven implementation.