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,
33 pub loss_rate: u8,
35 pub discard_rate: u8,
37 pub burst_density: u8,
39 pub gap_density: u8,
41 pub burst_duration: u16,
43 pub gap_duration: u16,
45 pub round_trip_delay: u16,
47 pub end_system_delay: u16,
49 pub signal_level: u8,
51 pub noise_level: u8,
53 pub rerl: u8,
55 pub gmin: u8,
57 pub rfactor: u8,
59 pub ext_rfactor: u8,
61 pub mos_lq: u8,
63 pub mos_cq: u8,
65 pub rx_config: u8,
67 pub reserved: u8,
69 pub jb_nominal: u16,
71 pub jb_maximum: u16,
73 pub jb_abs_max: u16,
75}
76
77impl fmt::Display for VoIPMetricsReportBlock {
78 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
79 write!(f, "{self:?}")
80 }
81}
82
83impl VoIPMetricsReportBlock {
84 pub fn xr_header(&self) -> XRHeader {
86 XRHeader {
87 block_type: BlockType::VoIPMetrics,
88 type_specific: 0,
89 block_length: (self.raw_size() / 4 - 1) as u16,
90 }
91 }
92}
93
94impl Packet for VoIPMetricsReportBlock {
95 fn header(&self) -> Header {
96 Header::default()
97 }
98
99 fn destination_ssrc(&self) -> Vec<u32> {
101 vec![self.ssrc]
102 }
103
104 fn raw_size(&self) -> usize {
105 XR_HEADER_LENGTH + VM_REPORT_BLOCK_LENGTH as usize
106 }
107
108 fn as_any(&self) -> &dyn Any {
109 self
110 }
111 fn equal(&self, other: &dyn Packet) -> bool {
112 other.as_any().downcast_ref::<VoIPMetricsReportBlock>() == Some(self)
113 }
114 fn cloned(&self) -> Box<dyn Packet> {
115 Box::new(self.clone())
116 }
117}
118
119impl MarshalSize for VoIPMetricsReportBlock {
120 fn marshal_size(&self) -> usize {
121 self.raw_size()
122 }
123}
124
125impl Marshal for VoIPMetricsReportBlock {
126 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
128 if buf.remaining_mut() < self.marshal_size() {
129 return Err(Error::BufferTooShort);
130 }
131
132 let h = self.xr_header();
133 let n = h.marshal_to(buf)?;
134 buf = &mut buf[n..];
135
136 buf.put_u32(self.ssrc);
137 buf.put_u8(self.loss_rate);
138 buf.put_u8(self.discard_rate);
139 buf.put_u8(self.burst_density);
140 buf.put_u8(self.gap_density);
141 buf.put_u16(self.burst_duration);
142 buf.put_u16(self.gap_duration);
143 buf.put_u16(self.round_trip_delay);
144 buf.put_u16(self.end_system_delay);
145 buf.put_u8(self.signal_level);
146 buf.put_u8(self.noise_level);
147 buf.put_u8(self.rerl);
148 buf.put_u8(self.gmin);
149 buf.put_u8(self.rfactor);
150 buf.put_u8(self.ext_rfactor);
151 buf.put_u8(self.mos_lq);
152 buf.put_u8(self.mos_cq);
153 buf.put_u8(self.rx_config);
154 buf.put_u8(self.reserved);
155 buf.put_u16(self.jb_nominal);
156 buf.put_u16(self.jb_maximum);
157 buf.put_u16(self.jb_abs_max);
158
159 Ok(self.marshal_size())
160 }
161}
162
163impl Unmarshal for VoIPMetricsReportBlock {
164 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
166 where
167 Self: Sized,
168 B: Buf,
169 {
170 if raw_packet.remaining() < XR_HEADER_LENGTH {
171 return Err(Error::PacketTooShort);
172 }
173
174 let xr_header = XRHeader::unmarshal(raw_packet)?;
175 let block_length = match xr_header.block_length.checked_mul(4) {
176 Some(length) => length,
177 None => return Err(Error::InvalidBlockSize),
178 };
179 if block_length != VM_REPORT_BLOCK_LENGTH || raw_packet.remaining() < block_length as usize
180 {
181 return Err(Error::PacketTooShort);
182 }
183
184 let ssrc = raw_packet.get_u32();
185 let loss_rate = raw_packet.get_u8();
186 let discard_rate = raw_packet.get_u8();
187 let burst_density = raw_packet.get_u8();
188 let gap_density = raw_packet.get_u8();
189 let burst_duration = raw_packet.get_u16();
190 let gap_duration = raw_packet.get_u16();
191 let round_trip_delay = raw_packet.get_u16();
192 let end_system_delay = raw_packet.get_u16();
193 let signal_level = raw_packet.get_u8();
194 let noise_level = raw_packet.get_u8();
195 let rerl = raw_packet.get_u8();
196 let gmin = raw_packet.get_u8();
197 let rfactor = raw_packet.get_u8();
198 let ext_rfactor = raw_packet.get_u8();
199 let mos_lq = raw_packet.get_u8();
200 let mos_cq = raw_packet.get_u8();
201 let rx_config = raw_packet.get_u8();
202 let reserved = raw_packet.get_u8();
203 let jb_nominal = raw_packet.get_u16();
204 let jb_maximum = raw_packet.get_u16();
205 let jb_abs_max = raw_packet.get_u16();
206
207 Ok(VoIPMetricsReportBlock {
208 ssrc,
209 loss_rate,
210 discard_rate,
211 burst_density,
212 gap_density,
213 burst_duration,
214 gap_duration,
215 round_trip_delay,
216 end_system_delay,
217 signal_level,
218 noise_level,
219 rerl,
220 gmin,
221 rfactor,
222 ext_rfactor,
223 mos_lq,
224 mos_cq,
225 rx_config,
226 reserved,
227 jb_nominal,
228 jb_maximum,
229 jb_abs_max,
230 })
231 }
232}