1#[cfg(test)]
10mod transport_layer_cc_test;
11
12use crate::{header::*, packet::*, util::*};
13use shared::{
14 error::{Error, Result},
15 marshal::{Marshal, MarshalSize, Unmarshal},
16};
17
18use bytes::{Buf, BufMut};
19use std::any::Any;
20use std::fmt;
21
22#[derive(Default, PartialEq, Eq, Debug, Clone)]
57#[repr(u16)]
58pub enum StatusChunkTypeTcc {
59 #[default]
60 RunLengthChunk = 0,
62 StatusVectorChunk = 1,
64}
65
66#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
68#[repr(u16)]
69pub enum SymbolTypeTcc {
70 #[default]
72 PacketNotReceived = 0,
73 PacketReceivedSmallDelta = 1,
75 PacketReceivedLargeDelta = 2,
77 PacketReceivedWithoutDelta = 3,
80}
81
82#[derive(Default, PartialEq, Eq, Debug, Copy, Clone)]
84#[repr(u16)]
85pub enum SymbolSizeTypeTcc {
86 #[default]
88 OneBit = 0,
89 TwoBit = 1,
91}
92
93impl From<u16> for SymbolSizeTypeTcc {
94 fn from(val: u16) -> Self {
95 match val {
96 0 => SymbolSizeTypeTcc::OneBit,
97 _ => SymbolSizeTypeTcc::TwoBit,
98 }
99 }
100}
101
102impl From<u16> for StatusChunkTypeTcc {
103 fn from(val: u16) -> Self {
104 match val {
105 0 => StatusChunkTypeTcc::RunLengthChunk,
106 _ => StatusChunkTypeTcc::StatusVectorChunk,
107 }
108 }
109}
110
111impl From<u16> for SymbolTypeTcc {
112 fn from(val: u16) -> Self {
113 match val {
114 0 => SymbolTypeTcc::PacketNotReceived,
115 1 => SymbolTypeTcc::PacketReceivedSmallDelta,
116 2 => SymbolTypeTcc::PacketReceivedLargeDelta,
117 _ => SymbolTypeTcc::PacketReceivedWithoutDelta,
118 }
119 }
120}
121
122#[derive(Debug, Clone, PartialEq, Eq)]
125pub enum PacketStatusChunk {
126 RunLengthChunk(RunLengthChunk),
128 StatusVectorChunk(StatusVectorChunk),
130}
131
132impl MarshalSize for PacketStatusChunk {
133 fn marshal_size(&self) -> usize {
134 match self {
135 PacketStatusChunk::RunLengthChunk(c) => c.marshal_size(),
136 PacketStatusChunk::StatusVectorChunk(c) => c.marshal_size(),
137 }
138 }
139}
140
141impl Marshal for PacketStatusChunk {
142 fn marshal_to(&self, buf: &mut [u8]) -> Result<usize> {
144 match self {
145 PacketStatusChunk::RunLengthChunk(c) => c.marshal_to(buf),
146 PacketStatusChunk::StatusVectorChunk(c) => c.marshal_to(buf),
147 }
148 }
149}
150
151#[derive(Debug, Clone, PartialEq, Eq, Default)]
158pub struct RunLengthChunk {
159 pub type_tcc: StatusChunkTypeTcc,
161 pub packet_status_symbol: SymbolTypeTcc,
164 pub run_length: u16,
166}
167
168impl MarshalSize for RunLengthChunk {
169 fn marshal_size(&self) -> usize {
170 PACKET_STATUS_CHUNK_LENGTH
171 }
172}
173
174impl Marshal for RunLengthChunk {
175 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
177 let mut dst = set_nbits_of_uint16(0, 1, 0, 0)?;
179
180 dst = set_nbits_of_uint16(dst, 2, 1, self.packet_status_symbol as u16)?;
182
183 dst = set_nbits_of_uint16(dst, 13, 3, self.run_length)?;
185
186 buf.put_u16(dst);
187
188 Ok(PACKET_STATUS_CHUNK_LENGTH)
189 }
190}
191
192impl Unmarshal for RunLengthChunk {
193 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
195 where
196 Self: Sized,
197 B: Buf,
198 {
199 let raw_packet_len = raw_packet.remaining();
200 if raw_packet_len < PACKET_STATUS_CHUNK_LENGTH {
201 return Err(Error::PacketStatusChunkLength);
202 }
203
204 let type_tcc = StatusChunkTypeTcc::RunLengthChunk;
206
207 let b0 = raw_packet.get_u8();
208 let b1 = raw_packet.get_u8();
209
210 let packet_status_symbol = get_nbits_from_byte(b0, 1, 2).into();
212
213 let run_length = ((get_nbits_from_byte(b0, 3, 5) as usize) << 8) as u16 + (b1 as u16);
215
216 Ok(RunLengthChunk {
217 type_tcc,
218 packet_status_symbol,
219 run_length,
220 })
221 }
222}
223
224#[derive(Debug, Clone, PartialEq, Eq, Default)]
231pub struct StatusVectorChunk {
232 pub type_tcc: StatusChunkTypeTcc,
234
235 pub symbol_size: SymbolSizeTypeTcc,
237
238 pub symbol_list: Vec<SymbolTypeTcc>,
243}
244
245impl MarshalSize for StatusVectorChunk {
246 fn marshal_size(&self) -> usize {
247 PACKET_STATUS_CHUNK_LENGTH
248 }
249}
250
251impl Marshal for StatusVectorChunk {
252 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
254 let mut dst = set_nbits_of_uint16(0, 1, 0, 1)?;
256
257 dst = set_nbits_of_uint16(dst, 1, 1, self.symbol_size as u16)?;
259
260 let num_of_bits = NUM_OF_BITS_OF_SYMBOL_SIZE[self.symbol_size as usize];
261 for (i, s) in self.symbol_list.iter().enumerate() {
263 let index = num_of_bits * (i as u16) + 2;
264 dst = set_nbits_of_uint16(dst, num_of_bits, index, *s as u16)?;
265 }
266
267 buf.put_u16(dst);
268
269 Ok(PACKET_STATUS_CHUNK_LENGTH)
270 }
271}
272
273impl Unmarshal for StatusVectorChunk {
274 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
276 where
277 Self: Sized,
278 B: Buf,
279 {
280 let raw_packet_len = raw_packet.remaining();
281 if raw_packet_len < PACKET_STATUS_CHUNK_LENGTH {
282 return Err(Error::PacketBeforeCname);
283 }
284
285 let type_tcc = StatusChunkTypeTcc::StatusVectorChunk;
286
287 let b0 = raw_packet.get_u8();
288 let b1 = raw_packet.get_u8();
289
290 let symbol_size = get_nbits_from_byte(b0, 1, 1).into();
291
292 let mut symbol_list: Vec<SymbolTypeTcc> = vec![];
293 match symbol_size {
294 SymbolSizeTypeTcc::OneBit => {
295 for i in 0..6u16 {
296 symbol_list.push(get_nbits_from_byte(b0, 2 + i, 1).into());
297 }
298
299 for i in 0..8u16 {
300 symbol_list.push(get_nbits_from_byte(b1, i, 1).into())
301 }
302 }
303
304 SymbolSizeTypeTcc::TwoBit => {
305 for i in 0..3u16 {
306 symbol_list.push(get_nbits_from_byte(b0, 2 + i * 2, 2).into());
307 }
308
309 for i in 0..4u16 {
310 symbol_list.push(get_nbits_from_byte(b1, i * 2, 2).into());
311 }
312 }
313 }
314
315 Ok(StatusVectorChunk {
316 type_tcc,
317 symbol_size,
318 symbol_list,
319 })
320 }
321}
322
323#[derive(Debug, Clone, PartialEq, Eq, Default)]
328pub struct RecvDelta {
329 pub type_tcc_packet: SymbolTypeTcc,
331 pub delta: i64,
333}
334
335impl MarshalSize for RecvDelta {
336 fn marshal_size(&self) -> usize {
337 let delta = self.delta / TYPE_TCC_DELTA_SCALE_FACTOR;
338
339 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta
341 && delta >= 0
342 && delta <= u8::MAX as i64
343 {
344 return 1;
345 }
346
347 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedLargeDelta
349 && delta >= i16::MIN as i64
350 && delta <= i16::MAX as i64
351 {
352 return 2;
353 }
354
355 0
356 }
357}
358
359impl Marshal for RecvDelta {
360 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
362 let delta = self.delta / TYPE_TCC_DELTA_SCALE_FACTOR;
363
364 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta
366 && delta >= 0
367 && delta <= u8::MAX as i64
368 && buf.remaining_mut() >= 1
369 {
370 buf.put_u8(delta as u8);
371 return Ok(1);
372 }
373
374 if self.type_tcc_packet == SymbolTypeTcc::PacketReceivedLargeDelta
376 && delta >= i16::MIN as i64
377 && delta <= i16::MAX as i64
378 && buf.remaining_mut() >= 2
379 {
380 buf.put_i16(delta as i16);
381 return Ok(2);
382 }
383
384 Err(Error::DeltaExceedLimit)
386 }
387}
388
389impl Unmarshal for RecvDelta {
390 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
392 where
393 Self: Sized,
394 B: Buf,
395 {
396 let chunk_len = raw_packet.remaining();
397
398 if chunk_len != 1 && chunk_len != 2 {
400 return Err(Error::DeltaExceedLimit);
401 }
402
403 let (type_tcc_packet, delta) = if chunk_len == 1 {
404 (
405 SymbolTypeTcc::PacketReceivedSmallDelta,
406 TYPE_TCC_DELTA_SCALE_FACTOR * raw_packet.get_u8() as i64,
407 )
408 } else {
409 (
410 SymbolTypeTcc::PacketReceivedLargeDelta,
411 TYPE_TCC_DELTA_SCALE_FACTOR * raw_packet.get_i16() as i64,
412 )
413 };
414
415 Ok(RecvDelta {
416 type_tcc_packet,
417 delta,
418 })
419 }
420}
421
422const BASE_SEQUENCE_NUMBER_OFFSET: usize = 8;
424const PACKET_STATUS_COUNT_OFFSET: usize = 10;
426const REFERENCE_TIME_OFFSET: usize = 12;
428const FB_PKT_COUNT_OFFSET: usize = 15;
430const PACKET_CHUNK_OFFSET: usize = 16;
432const TYPE_TCC_STATUS_VECTOR_CHUNK: usize = 1;
434
435pub const TYPE_TCC_DELTA_SCALE_FACTOR: i64 = 250;
437
438static NUM_OF_BITS_OF_SYMBOL_SIZE: [u16; 2] = [1, 2];
443
444const PACKET_STATUS_CHUNK_LENGTH: usize = 2;
446
447#[derive(Debug, Default, PartialEq, Eq, Clone)]
450pub struct TransportLayerCc {
451 pub sender_ssrc: u32,
453 pub media_ssrc: u32,
455 pub base_sequence_number: u16,
457 pub packet_status_count: u16,
459 pub reference_time: u32,
461 pub fb_pkt_count: u8,
463 pub packet_chunks: Vec<PacketStatusChunk>,
465 pub recv_deltas: Vec<RecvDelta>,
467}
468
469impl fmt::Display for TransportLayerCc {
470 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
471 let mut out = String::new();
472 out += format!("TransportLayerCC:\n\tSender Ssrc {}\n", self.sender_ssrc).as_str();
473 out += format!("\tMedia Ssrc {}\n", self.media_ssrc).as_str();
474 out += format!("\tBase Sequence Number {}\n", self.base_sequence_number).as_str();
475 out += format!("\tStatus Count {}\n", self.packet_status_count).as_str();
476 out += format!("\tReference Time {}\n", self.reference_time).as_str();
477 out += format!("\tFeedback Packet Count {}\n", self.fb_pkt_count).as_str();
478 out += "\tpacket_chunks ";
479 out += "\n\trecv_deltas ";
480 for delta in &self.recv_deltas {
481 out += format!("{delta:?} ").as_str();
482 }
483 out += "\n";
484
485 write!(f, "{out}")
486 }
487}
488
489impl Packet for TransportLayerCc {
490 fn header(&self) -> Header {
491 Header {
492 padding: get_padding_size(self.raw_size()) != 0,
493 count: FORMAT_TCC,
494 packet_type: PacketType::TransportSpecificFeedback,
495 length: ((self.marshal_size() / 4) - 1) as u16,
496 }
497 }
498
499 fn destination_ssrc(&self) -> Vec<u32> {
501 vec![self.media_ssrc]
502 }
503
504 fn raw_size(&self) -> usize {
505 let mut n = HEADER_LENGTH + PACKET_CHUNK_OFFSET + self.packet_chunks.len() * 2;
506 for d in &self.recv_deltas {
507 if d.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta {
509 n += 1;
510 } else {
511 n += 2
512 }
513 }
514 n
515 }
516
517 fn as_any(&self) -> &dyn Any {
518 self
519 }
520
521 fn equal(&self, other: &dyn Packet) -> bool {
522 other.as_any().downcast_ref::<TransportLayerCc>() == Some(self)
523 }
524
525 fn cloned(&self) -> Box<dyn Packet> {
526 Box::new(self.clone())
527 }
528}
529
530impl MarshalSize for TransportLayerCc {
531 fn marshal_size(&self) -> usize {
532 let l = self.raw_size();
533 l + get_padding_size(l)
535 }
536}
537
538impl Marshal for TransportLayerCc {
539 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
540 if buf.remaining_mut() < self.marshal_size() {
541 return Err(Error::BufferTooShort);
542 }
543
544 let h = self.header();
545 let n = h.marshal_to(buf)?;
546 buf = &mut buf[n..];
547
548 buf.put_u32(self.sender_ssrc);
549 buf.put_u32(self.media_ssrc);
550 buf.put_u16(self.base_sequence_number);
551 buf.put_u16(self.packet_status_count);
552
553 let reference_time_and_fb_pkt_count = append_nbits_to_uint32(0, 24, self.reference_time);
554 let reference_time_and_fb_pkt_count =
555 append_nbits_to_uint32(reference_time_and_fb_pkt_count, 8, self.fb_pkt_count as u32);
556
557 buf.put_u32(reference_time_and_fb_pkt_count);
558
559 for chunk in &self.packet_chunks {
560 let n = chunk.marshal_to(buf)?;
561 buf = &mut buf[n..];
562 }
563
564 for delta in &self.recv_deltas {
565 let n = delta.marshal_to(buf)?;
566 buf = &mut buf[n..];
567 }
568
569 if h.padding {
570 put_padding(buf, self.raw_size());
571 }
572
573 Ok(self.marshal_size())
574 }
575}
576
577impl Unmarshal for TransportLayerCc {
578 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
580 where
581 Self: Sized,
582 B: Buf,
583 {
584 let raw_packet_len = raw_packet.remaining();
585 if raw_packet_len < (HEADER_LENGTH + SSRC_LENGTH) {
586 return Err(Error::PacketTooShort);
587 }
588
589 let h = Header::unmarshal(raw_packet)?;
590
591 let total_length = 4 * (h.length + 1) as usize;
594
595 if total_length < HEADER_LENGTH + PACKET_CHUNK_OFFSET {
596 return Err(Error::PacketTooShort);
597 }
598
599 if raw_packet_len < total_length {
600 return Err(Error::PacketTooShort);
601 }
602
603 if h.packet_type != PacketType::TransportSpecificFeedback || h.count != FORMAT_TCC {
604 return Err(Error::WrongType);
605 }
606
607 let sender_ssrc = raw_packet.get_u32();
608 let media_ssrc = raw_packet.get_u32();
609 let base_sequence_number = raw_packet.get_u16();
610 let packet_status_count = raw_packet.get_u16();
611
612 let mut buf = vec![0u8; 3];
613 buf[0] = raw_packet.get_u8();
614 buf[1] = raw_packet.get_u8();
615 buf[2] = raw_packet.get_u8();
616 let reference_time = get_24bits_from_bytes(&buf);
617 let fb_pkt_count = raw_packet.get_u8();
618 let mut packet_chunks = vec![];
619 let mut recv_deltas = vec![];
620
621 let mut packet_status_pos = HEADER_LENGTH + PACKET_CHUNK_OFFSET;
622 let mut processed_packet_num = 0u16;
623 while processed_packet_num < packet_status_count {
624 if packet_status_pos + PACKET_STATUS_CHUNK_LENGTH >= total_length {
625 return Err(Error::PacketTooShort);
626 }
627
628 let mut chunk_reader = raw_packet.copy_to_bytes(PACKET_STATUS_CHUNK_LENGTH);
629 let b0 = chunk_reader[0];
630
631 let typ = get_nbits_from_byte(b0, 0, 1);
632 let initial_packet_status: PacketStatusChunk;
633 match typ.into() {
634 StatusChunkTypeTcc::RunLengthChunk => {
635 let packet_status = RunLengthChunk::unmarshal(&mut chunk_reader)?;
636 let packet_number_to_process =
637 (packet_status_count - processed_packet_num).min(packet_status.run_length);
638
639 if packet_status.packet_status_symbol == SymbolTypeTcc::PacketReceivedSmallDelta
640 || packet_status.packet_status_symbol
641 == SymbolTypeTcc::PacketReceivedLargeDelta
642 {
643 let mut j = 0u16;
644
645 while j < packet_number_to_process {
646 recv_deltas.push(RecvDelta {
647 type_tcc_packet: packet_status.packet_status_symbol,
648 ..Default::default()
649 });
650
651 j += 1;
652 }
653 }
654
655 initial_packet_status = PacketStatusChunk::RunLengthChunk(packet_status);
656
657 processed_packet_num =
658 processed_packet_num.saturating_add(packet_number_to_process);
659 }
660
661 StatusChunkTypeTcc::StatusVectorChunk => {
662 let packet_status = StatusVectorChunk::unmarshal(&mut chunk_reader)?;
663
664 match packet_status.symbol_size {
665 SymbolSizeTypeTcc::OneBit => {
666 for sym in &packet_status.symbol_list {
667 if *sym == SymbolTypeTcc::PacketReceivedSmallDelta {
668 recv_deltas.push(RecvDelta {
669 type_tcc_packet: SymbolTypeTcc::PacketReceivedSmallDelta,
670 ..Default::default()
671 })
672 }
673 }
674 }
675
676 SymbolSizeTypeTcc::TwoBit => {
677 for sym in &packet_status.symbol_list {
678 if *sym == SymbolTypeTcc::PacketReceivedSmallDelta
679 || *sym == SymbolTypeTcc::PacketReceivedLargeDelta
680 {
681 recv_deltas.push(RecvDelta {
682 type_tcc_packet: *sym,
683 ..Default::default()
684 })
685 }
686 }
687 }
688 }
689
690 processed_packet_num =
691 processed_packet_num.saturating_add(packet_status.symbol_list.len() as u16);
692 initial_packet_status = PacketStatusChunk::StatusVectorChunk(packet_status);
693 }
694 }
695
696 packet_status_pos += PACKET_STATUS_CHUNK_LENGTH;
697 packet_chunks.push(initial_packet_status);
698 }
699
700 let mut recv_deltas_pos = packet_status_pos;
701
702 for delta in &mut recv_deltas {
703 if recv_deltas_pos >= total_length {
704 return Err(Error::PacketTooShort);
705 }
706
707 if delta.type_tcc_packet == SymbolTypeTcc::PacketReceivedSmallDelta {
708 let mut delta_reader = raw_packet.take(1);
709 *delta = RecvDelta::unmarshal(&mut delta_reader)?;
710 recv_deltas_pos += 1;
711 }
712
713 if delta.type_tcc_packet == SymbolTypeTcc::PacketReceivedLargeDelta {
714 let mut delta_reader = raw_packet.take(2);
715 *delta = RecvDelta::unmarshal(&mut delta_reader)?;
716 recv_deltas_pos += 2;
717 }
718 }
719
720 if
721 raw_packet.has_remaining() {
723 raw_packet.advance(raw_packet.remaining());
724 }
725
726 Ok(TransportLayerCc {
727 sender_ssrc,
728 media_ssrc,
729 base_sequence_number,
730 packet_status_count,
731 reference_time,
732 fb_pkt_count,
733 packet_chunks,
734 recv_deltas,
735 })
736 }
737}