pamoja_lora/region/channel_list.rs
1//! The published channel numberings a channel mask can refer to.
2
3/// A published list that gives every channel number a frequency.
4///
5/// RP002-1.0.5 section 3.3.1 fixes a frequency for each number, so a network can enable
6/// channels on a device with a bit each rather than spelling their frequencies out. A join
7/// accept's type 1 channel list is read this way in a dynamic channel plan: each bit set
8/// creates the channel its number stands for.
9///
10/// # Examples
11///
12/// ```
13/// use pamoja_lora::region::FixedChannelList;
14///
15/// assert_eq!(FixedChannelList::Mhz800.frequency_hz(0), Some(863_100_000));
16/// assert_eq!(FixedChannelList::Mhz800.frequency_hz(39), Some(865_985_000));
17/// assert_eq!(FixedChannelList::Mhz900.frequency_hz(95), Some(924_600_000));
18/// assert_eq!(FixedChannelList::Mhz900.frequency_hz(96), None);
19/// ```
20#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
21pub enum FixedChannelList {
22 /// Section 3.3.1.1: forty channels, from 863.1 MHz in 200 kHz steps to 869.9 MHz at
23 /// channel 34, then five at 865.0625, 865.4025, 865.6025, 865.785 and 865.985 MHz. It
24 /// covers the channels EU868, IN865 and RU864 networks run.
25 Mhz800,
26 /// Section 3.3.1.2: ninety-six channels, from 915.1 MHz in 100 kHz steps to 924.6 MHz.
27 /// It covers the channels AS923 and KR920 networks run.
28 Mhz900,
29}
30
31impl FixedChannelList {
32 /// Returns the frequency a channel number stands for.
33 ///
34 /// # Arguments
35 ///
36 /// * `channel` - the channel number.
37 ///
38 /// # Returns
39 ///
40 /// The frequency in hertz, or [`None`] for a number the list does not define.
41 pub const fn frequency_hz(self, channel: u8) -> Option<u32> {
42 match self {
43 FixedChannelList::Mhz800 => match channel {
44 0..=34 => Some(863_100_000 + channel as u32 * 200_000),
45 35 => Some(865_062_500),
46 36 => Some(865_402_500),
47 37 => Some(865_602_500),
48 38 => Some(865_785_000),
49 39 => Some(865_985_000),
50 _ => None,
51 },
52 FixedChannelList::Mhz900 => match channel {
53 0..=95 => Some(915_100_000 + channel as u32 * 100_000),
54 _ => None,
55 },
56 }
57 }
58
59 /// Returns how many channels the list defines.
60 ///
61 /// # Returns
62 ///
63 /// Forty for the 800 MHz list, ninety-six for the 900 MHz one.
64 pub const fn len(self) -> u8 {
65 match self {
66 FixedChannelList::Mhz800 => 40,
67 FixedChannelList::Mhz900 => 96,
68 }
69 }
70
71 /// Reports whether the list defines no channels, which neither published list does.
72 ///
73 /// # Returns
74 ///
75 /// `false`.
76 pub const fn is_empty(self) -> bool {
77 self.len() == 0
78 }
79}
80
81#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn the_lists_end_where_the_document_says() {
87 // RP002-1.0.5 sections 3.3.1.1 and 3.3.1.2.
88 assert_eq!(FixedChannelList::Mhz800.frequency_hz(34), Some(869_900_000));
89 assert_eq!(FixedChannelList::Mhz800.frequency_hz(35), Some(865_062_500));
90 assert_eq!(FixedChannelList::Mhz800.frequency_hz(36), Some(865_402_500));
91 assert_eq!(FixedChannelList::Mhz800.frequency_hz(37), Some(865_602_500));
92 assert_eq!(FixedChannelList::Mhz800.frequency_hz(38), Some(865_785_000));
93 assert_eq!(FixedChannelList::Mhz800.frequency_hz(40), None);
94 assert_eq!(FixedChannelList::Mhz800.len(), 40);
95 assert_eq!(FixedChannelList::Mhz900.frequency_hz(0), Some(915_100_000));
96 assert_eq!(FixedChannelList::Mhz900.len(), 96);
97 }
98
99 #[test]
100 fn the_examples_under_the_800_mhz_list_land_on_their_frequencies() {
101 // Section 3.3.1.1's worked example creates channels 0, 21, 23 and 28 at 863.1,
102 // 867.3, 867.7 and 868.7 MHz.
103 let example: [u32; 4] = [0, 21, 23, 28].map(|channel| {
104 FixedChannelList::Mhz800
105 .frequency_hz(channel)
106 .expect("defined")
107 });
108 assert_eq!(
109 example,
110 [863_100_000, 867_300_000, 867_700_000, 868_700_000]
111 );
112
113 // Its notes put the EU868 default channels at 25 to 27, and the four RFID channels
114 // of ETSI EN 302 208 at 13, 16, 19 and 22.
115 let defaults: [u32; 3] = [25, 26, 27].map(|channel| {
116 FixedChannelList::Mhz800
117 .frequency_hz(channel)
118 .expect("defined")
119 });
120 assert_eq!(defaults, [868_100_000, 868_300_000, 868_500_000]);
121 let rfid: [u32; 4] = [13, 16, 19, 22].map(|channel| {
122 FixedChannelList::Mhz800
123 .frequency_hz(channel)
124 .expect("defined")
125 });
126 assert_eq!(rfid, [865_700_000, 866_300_000, 866_900_000, 867_500_000]);
127 }
128}