rtc_rtcp/extended_report/
vm.rs1use super::*;
2
3const VM_REPORT_BLOCK_LENGTH: u16 = 4 + 4 + 2 * 4 + 10 + 2 * 3;
4
5#[derive(Debug, Default, PartialEq, Eq, Clone)]
30pub struct VoIPMetricsReportBlock {
31 pub ssrc: u32,
32 pub loss_rate: u8,
33 pub discard_rate: u8,
34 pub burst_density: u8,
35 pub gap_density: u8,
36 pub burst_duration: u16,
37 pub gap_duration: u16,
38 pub round_trip_delay: u16,
39 pub end_system_delay: u16,
40 pub signal_level: u8,
41 pub noise_level: u8,
42 pub rerl: u8,
43 pub gmin: u8,
44 pub rfactor: u8,
45 pub ext_rfactor: u8,
46 pub mos_lq: u8,
47 pub mos_cq: u8,
48 pub rx_config: u8,
49 pub reserved: u8,
50 pub jb_nominal: u16,
51 pub jb_maximum: u16,
52 pub jb_abs_max: u16,
53}
54
55impl fmt::Display for VoIPMetricsReportBlock {
56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
57 write!(f, "{self:?}")
58 }
59}
60
61impl VoIPMetricsReportBlock {
62 pub fn xr_header(&self) -> XRHeader {
63 XRHeader {
64 block_type: BlockType::VoIPMetrics,
65 type_specific: 0,
66 block_length: (self.raw_size() / 4 - 1) as u16,
67 }
68 }
69}
70
71impl Packet for VoIPMetricsReportBlock {
72 fn header(&self) -> Header {
73 Header::default()
74 }
75
76 fn destination_ssrc(&self) -> Vec<u32> {
78 vec![self.ssrc]
79 }
80
81 fn raw_size(&self) -> usize {
82 XR_HEADER_LENGTH + VM_REPORT_BLOCK_LENGTH as usize
83 }
84
85 fn as_any(&self) -> &dyn Any {
86 self
87 }
88 fn equal(&self, other: &dyn Packet) -> bool {
89 other.as_any().downcast_ref::<VoIPMetricsReportBlock>() == Some(self)
90 }
91 fn cloned(&self) -> Box<dyn Packet> {
92 Box::new(self.clone())
93 }
94}
95
96impl MarshalSize for VoIPMetricsReportBlock {
97 fn marshal_size(&self) -> usize {
98 self.raw_size()
99 }
100}
101
102impl Marshal for VoIPMetricsReportBlock {
103 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
105 if buf.remaining_mut() < self.marshal_size() {
106 return Err(Error::BufferTooShort);
107 }
108
109 let h = self.xr_header();
110 let n = h.marshal_to(buf)?;
111 buf = &mut buf[n..];
112
113 buf.put_u32(self.ssrc);
114 buf.put_u8(self.loss_rate);
115 buf.put_u8(self.discard_rate);
116 buf.put_u8(self.burst_density);
117 buf.put_u8(self.gap_density);
118 buf.put_u16(self.burst_duration);
119 buf.put_u16(self.gap_duration);
120 buf.put_u16(self.round_trip_delay);
121 buf.put_u16(self.end_system_delay);
122 buf.put_u8(self.signal_level);
123 buf.put_u8(self.noise_level);
124 buf.put_u8(self.rerl);
125 buf.put_u8(self.gmin);
126 buf.put_u8(self.rfactor);
127 buf.put_u8(self.ext_rfactor);
128 buf.put_u8(self.mos_lq);
129 buf.put_u8(self.mos_cq);
130 buf.put_u8(self.rx_config);
131 buf.put_u8(self.reserved);
132 buf.put_u16(self.jb_nominal);
133 buf.put_u16(self.jb_maximum);
134 buf.put_u16(self.jb_abs_max);
135
136 Ok(self.marshal_size())
137 }
138}
139
140impl Unmarshal for VoIPMetricsReportBlock {
141 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
143 where
144 Self: Sized,
145 B: Buf,
146 {
147 if raw_packet.remaining() < XR_HEADER_LENGTH {
148 return Err(Error::PacketTooShort);
149 }
150
151 let xr_header = XRHeader::unmarshal(raw_packet)?;
152 let block_length = match xr_header.block_length.checked_mul(4) {
153 Some(length) => length,
154 None => return Err(Error::InvalidBlockSize),
155 };
156 if block_length != VM_REPORT_BLOCK_LENGTH || raw_packet.remaining() < block_length as usize
157 {
158 return Err(Error::PacketTooShort);
159 }
160
161 let ssrc = raw_packet.get_u32();
162 let loss_rate = raw_packet.get_u8();
163 let discard_rate = raw_packet.get_u8();
164 let burst_density = raw_packet.get_u8();
165 let gap_density = raw_packet.get_u8();
166 let burst_duration = raw_packet.get_u16();
167 let gap_duration = raw_packet.get_u16();
168 let round_trip_delay = raw_packet.get_u16();
169 let end_system_delay = raw_packet.get_u16();
170 let signal_level = raw_packet.get_u8();
171 let noise_level = raw_packet.get_u8();
172 let rerl = raw_packet.get_u8();
173 let gmin = raw_packet.get_u8();
174 let rfactor = raw_packet.get_u8();
175 let ext_rfactor = raw_packet.get_u8();
176 let mos_lq = raw_packet.get_u8();
177 let mos_cq = raw_packet.get_u8();
178 let rx_config = raw_packet.get_u8();
179 let reserved = raw_packet.get_u8();
180 let jb_nominal = raw_packet.get_u16();
181 let jb_maximum = raw_packet.get_u16();
182 let jb_abs_max = raw_packet.get_u16();
183
184 Ok(VoIPMetricsReportBlock {
185 ssrc,
186 loss_rate,
187 discard_rate,
188 burst_density,
189 gap_density,
190 burst_duration,
191 gap_duration,
192 round_trip_delay,
193 end_system_delay,
194 signal_level,
195 noise_level,
196 rerl,
197 gmin,
198 rfactor,
199 ext_rfactor,
200 mos_lq,
201 mos_cq,
202 rx_config,
203 reserved,
204 jb_nominal,
205 jb_maximum,
206 jb_abs_max,
207 })
208 }
209}