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