Skip to content
File

Blob: firmware/vendor/str0m/src/rtp/rtcp/bb.rs

rust63 lines
1use super::{FeedbackMessageType, ReportList, RtcpHeader, RtcpPacket, RtcpType, Ssrc};
2 
3/// RTCP packet BY
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct Goodbye {
6 /// The SSRC that are no longer in use.
7 pub reports: ReportList<Ssrc>,
8}
9 
10impl RtcpPacket for Goodbye {
11 fn header(&self) -> RtcpHeader {
12 RtcpHeader {
13 rtcp_type: RtcpType::Goodbye,
14 feedback_message_type: FeedbackMessageType::SourceCount(self.reports.len() as u8),
15 words_less_one: (self.length_words() - 1) as u16,
16 }
17 }
18 
19 fn length_words(&self) -> usize {
20 // each ssrc is one word
21 1 + self.reports.len()
22 }
23 
24 fn write_to(&self, buf: &mut [u8]) -> usize {
25 self.header().write_to(&mut buf[..4]);
26 let buf = &mut buf[4..];
27 for (i, s) in self.reports.iter().enumerate() {
28 buf[i * 4..(i + 1) * 4].copy_from_slice(&s.to_be_bytes());
29 }
30 
31 self.length_words() * 4
32 }
33}
34 
35impl<'a> TryFrom<(usize, &'a [u8])> for Goodbye {
36 type Error = &'static str;
37 
38 fn try_from((count, buf): (usize, &'a [u8])) -> Result<Self, Self::Error> {
39 if buf.len() < 4 {
40 return Err("Less than 4 bytes for Goodbye");
41 }
42 
43 let mut reports = ReportList::new();
44 let mut buf = buf;
45 
46 if buf.len() < count * 4 {
47 return Err("Less than count * 4 bytes for Goodbye");
48 }
49 
50 let max = count.min(31);
51 
52 for _ in 0..max {
53 let ssrc = u32::from_be_bytes([buf[0], buf[1], buf[2], buf[3]]).into();
54 reports.push(ssrc);
55 buf = &buf[4..];
56 }
57 
58 // TODO parse the optional reason string here.
59 
60 Ok(Goodbye { reports })
61 }
62}