rtc_ice/attributes/control/
mod.rs1#[cfg(test)]
2mod control_test;
3
4use std::fmt;
5
6use shared::error::*;
7use stun::attributes::*;
8use stun::checks::*;
9use stun::message::*;
10
11#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
13pub struct TieBreaker(pub u64);
14
15pub(crate) const TIE_BREAKER_SIZE: usize = 8; impl TieBreaker {
18 pub fn add_to_as(self, m: &mut Message, t: AttrType) -> Result<()> {
20 let mut v = vec![0; TIE_BREAKER_SIZE];
21 v.copy_from_slice(&self.0.to_be_bytes());
22 m.add(t, &v);
23 Ok(())
24 }
25
26 pub fn get_from_as(&mut self, m: &Message, t: AttrType) -> Result<()> {
28 let v = m.get(t)?;
29 check_size(t, v.len(), TIE_BREAKER_SIZE)?;
30 self.0 = u64::from_be_bytes([v[0], v[1], v[2], v[3], v[4], v[5], v[6], v[7]]);
31 Ok(())
32 }
33}
34#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
36pub struct AttrControlled(pub u64);
37
38impl Setter for AttrControlled {
39 fn add_to(&self, m: &mut Message) -> Result<()> {
41 TieBreaker(self.0).add_to_as(m, ATTR_ICE_CONTROLLED)
42 }
43}
44
45impl Getter for AttrControlled {
46 fn get_from(&mut self, m: &Message) -> Result<()> {
48 let mut t = TieBreaker::default();
49 t.get_from_as(m, ATTR_ICE_CONTROLLED)?;
50 self.0 = t.0;
51 Ok(())
52 }
53}
54
55#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
57pub struct AttrControlling(pub u64);
58
59impl Setter for AttrControlling {
60 fn add_to(&self, m: &mut Message) -> Result<()> {
62 TieBreaker(self.0).add_to_as(m, ATTR_ICE_CONTROLLING)
63 }
64}
65
66impl Getter for AttrControlling {
67 fn get_from(&mut self, m: &Message) -> Result<()> {
69 let mut t = TieBreaker::default();
70 t.get_from_as(m, ATTR_ICE_CONTROLLING)?;
71 self.0 = t.0;
72 Ok(())
73 }
74}
75
76#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
78pub struct AttrControl {
79 role: Role,
80 tie_breaker: TieBreaker,
81}
82
83impl Setter for AttrControl {
84 fn add_to(&self, m: &mut Message) -> Result<()> {
86 if self.role == Role::Controlling {
87 self.tie_breaker.add_to_as(m, ATTR_ICE_CONTROLLING)
88 } else {
89 self.tie_breaker.add_to_as(m, ATTR_ICE_CONTROLLED)
90 }
91 }
92}
93
94impl Getter for AttrControl {
95 fn get_from(&mut self, m: &Message) -> Result<()> {
97 if m.contains(ATTR_ICE_CONTROLLING) {
98 self.role = Role::Controlling;
99 return self.tie_breaker.get_from_as(m, ATTR_ICE_CONTROLLING);
100 }
101 if m.contains(ATTR_ICE_CONTROLLED) {
102 self.role = Role::Controlled;
103 return self.tie_breaker.get_from_as(m, ATTR_ICE_CONTROLLED);
104 }
105
106 Err(Error::ErrAttributeNotFound)
107 }
108}
109
110#[derive(PartialEq, Eq, Copy, Clone, Debug)]
113pub enum Role {
114 Controlling,
115 Controlled,
116 Unspecified,
117}
118
119impl Default for Role {
120 fn default() -> Self {
121 Self::Controlling
122 }
123}
124
125impl From<&str> for Role {
126 fn from(raw: &str) -> Self {
127 match raw {
128 "controlling" => Self::Controlling,
129 "controlled" => Self::Controlled,
130 _ => Self::Unspecified,
131 }
132 }
133}
134
135impl fmt::Display for Role {
136 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
137 let s = match *self {
138 Self::Controlling => "controlling",
139 Self::Controlled => "controlled",
140 Self::Unspecified => "unspecified",
141 };
142 write!(f, "{s}")
143 }
144}