Skip to main content

pamoja_lorawan/relay/
mode.rs

1//! How an end device decides to use a relay, TS011-1.0.1 sections 3.9 and 10.2.
2
3/// How an end device manages its relay mode, TS011-1.0.1 table 40.
4#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
5pub enum RelayActivation {
6    /// Never send through a relay.
7    Disabled,
8    /// Always send through a relay, whether or not one answers.
9    Enabled,
10    /// Start sending through a relay after enough uplinks go unanswered, with
11    /// [`smart_enable_uplinks`] of them.
12    Dynamic,
13    /// Leave it to the device, which is where every device starts and returns to when it
14    /// joins again.
15    DeviceControlled,
16}
17
18impl RelayActivation {
19    /// Reads a coded mode, 0 through 3.
20    ///
21    /// # Arguments
22    ///
23    /// * `code` - the two bits an `EndDeviceConfReq` carries; only those are read.
24    ///
25    /// # Returns
26    ///
27    /// The mode.
28    #[must_use]
29    pub const fn from_code(code: u8) -> RelayActivation {
30        match code & 0x03 {
31            0 => RelayActivation::Disabled,
32            1 => RelayActivation::Enabled,
33            2 => RelayActivation::Dynamic,
34            _ => RelayActivation::DeviceControlled,
35        }
36    }
37
38    /// Returns the value an `EndDeviceConfReq` carries.
39    ///
40    /// # Returns
41    ///
42    /// The code, 0 through 3.
43    #[must_use]
44    pub const fn code(self) -> u8 {
45        self as u8
46    }
47}
48
49/// How many uplinks may go unanswered before a device in [`RelayActivation::Dynamic`] mode
50/// starts using a relay, TS011-1.0.1 table 41.
51///
52/// # Arguments
53///
54/// * `level` - the coded level; only its low two bits are read.
55///
56/// # Returns
57///
58/// 8, 16, 32 or 64.
59///
60/// # Examples
61///
62/// ```
63/// use pamoja_lorawan::relay::smart_enable_uplinks;
64///
65/// assert_eq!(smart_enable_uplinks(0), 8);
66/// assert_eq!(smart_enable_uplinks(3), 64);
67/// ```
68#[must_use]
69pub const fn smart_enable_uplinks(level: u8) -> u16 {
70    8 << (level & 0x03)
71}
72
73/// What an end device knows about when its relay listens, TS011-1.0.1 section 3.9.
74#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
75pub enum RelaySync {
76    /// Nothing: the device assumes a relay scanning every second with a crystal good to 40
77    /// parts per million and eight symbols to start receiving, sends a preamble spanning
78    /// that whole second, and alternates the region's default channels.
79    Initialized,
80    /// How the relay scans, but not when: the preamble spans one scan period.
81    Unsynchronized,
82    /// When the relay next scans, so a preamble need only cover the drift since the last
83    /// acknowledgment.
84    Synchronized,
85}