1 #[cfg(test)] 2 mod transport_layer_cc_test; 3 4 use crate::{error::Error, header::*, packet::*, util::*}; 5 use util::marshal::{Marshal, MarshalSize, Unmarshal}; 6 7 use bytes::{Buf, BufMut}; 8 use std::any::Any; 9 use std::fmt; 10 11 type Result<T> = std::result::Result<T, util::Error>; 12 13 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#page-5 14 /// 0 1 2 3 15 /// 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 16 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 17 /// |V=2|P| FMT=15 | PT=205 | length | 18 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 19 /// | SSRC of packet sender | 20 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 21 /// | SSRC of media source | 22 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 23 /// | base sequence number | packet status count | 24 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 25 /// | reference time | fb pkt. count | 26 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 27 /// | packet chunk | packet chunk | 28 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 29 /// . . 30 /// . . 31 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 32 /// | packet chunk | recv delta | recv delta | 33 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 34 /// . . 35 /// . . 36 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 37 /// | recv delta | recv delta | zero padding | 38 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 39 40 // for packet status chunk 41 /// type of packet status chunk 42 #[derive(Default, PartialEq, Eq, Debug, Clone)] 43 #[repr(u16)] 44 pub enum StatusChunkTypeTcc { 45 #[default] 46 RunLengthChunk = 0, 47 StatusVectorChunk = 1, 48 } 49 50 /// type of packet status symbol and recv delta 51 #[derive(Default, PartialEq, Eq, Debug, Copy, Clone)] 52 #[repr(u16)] 53 pub enum SymbolTypeTcc { 54 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1.1 55 #[default] 56 PacketNotReceived = 0, 57 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1.1 58 PacketReceivedSmallDelta = 1, 59 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1.1 60 PacketReceivedLargeDelta = 2, 61 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#page-7 62 /// see Example 2: "packet received, w/o recv delta" 63 PacketReceivedWithoutDelta = 3, 64 } 65 66 /// for status vector chunk 67 #[derive(Default, PartialEq, Eq, Debug, Copy, Clone)] 68 #[repr(u16)] 69 pub enum SymbolSizeTypeTcc { 70 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1.4 71 #[default] 72 OneBit = 0, 73 TwoBit = 1, 74 } 75 76 impl From<u16> for SymbolSizeTypeTcc { from(val: u16) -> Self77 fn from(val: u16) -> Self { 78 match val { 79 0 => SymbolSizeTypeTcc::OneBit, 80 _ => SymbolSizeTypeTcc::TwoBit, 81 } 82 } 83 } 84 85 impl From<u16> for StatusChunkTypeTcc { from(val: u16) -> Self86 fn from(val: u16) -> Self { 87 match val { 88 0 => StatusChunkTypeTcc::RunLengthChunk, 89 _ => StatusChunkTypeTcc::StatusVectorChunk, 90 } 91 } 92 } 93 94 impl From<u16> for SymbolTypeTcc { from(val: u16) -> Self95 fn from(val: u16) -> Self { 96 match val { 97 0 => SymbolTypeTcc::PacketNotReceived, 98 1 => SymbolTypeTcc::PacketReceivedSmallDelta, 99 2 => SymbolTypeTcc::PacketReceivedLargeDelta, 100 _ => SymbolTypeTcc::PacketReceivedWithoutDelta, 101 } 102 } 103 } 104 105 /// PacketStatusChunk has two kinds: 106 /// RunLengthChunk and StatusVectorChunk 107 #[derive(Debug, Clone, PartialEq, Eq)] 108 pub enum PacketStatusChunk { 109 RunLengthChunk(RunLengthChunk), 110 StatusVectorChunk(StatusVectorChunk), 111 } 112 113 impl MarshalSize for PacketStatusChunk { marshal_size(&self) -> usize114 fn marshal_size(&self) -> usize { 115 match self { 116 PacketStatusChunk::RunLengthChunk(c) => c.marshal_size(), 117 PacketStatusChunk::StatusVectorChunk(c) => c.marshal_size(), 118 } 119 } 120 } 121 122 impl Marshal for PacketStatusChunk { 123 /// Marshal .. marshal_to(&self, buf: &mut [u8]) -> Result<usize>124 fn marshal_to(&self, buf: &mut [u8]) -> Result<usize> { 125 match self { 126 PacketStatusChunk::RunLengthChunk(c) => c.marshal_to(buf), 127 PacketStatusChunk::StatusVectorChunk(c) => c.marshal_to(buf), 128 } 129 } 130 } 131 132 /// RunLengthChunk T=TypeTCCRunLengthChunk 133 /// 0 1 134 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 135 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 136 /// |T| S | Run Length | 137 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 138 #[derive(Debug, Clone, PartialEq, Eq, Default)] 139 pub struct RunLengthChunk { 140 /// T = TypeTCCRunLengthChunk 141 pub type_tcc: StatusChunkTypeTcc, 142 /// S: type of packet status 143 /// kind: TypeTCCPacketNotReceived or... 144 pub packet_status_symbol: SymbolTypeTcc, 145 /// run_length: count of S 146 pub run_length: u16, 147 } 148 149 impl MarshalSize for RunLengthChunk { marshal_size(&self) -> usize150 fn marshal_size(&self) -> usize { 151 PACKET_STATUS_CHUNK_LENGTH 152 } 153 } 154 155 impl Marshal for RunLengthChunk { 156 /// Marshal .. marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>157 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> { 158 // append 1 bit '0' 159 let mut dst = set_nbits_of_uint16(0, 1, 0, 0)?; 160 161 // append 2 bit packet_status_symbol 162 dst = set_nbits_of_uint16(dst, 2, 1, self.packet_status_symbol as u16)?; 163 164 // append 13 bit run_length 165 dst = set_nbits_of_uint16(dst, 13, 3, self.run_length)?; 166 167 buf.put_u16(dst); 168 169 Ok(PACKET_STATUS_CHUNK_LENGTH) 170 } 171 } 172 173 impl Unmarshal for RunLengthChunk { 174 /// Unmarshal .. unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,175 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self> 176 where 177 Self: Sized, 178 B: Buf, 179 { 180 let raw_packet_len = raw_packet.remaining(); 181 if raw_packet_len < PACKET_STATUS_CHUNK_LENGTH { 182 return Err(Error::PacketStatusChunkLength.into()); 183 } 184 185 // record type 186 let type_tcc = StatusChunkTypeTcc::RunLengthChunk; 187 188 let b0 = raw_packet.get_u8(); 189 let b1 = raw_packet.get_u8(); 190 191 // get PacketStatusSymbol 192 let packet_status_symbol = get_nbits_from_byte(b0, 1, 2).into(); 193 194 // get RunLength 195 let run_length = ((get_nbits_from_byte(b0, 3, 5) as usize) << 8) as u16 + (b1 as u16); 196 197 Ok(RunLengthChunk { 198 type_tcc, 199 packet_status_symbol, 200 run_length, 201 }) 202 } 203 } 204 205 /// StatusVectorChunk T=typeStatusVecotrChunk 206 /// 0 1 207 /// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 208 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 209 /// |T|S| symbol list | 210 /// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 211 #[derive(Debug, Clone, PartialEq, Eq, Default)] 212 pub struct StatusVectorChunk { 213 /// T = TypeTCCRunLengthChunk 214 pub type_tcc: StatusChunkTypeTcc, 215 216 /// TypeTCCSymbolSizeOneBit or TypeTCCSymbolSizeTwoBit 217 pub symbol_size: SymbolSizeTypeTcc, 218 219 /// when symbol_size = TypeTCCSymbolSizeOneBit, symbol_list is 14*1bit: 220 /// TypeTCCSymbolListPacketReceived or TypeTCCSymbolListPacketNotReceived 221 /// when symbol_size = TypeTCCSymbolSizeTwoBit, symbol_list is 7*2bit: 222 /// TypeTCCPacketNotReceived TypeTCCPacketReceivedSmallDelta TypeTCCPacketReceivedLargeDelta or typePacketReserved 223 pub symbol_list: Vec<SymbolTypeTcc>, 224 } 225 226 impl MarshalSize for StatusVectorChunk { marshal_size(&self) -> usize227 fn marshal_size(&self) -> usize { 228 PACKET_STATUS_CHUNK_LENGTH 229 } 230 } 231 232 impl Marshal for StatusVectorChunk { 233 /// Marshal .. marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>234 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> { 235 // set first bit '1' 236 let mut dst = set_nbits_of_uint16(0, 1, 0, 1)?; 237 238 // set second bit symbol_size 239 dst = set_nbits_of_uint16(dst, 1, 1, self.symbol_size as u16)?; 240 241 let num_of_bits = NUM_OF_BITS_OF_SYMBOL_SIZE[self.symbol_size as usize]; 242 // append 14 bit symbol_list 243 for (i, s) in self.symbol_list.iter().enumerate() { 244 let index = num_of_bits * (i as u16) + 2; 245 dst = set_nbits_of_uint16(dst, num_of_bits, index, *s as u16)?; 246 } 247 248 buf.put_u16(dst); 249 250 Ok(PACKET_STATUS_CHUNK_LENGTH) 251 } 252 } 253 254 impl Unmarshal for StatusVectorChunk { 255 /// Unmarshal .. unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,256 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self> 257 where 258 Self: Sized, 259 B: Buf, 260 { 261 let raw_packet_len = raw_packet.remaining(); 262 if raw_packet_len < PACKET_STATUS_CHUNK_LENGTH { 263 return Err(Error::PacketBeforeCname.into()); 264 } 265 266 let type_tcc = StatusChunkTypeTcc::StatusVectorChunk; 267 268 let b0 = raw_packet.get_u8(); 269 let b1 = raw_packet.get_u8(); 270 271 let symbol_size = get_nbits_from_byte(b0, 1, 1).into(); 272 273 let mut symbol_list: Vec<SymbolTypeTcc> = vec![]; 274 match symbol_size { 275 SymbolSizeTypeTcc::OneBit => { 276 for i in 0..6u16 { 277 symbol_list.push(get_nbits_from_byte(b0, 2 + i, 1).into()); 278 } 279 280 for i in 0..8u16 { 281 symbol_list.push(get_nbits_from_byte(b1, i, 1).into()) 282 } 283 } 284 285 SymbolSizeTypeTcc::TwoBit => { 286 for i in 0..3u16 { 287 symbol_list.push(get_nbits_from_byte(b0, 2 + i * 2, 2).into()); 288 } 289 290 for i in 0..4u16 { 291 symbol_list.push(get_nbits_from_byte(b1, i * 2, 2).into()); 292 } 293 } 294 } 295 296 Ok(StatusVectorChunk { 297 type_tcc, 298 symbol_size, 299 symbol_list, 300 }) 301 } 302 } 303 304 /// RecvDelta are represented as multiples of 250us 305 /// small delta is 1 byte: [0,63.75]ms = [0, 63750]us = [0, 255]*250us 306 /// big delta is 2 bytes: [-8192.0, 8191.75]ms = [-8192000, 8191750]us = [-32768, 32767]*250us 307 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1.5 308 #[derive(Debug, Clone, PartialEq, Eq, Default)] 309 pub struct RecvDelta { 310 pub type_tcc_packet: SymbolTypeTcc, 311 /// us 312 pub delta: i64, 313 } 314 315 impl MarshalSize for RecvDelta { marshal_size(&self) -> usize316 fn marshal_size(&self) -> usize { 317 let delta = self.delta / TYPE_TCC_DELTA_SCALE_FACTOR; 318 319 // small delta 320 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta 321 && delta >= 0 322 && delta <= std::u8::MAX as i64 323 { 324 return 1; 325 } 326 327 // big delta 328 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedLargeDelta 329 && delta >= std::i16::MIN as i64 330 && delta <= std::u16::MAX as i64 331 { 332 return 2; 333 } 334 335 0 336 } 337 } 338 339 impl Marshal for RecvDelta { 340 /// Marshal .. marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>341 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> { 342 let delta = self.delta / TYPE_TCC_DELTA_SCALE_FACTOR; 343 344 // small delta 345 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta 346 && delta >= 0 347 && delta <= std::u8::MAX as i64 348 && buf.remaining_mut() >= 1 349 { 350 buf.put_u8(delta as u8); 351 return Ok(1); 352 } 353 354 // big delta 355 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedLargeDelta 356 && delta >= std::i16::MIN as i64 357 && delta <= std::u16::MAX as i64 358 && buf.remaining_mut() >= 2 359 { 360 buf.put_u16(delta as u16); 361 return Ok(2); 362 } 363 364 // overflow 365 Err(Error::DeltaExceedLimit.into()) 366 } 367 } 368 369 impl Unmarshal for RecvDelta { 370 /// Unmarshal .. unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,371 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self> 372 where 373 Self: Sized, 374 B: Buf, 375 { 376 let chunk_len = raw_packet.remaining(); 377 378 // must be 1 or 2 bytes 379 if chunk_len != 1 && chunk_len != 2 { 380 return Err(Error::DeltaExceedLimit.into()); 381 } 382 383 let (type_tcc_packet, delta) = if chunk_len == 1 { 384 ( 385 SymbolTypeTcc::PacketReceivedSmallDelta, 386 TYPE_TCC_DELTA_SCALE_FACTOR * raw_packet.get_u8() as i64, 387 ) 388 } else { 389 ( 390 SymbolTypeTcc::PacketReceivedLargeDelta, 391 TYPE_TCC_DELTA_SCALE_FACTOR * raw_packet.get_i16() as i64, 392 ) 393 }; 394 395 Ok(RecvDelta { 396 type_tcc_packet, 397 delta, 398 }) 399 } 400 } 401 402 /// The offset after header 403 const BASE_SEQUENCE_NUMBER_OFFSET: usize = 8; 404 /// The offset after header 405 const PACKET_STATUS_COUNT_OFFSET: usize = 10; 406 /// The offset after header 407 const REFERENCE_TIME_OFFSET: usize = 12; 408 /// The offset after header 409 const FB_PKT_COUNT_OFFSET: usize = 15; 410 /// The offset after header 411 const PACKET_CHUNK_OFFSET: usize = 16; 412 /// len of packet status chunk 413 const TYPE_TCC_STATUS_VECTOR_CHUNK: usize = 1; 414 415 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#section-3.1.5 416 pub const TYPE_TCC_DELTA_SCALE_FACTOR: i64 = 250; 417 418 // Notice: RFC is wrong: "packet received" (0) and "packet not received" (1) 419 // if S == TYPE_TCCSYMBOL_SIZE_ONE_BIT, symbol list will be: TypeTCCPacketNotReceived TypeTCCPacketReceivedSmallDelta 420 // if S == TYPE_TCCSYMBOL_SIZE_TWO_BIT, symbol list will be same as above: 421 422 static NUM_OF_BITS_OF_SYMBOL_SIZE: [u16; 2] = [1, 2]; 423 424 /// len of packet status chunk 425 const PACKET_STATUS_CHUNK_LENGTH: usize = 2; 426 427 /// TransportLayerCC for sender-BWE 428 /// https://tools.ietf.org/html/draft-holmer-rmcat-transport-wide-cc-extensions-01#page-5 429 #[derive(Debug, Default, PartialEq, Eq, Clone)] 430 pub struct TransportLayerCc { 431 /// SSRC of sender 432 pub sender_ssrc: u32, 433 /// SSRC of the media source 434 pub media_ssrc: u32, 435 /// Transport wide sequence of rtp extension 436 pub base_sequence_number: u16, 437 /// packet_status_count 438 pub packet_status_count: u16, 439 /// reference_time 440 pub reference_time: u32, 441 /// fb_pkt_count 442 pub fb_pkt_count: u8, 443 /// packet_chunks 444 pub packet_chunks: Vec<PacketStatusChunk>, 445 /// recv_deltas 446 pub recv_deltas: Vec<RecvDelta>, 447 } 448 449 impl fmt::Display for TransportLayerCc { fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result450 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { 451 let mut out = String::new(); 452 out += format!("TransportLayerCC:\n\tSender Ssrc {}\n", self.sender_ssrc).as_str(); 453 out += format!("\tMedia Ssrc {}\n", self.media_ssrc).as_str(); 454 out += format!("\tBase Sequence Number {}\n", self.base_sequence_number).as_str(); 455 out += format!("\tStatus Count {}\n", self.packet_status_count).as_str(); 456 out += format!("\tReference Time {}\n", self.reference_time).as_str(); 457 out += format!("\tFeedback Packet Count {}\n", self.fb_pkt_count).as_str(); 458 out += "\tpacket_chunks "; 459 out += "\n\trecv_deltas "; 460 for delta in &self.recv_deltas { 461 out += format!("{delta:?} ").as_str(); 462 } 463 out += "\n"; 464 465 write!(f, "{out}") 466 } 467 } 468 469 impl Packet for TransportLayerCc { header(&self) -> Header470 fn header(&self) -> Header { 471 Header { 472 padding: get_padding_size(self.raw_size()) != 0, 473 count: FORMAT_TCC, 474 packet_type: PacketType::TransportSpecificFeedback, 475 length: ((self.marshal_size() / 4) - 1) as u16, 476 } 477 } 478 479 /// destination_ssrc returns an array of SSRC values that this packet refers to. destination_ssrc(&self) -> Vec<u32>480 fn destination_ssrc(&self) -> Vec<u32> { 481 vec![self.media_ssrc] 482 } 483 raw_size(&self) -> usize484 fn raw_size(&self) -> usize { 485 let mut n = HEADER_LENGTH + PACKET_CHUNK_OFFSET + self.packet_chunks.len() * 2; 486 for d in &self.recv_deltas { 487 // small delta 488 if d.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta { 489 n += 1; 490 } else { 491 n += 2 492 } 493 } 494 n 495 } 496 as_any(&self) -> &(dyn Any + Send + Sync)497 fn as_any(&self) -> &(dyn Any + Send + Sync) { 498 self 499 } 500 equal(&self, other: &(dyn Packet + Send + Sync)) -> bool501 fn equal(&self, other: &(dyn Packet + Send + Sync)) -> bool { 502 other 503 .as_any() 504 .downcast_ref::<TransportLayerCc>() 505 .map_or(false, |a| self == a) 506 } 507 cloned(&self) -> Box<dyn Packet + Send + Sync>508 fn cloned(&self) -> Box<dyn Packet + Send + Sync> { 509 Box::new(self.clone()) 510 } 511 } 512 513 impl MarshalSize for TransportLayerCc { marshal_size(&self) -> usize514 fn marshal_size(&self) -> usize { 515 let l = self.raw_size(); 516 // align to 32-bit boundary 517 l + get_padding_size(l) 518 } 519 } 520 521 impl Marshal for TransportLayerCc { marshal_to(&self, mut buf: &mut [u8]) -> Result<usize>522 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> { 523 if buf.remaining_mut() < self.marshal_size() { 524 return Err(Error::BufferTooShort.into()); 525 } 526 527 let h = self.header(); 528 let n = h.marshal_to(buf)?; 529 buf = &mut buf[n..]; 530 531 buf.put_u32(self.sender_ssrc); 532 buf.put_u32(self.media_ssrc); 533 buf.put_u16(self.base_sequence_number); 534 buf.put_u16(self.packet_status_count); 535 536 let reference_time_and_fb_pkt_count = append_nbits_to_uint32(0, 24, self.reference_time); 537 let reference_time_and_fb_pkt_count = 538 append_nbits_to_uint32(reference_time_and_fb_pkt_count, 8, self.fb_pkt_count as u32); 539 540 buf.put_u32(reference_time_and_fb_pkt_count); 541 542 for chunk in &self.packet_chunks { 543 let n = chunk.marshal_to(buf)?; 544 buf = &mut buf[n..]; 545 } 546 547 for delta in &self.recv_deltas { 548 let n = delta.marshal_to(buf)?; 549 buf = &mut buf[n..]; 550 } 551 552 if h.padding { 553 put_padding(buf, self.raw_size()); 554 } 555 556 Ok(self.marshal_size()) 557 } 558 } 559 560 impl Unmarshal for TransportLayerCc { 561 /// Unmarshal .. unmarshal<B>(raw_packet: &mut B) -> Result<Self> where Self: Sized, B: Buf,562 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self> 563 where 564 Self: Sized, 565 B: Buf, 566 { 567 let raw_packet_len = raw_packet.remaining(); 568 if raw_packet_len < (HEADER_LENGTH + SSRC_LENGTH) { 569 return Err(Error::PacketTooShort.into()); 570 } 571 572 let h = Header::unmarshal(raw_packet)?; 573 574 // https://tools.ietf.org/html/rfc4585#page-33 575 // header's length + payload's length 576 let total_length = 4 * (h.length + 1) as usize; 577 578 if total_length < HEADER_LENGTH + PACKET_CHUNK_OFFSET { 579 return Err(Error::PacketTooShort.into()); 580 } 581 582 if raw_packet_len < total_length { 583 return Err(Error::PacketTooShort.into()); 584 } 585 586 if h.packet_type != PacketType::TransportSpecificFeedback || h.count != FORMAT_TCC { 587 return Err(Error::WrongType.into()); 588 } 589 590 let sender_ssrc = raw_packet.get_u32(); 591 let media_ssrc = raw_packet.get_u32(); 592 let base_sequence_number = raw_packet.get_u16(); 593 let packet_status_count = raw_packet.get_u16(); 594 595 let mut buf = vec![0u8; 3]; 596 buf[0] = raw_packet.get_u8(); 597 buf[1] = raw_packet.get_u8(); 598 buf[2] = raw_packet.get_u8(); 599 let reference_time = get_24bits_from_bytes(&buf); 600 let fb_pkt_count = raw_packet.get_u8(); 601 let mut packet_chunks = vec![]; 602 let mut recv_deltas = vec![]; 603 604 let mut packet_status_pos = HEADER_LENGTH + PACKET_CHUNK_OFFSET; 605 let mut processed_packet_num = 0u16; 606 while processed_packet_num < packet_status_count { 607 if packet_status_pos + PACKET_STATUS_CHUNK_LENGTH >= total_length { 608 return Err(Error::PacketTooShort.into()); 609 } 610 611 let mut chunk_reader = raw_packet.copy_to_bytes(PACKET_STATUS_CHUNK_LENGTH); 612 let b0 = chunk_reader[0]; 613 614 let typ = get_nbits_from_byte(b0, 0, 1); 615 let initial_packet_status: PacketStatusChunk; 616 match typ.into() { 617 StatusChunkTypeTcc::RunLengthChunk => { 618 let packet_status = RunLengthChunk::unmarshal(&mut chunk_reader)?; 619 620 let packet_number_to_process = 621 (packet_status_count - processed_packet_num).min(packet_status.run_length); 622 623 if packet_status.packet_status_symbol == SymbolTypeTcc::PacketReceivedSmallDelta 624 || packet_status.packet_status_symbol 625 == SymbolTypeTcc::PacketReceivedLargeDelta 626 { 627 let mut j = 0u16; 628 629 while j < packet_number_to_process { 630 recv_deltas.push(RecvDelta { 631 type_tcc_packet: packet_status.packet_status_symbol, 632 ..Default::default() 633 }); 634 635 j += 1; 636 } 637 } 638 639 initial_packet_status = PacketStatusChunk::RunLengthChunk(packet_status); 640 processed_packet_num += packet_number_to_process; 641 } 642 643 StatusChunkTypeTcc::StatusVectorChunk => { 644 let packet_status = StatusVectorChunk::unmarshal(&mut chunk_reader)?; 645 646 match packet_status.symbol_size { 647 SymbolSizeTypeTcc::OneBit => { 648 for sym in &packet_status.symbol_list { 649 if *sym == SymbolTypeTcc::PacketReceivedSmallDelta { 650 recv_deltas.push(RecvDelta { 651 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta, 652 ..Default::default() 653 }) 654 } 655 } 656 } 657 658 SymbolSizeTypeTcc::TwoBit => { 659 for sym in &packet_status.symbol_list { 660 if *sym == SymbolTypeTcc::PacketReceivedSmallDelta 661 || *sym == SymbolTypeTcc::PacketReceivedLargeDelta 662 { 663 recv_deltas.push(RecvDelta { 664 type_tcc_packet: *sym, 665 ..Default::default() 666 }) 667 } 668 } 669 } 670 } 671 672 processed_packet_num += packet_status.symbol_list.len() as u16; 673 initial_packet_status = PacketStatusChunk::StatusVectorChunk(packet_status); 674 } 675 } 676 677 packet_status_pos += PACKET_STATUS_CHUNK_LENGTH; 678 packet_chunks.push(initial_packet_status); 679 } 680 681 let mut recv_deltas_pos = packet_status_pos; 682 683 for delta in &mut recv_deltas { 684 if recv_deltas_pos >= total_length { 685 return Err(Error::PacketTooShort.into()); 686 } 687 688 if delta.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta { 689 let mut delta_reader = raw_packet.take(1); 690 *delta = RecvDelta::unmarshal(&mut delta_reader)?; 691 recv_deltas_pos += 1; 692 } 693 694 if delta.type_tcc_packet == SymbolTypeTcc::PacketReceivedLargeDelta { 695 let mut delta_reader = raw_packet.take(2); 696 *delta = RecvDelta::unmarshal(&mut delta_reader)?; 697 recv_deltas_pos += 2; 698 } 699 } 700 701 if 702 /*h.padding &&*/ 703 raw_packet.has_remaining() { 704 raw_packet.advance(raw_packet.remaining()); 705 } 706 707 Ok(TransportLayerCc { 708 sender_ssrc, 709 media_ssrc, 710 base_sequence_number, 711 packet_status_count, 712 reference_time, 713 fb_pkt_count, 714 packet_chunks, 715 recv_deltas, 716 }) 717 } 718 } 719