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