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}