1 #[cfg(test)] 2 mod channnum_test; 3 4 use std::fmt; 5 use stun::attributes::*; 6 use stun::checks::*; 7 use stun::message::*; 8 9 // 16 bits of uint + 16 bits of RFFU = 0. 10 const CHANNEL_NUMBER_SIZE: usize = 4; 11 12 // See https://tools.ietf.org/html/rfc5766#section-11: 13 // 14 // 0x4000 through 0x7FFF: These values are the allowed channel 15 // numbers (16,383 possible values). 16 pub const MIN_CHANNEL_NUMBER: u16 = 0x4000; 17 pub const MAX_CHANNEL_NUMBER: u16 = 0x7FFF; 18 19 // ChannelNumber represents CHANNEL-NUMBER attribute. 20 // 21 // The CHANNEL-NUMBER attribute contains the number of the channel. 22 // 23 // RFC 5766 Section 14.1 24 // encoded as uint16 25 #[derive(Default, Eq, PartialEq, Debug, Copy, Clone, Hash)] 26 pub struct ChannelNumber(pub u16); 27 28 impl fmt::Display for ChannelNumber { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result29 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 30 write!(f, "{}", self.0) 31 } 32 } 33 34 impl Setter for ChannelNumber { 35 // AddTo adds CHANNEL-NUMBER to message. add_to(&self, m: &mut Message) -> Result<(), stun::Error>36 fn add_to(&self, m: &mut Message) -> Result<(), stun::Error> { 37 let mut v = vec![0; CHANNEL_NUMBER_SIZE]; 38 v[..2].copy_from_slice(&self.0.to_be_bytes()); 39 // v[2:4] are zeroes (RFFU = 0) 40 m.add(ATTR_CHANNEL_NUMBER, &v); 41 Ok(()) 42 } 43 } 44 45 impl Getter for ChannelNumber { 46 // GetFrom decodes CHANNEL-NUMBER from message. get_from(&mut self, m: &Message) -> Result<(), stun::Error>47 fn get_from(&mut self, m: &Message) -> Result<(), stun::Error> { 48 let v = m.get(ATTR_CHANNEL_NUMBER)?; 49 50 check_size(ATTR_CHANNEL_NUMBER, v.len(), CHANNEL_NUMBER_SIZE)?; 51 52 //_ = v[CHANNEL_NUMBER_SIZE-1] // asserting length 53 self.0 = u16::from_be_bytes([v[0], v[1]]); 54 // v[2:4] is RFFU and equals to 0. 55 Ok(()) 56 } 57 } 58 59 impl ChannelNumber { 60 // is_channel_number_valid returns true if c in [0x4000, 0x7FFF]. is_channel_number_valid(&self) -> bool61 fn is_channel_number_valid(&self) -> bool { 62 self.0 >= MIN_CHANNEL_NUMBER && self.0 <= MAX_CHANNEL_NUMBER 63 } 64 65 // Valid returns true if channel number has correct value that complies RFC 5766 Section 11 range. valid(&self) -> bool66 pub fn valid(&self) -> bool { 67 self.is_channel_number_valid() 68 } 69 } 70