stun_rs/attributes/turn/
channel_number.rs

1use crate::attributes::{stunt_attribute, DecodeAttributeValue, EncodeAttributeValue};
2use crate::context::{AttributeDecoderContext, AttributeEncoderContext};
3use crate::Encode;
4use crate::{Decode, StunError};
5
6const CHANNEL_NUMBER: u16 = 0x000C;
7const CHANNEL_NUMBER_SIZE: usize = 4;
8
9/// The `ChannelNumber` attribute contains the number of the channel.  The
10/// value portion of this attribute is 4 bytes long and consists of a
11/// 16-bit unsigned integer followed by a two-octet `RFFU` (Reserved For
12/// Future Use) field, which MUST be set to 0 on transmission and MUST be
13/// ignored on reception.
14///
15/// # Examples
16///```rust
17/// # use stun_rs::attributes::turn::ChannelNumber;
18/// let attr = ChannelNumber::new(1234);
19/// assert_eq!(attr.number(), 1234);
20///```
21#[derive(Debug, Clone, Default, PartialEq, Eq)]
22pub struct ChannelNumber {
23    number: u16,
24    rffu: u16,
25}
26
27impl ChannelNumber {
28    /// Creates a new [`ChannelNumber`] attribute
29    /// # Arguments:
30    /// `number`- The channel number
31    pub fn new(number: u16) -> Self {
32        Self { number, rffu: 0 }
33    }
34
35    /// Gets the channel number
36    pub fn number(&self) -> u16 {
37        self.number
38    }
39}
40
41impl DecodeAttributeValue for ChannelNumber {
42    fn decode(ctx: AttributeDecoderContext) -> Result<(Self, usize), StunError> {
43        let raw_value = ctx.raw_value();
44        let (number, _) = u16::decode(raw_value)?;
45        let (_rffu, _) = u16::decode(&raw_value[2..])?;
46        Ok((ChannelNumber::new(number), CHANNEL_NUMBER_SIZE))
47    }
48}
49
50impl EncodeAttributeValue for ChannelNumber {
51    fn encode(&self, mut ctx: AttributeEncoderContext) -> Result<usize, StunError> {
52        let raw_value = ctx.raw_value_mut();
53        self.number.encode(raw_value)?;
54        self.rffu.encode(&mut raw_value[2..])?;
55        Ok(CHANNEL_NUMBER_SIZE)
56    }
57}
58
59impl crate::attributes::AsVerifiable for ChannelNumber {}
60
61stunt_attribute!(ChannelNumber, CHANNEL_NUMBER);
62
63#[cfg(test)]
64mod tests {
65    use super::*;
66    use crate::error::StunErrorType;
67    use crate::StunAttribute;
68
69    #[test]
70    fn decode_channel_number_value() {
71        let dummy_msg = [];
72        let buffer = [];
73        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
74        let result = ChannelNumber::decode(ctx);
75        assert_eq!(
76            result.expect_err("Error expected"),
77            StunErrorType::SmallBuffer
78        );
79
80        let buffer = [0xab, 0xf1, 0x2f];
81        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
82        let result = ChannelNumber::decode(ctx);
83        assert_eq!(
84            result.expect_err("Error expected"),
85            StunErrorType::SmallBuffer
86        );
87
88        let buffer = [0xab, 0xf1, 0x2f, 0x34];
89        let ctx = AttributeDecoderContext::new(None, &dummy_msg, &buffer);
90        let (attr, size) = ChannelNumber::decode(ctx).expect("Can not decode ChannelNumber");
91        assert_eq!(size, 4);
92        assert_eq!(attr.number(), 0xabf1);
93    }
94
95    #[test]
96    fn encode_channel_number_value() {
97        let attr = ChannelNumber::new(0xabf1);
98        let dummy_msg = [];
99
100        let mut buffer = [];
101        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
102        let result = attr.encode(ctx);
103        assert_eq!(
104            result.expect_err("Error expected"),
105            StunErrorType::SmallBuffer
106        );
107
108        let mut buffer: [u8; 3] = [0xFF; 3];
109        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
110        let result = attr.encode(ctx);
111        assert_eq!(
112            result.expect_err("Error expected"),
113            StunErrorType::SmallBuffer
114        );
115
116        let mut buffer: [u8; 4] = [0xFF; 4];
117        let ctx = AttributeEncoderContext::new(None, &dummy_msg, &mut buffer);
118        let result = attr.encode(ctx);
119        assert_eq!(result, Ok(4));
120
121        let expected_buffer = [0xab, 0xf1, 0x00, 0x00];
122        assert_eq!(&buffer[..], &expected_buffer[..]);
123    }
124
125    #[test]
126    fn channes_numbers_stunt_attribute() {
127        let attr = StunAttribute::ChannelNumber(ChannelNumber::new(1234));
128        assert!(attr.is_channel_number());
129        assert!(attr.as_channel_number().is_ok());
130        assert!(attr.as_error_code().is_err());
131
132        assert!(attr.attribute_type().is_comprehension_required());
133        assert!(!attr.attribute_type().is_comprehension_optional());
134
135        let dbg_fmt = format!("{:?}", attr);
136        assert_eq!(
137            "ChannelNumber(ChannelNumber { number: 1234, rffu: 0 })",
138            dbg_fmt
139        );
140    }
141}