twine_codec/radio/
channel.rs1use bytes::{Buf, BufMut};
9use typed_builder::TypedBuilder;
10
11use twine_rs_macros::Tlv;
12use twine_tlv::prelude::*;
13
14use crate::error::TwineCodecError;
15
16#[derive(Clone, Copy, Debug, Default, Eq, PartialEq, Tlv, TypedBuilder)]
18#[tlv(tlv_type = 0x00, tlv_length = 3)]
19pub struct Channel {
20 channel: u16,
21 page: u8,
22}
23
24impl Channel {
25 pub fn random() -> Self {
27 let channel = crate::random_range_u16(11..=26);
28 let page: u8 = 0;
29 Self { channel, page }
30 }
31
32 pub fn new(page: u8, channel: u16) -> Self {
33 Self { channel, page }
34 }
35
36 pub fn channel(&self) -> u16 {
37 self.channel
38 }
39
40 pub fn page(&self) -> u8 {
41 self.page
42 }
43
44 pub fn from_str_channel_only(s: &str) -> Result<Self, TwineCodecError> {
45 let channel = s
46 .parse::<u16>()
47 .map_err(|_| TwineCodecError::StringParseError)?;
48 Ok(Self::new(0, channel))
49 }
50}
51
52impl DecodeTlvValueUnchecked for Channel {
53 fn decode_tlv_value_unchecked(buffer: impl AsRef<[u8]>) -> Self {
54 let mut buffer = buffer.as_ref();
55 let page = buffer.get_u8();
56 let channel = buffer.get_u16();
57
58 Self { channel, page }
59 }
60}
61
62impl TryEncodeTlvValue for Channel {
63 fn try_encode_tlv_value(&self, buffer: &mut [u8]) -> Result<usize, TwineTlvError> {
64 let mut buffer = buffer;
65 buffer.put_u8(self.page());
66 buffer.put_u16(self.channel());
67 Ok(self.tlv_len())
68 }
69}
70
71#[cfg(test)]
72mod tests {
73 use std::println;
74
75 use super::*;
76
77 const CHANNEL_TLV_BYTES: [u8; 5] = [0x00, 0x03, 0x00, 0x00, 0x16];
78
79 #[test]
80 fn test_channel_random() {
81 let channel = Channel::random();
82 assert!(channel.channel() >= 11 && channel.channel() <= 26);
83 assert_eq!(channel.page(), 0);
84 }
85
86 #[test]
87 fn success_decode_unchecked_meshcop_tlv_for_channel() {
88 let test = Channel::decode_tlv_unchecked(CHANNEL_TLV_BYTES);
89 assert_eq!(test.page(), 0);
90 assert_eq!(test.channel(), 22);
91 }
92
93 #[test]
94 fn success_try_encode_meshcop_tlv_for_channel() {
95 let channel = Channel::new(0, 22);
96 let mut test_buffer = [0_u8; 10];
97 let bytes_written = channel
98 .try_encode_tlv(&mut test_buffer)
99 .expect("Could not encode Channel");
100 println!("Encoded Channel TLV: {:?}", &test_buffer[..]);
101 assert_eq!(bytes_written, Channel::tlv_total_constant_len());
102 assert_eq!(CHANNEL_TLV_BYTES.as_ref(), &test_buffer[..5]);
103 }
104
105 #[test]
106 fn success_from_str_channel_only() {
107 let channel =
108 Channel::from_str_channel_only("16").expect("Could not parse Channel from string");
109 assert_eq!(channel.page(), 0);
110 assert_eq!(channel.channel(), 16);
111 }
112}