1 use super::*; 2 3 const VM_REPORT_BLOCK_LENGTH: u16 = 4 + 4 + 2 * 4 + 10 + 2 * 3; 4 5 /// VoIPMetricsReportBlock encodes a VoIP Metrics Report Block as described 6 /// in RFC 3611, section 4.7. 7 /// 8 /// 0 1 2 3 9 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 10 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 11 /// | BT=7 | reserved | block length = 8 | 12 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 13 /// | ssrc of source | 14 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 15 /// | loss rate | discard rate | burst density | gap density | 16 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17 /// | burst duration | gap duration | 18 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 19 /// | round trip delay | end system delay | 20 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21 /// | signal level | noise level | RERL | Gmin | 22 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 /// | R factor | ext. R factor | MOS-LQ | MOS-CQ | 24 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 /// | RX config | reserved | JB nominal | 26 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 /// | JB maximum | JB abs max | 28 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 #[derive(Debug, Default, PartialEq, Eq, Clone)] 30 pub 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 55 impl fmt::Display for VoIPMetricsReportBlock { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result56 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 57 write!(f, "{self:?}") 58 } 59 } 60 61 impl VoIPMetricsReportBlock { xr_header(&self) -> XRHeader62 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 71 impl Packet for VoIPMetricsReportBlock { header(&self) -> Header72 fn header(&self) -> Header { 73 Header::default() 74 } 75 76 /// destination_ssrc returns an array of ssrc values that this report block refers to. destination_ssrc(&self) -> Vec<u32>77 fn destination_ssrc(&self) -> Vec<u32> { 78 vec![self.ssrc] 79 } 80 raw_size(&self) -> usize81 fn raw_size(&self) -> usize { 82 XR_HEADER_LENGTH + VM_REPORT_BLOCK_LENGTH as usize 83 } 84 as_any(&self) -> &(dyn Any + Send + Sync)85 fn as_any(&self) -> &(dyn Any + Send + Sync) { 86 self 87 } equal(&self, other: &(dyn Packet + Send + Sync)) -> bool88 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool { 89 other 90 .as_any() 91 .downcast_ref::<VoIPMetricsReportBlock>() 92 .map_or(false, |a| self == a) 93 } cloned(&self) -> Box<dyn Packet + Send + Sync>94 fn cloned(&self) -> Box<dyn Packet + Send + Sync> { 95 Box::new(self.clone()) 96 } 97 } 98 99 impl MarshalSize for VoIPMetricsReportBlock { marshal_size(&self) -> usize100 fn marshal_size(&self) -> usize { 101 self.raw_size() 102 } 103 } 104 105 impl Marshal for VoIPMetricsReportBlock { 106 /// marshal_to encodes the VoIPMetricsReportBlock in binary marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>107 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> { 108 if buf.remaining_mut() < self.marshal_size() { 109 return Err(error::Error::BufferTooShort.into()); 110 } 111 112 let h = self.xr_header(); 113 let n = h.marshal_to(buf)?; 114 buf = &mut buf[n..]; 115 116 buf.put_u32(self.ssrc); 117 buf.put_u8(self.loss_rate); 118 buf.put_u8(self.discard_rate); 119 buf.put_u8(self.burst_density); 120 buf.put_u8(self.gap_density); 121 buf.put_u16(self.burst_duration); 122 buf.put_u16(self.gap_duration); 123 buf.put_u16(self.round_trip_delay); 124 buf.put_u16(self.end_system_delay); 125 buf.put_u8(self.signal_level); 126 buf.put_u8(self.noise_level); 127 buf.put_u8(self.rerl); 128 buf.put_u8(self.gmin); 129 buf.put_u8(self.rfactor); 130 buf.put_u8(self.ext_rfactor); 131 buf.put_u8(self.mos_lq); 132 buf.put_u8(self.mos_cq); 133 buf.put_u8(self.rx_config); 134 buf.put_u8(self.reserved); 135 buf.put_u16(self.jb_nominal); 136 buf.put_u16(self.jb_maximum); 137 buf.put_u16(self.jb_abs_max); 138 139 Ok(self.marshal_size()) 140 } 141 } 142 143 impl Unmarshal for VoIPMetricsReportBlock { 144 /// Unmarshal decodes the VoIPMetricsReportBlock from binary unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,145 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self> 146 where 147 Self: Sized, 148 B: Buf, 149 { 150 if raw_packet.remaining() < XR_HEADER_LENGTH { 151 return Err(error::Error::PacketTooShort.into()); 152 } 153 154 let xr_header = XRHeader::unmarshal(raw_packet)?; 155 let block_length = xr_header.block_length * 4; 156 if block_length != VM_REPORT_BLOCK_LENGTH || raw_packet.remaining() < block_length as usize 157 { 158 return Err(error::Error::PacketTooShort.into()); 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 } 210