1use shared::{
2 error::{Error, Result},
3 marshal::{Marshal, MarshalSize, Unmarshal},
4};
5
6use bytes::{Buf, BufMut, Bytes};
7
8pub const HEADER_LENGTH: usize = 4;
9pub const VERSION_SHIFT: u8 = 6;
10pub const VERSION_MASK: u8 = 0x3;
11pub const PADDING_SHIFT: u8 = 5;
12pub const PADDING_MASK: u8 = 0x1;
13pub const EXTENSION_SHIFT: u8 = 4;
14pub const EXTENSION_MASK: u8 = 0x1;
15pub const EXTENSION_PROFILE_ONE_BYTE: u16 = 0xBEDE;
16pub const EXTENSION_PROFILE_TWO_BYTE: u16 = 0x1000;
17pub const EXTENSION_ID_RESERVED: u8 = 0xF;
18pub const CC_MASK: u8 = 0xF;
19pub const MARKER_SHIFT: u8 = 7;
20pub const MARKER_MASK: u8 = 0x1;
21pub const PT_MASK: u8 = 0x7F;
22pub const SEQ_NUM_OFFSET: usize = 2;
23pub const SEQ_NUM_LENGTH: usize = 2;
24pub const TIMESTAMP_OFFSET: usize = 4;
25pub const TIMESTAMP_LENGTH: usize = 4;
26pub const SSRC_OFFSET: usize = 8;
27pub const SSRC_LENGTH: usize = 4;
28pub const CSRC_OFFSET: usize = 12;
29pub const CSRC_LENGTH: usize = 4;
30
31#[derive(Debug, Eq, PartialEq, Default, Clone)]
32pub struct Extension {
33 pub id: u8,
34 pub payload: Bytes,
35}
36
37#[derive(Debug, Eq, PartialEq, Default, Clone)]
40pub struct Header {
41 pub version: u8,
42 pub padding: bool,
43 pub extension: bool,
44 pub marker: bool,
45 pub payload_type: u8,
46 pub sequence_number: u16,
47 pub timestamp: u32,
48 pub ssrc: u32,
49 pub csrc: Vec<u32>,
50 pub extension_profile: u16,
51 pub extensions: Vec<Extension>,
52 pub extensions_padding: usize,
53}
54
55impl Unmarshal for Header {
56 fn unmarshal<B>(raw_packet: &mut B) -> Result<Self>
58 where
59 Self: Sized,
60 B: Buf,
61 {
62 let raw_packet_len = raw_packet.remaining();
63 if raw_packet_len < HEADER_LENGTH {
64 return Err(Error::ErrHeaderSizeInsufficient);
65 }
66 let b0 = raw_packet.get_u8();
81 let version = b0 >> VERSION_SHIFT & VERSION_MASK;
82 let padding = (b0 >> PADDING_SHIFT & PADDING_MASK) > 0;
83 let extension = (b0 >> EXTENSION_SHIFT & EXTENSION_MASK) > 0;
84 let cc = (b0 & CC_MASK) as usize;
85
86 let mut curr_offset = CSRC_OFFSET + (cc * CSRC_LENGTH);
87 if raw_packet_len < curr_offset {
88 return Err(Error::ErrHeaderSizeInsufficient);
89 }
90
91 let b1 = raw_packet.get_u8();
92 let marker = (b1 >> MARKER_SHIFT & MARKER_MASK) > 0;
93 let payload_type = b1 & PT_MASK;
94
95 let sequence_number = raw_packet.get_u16();
96 let timestamp = raw_packet.get_u32();
97 let ssrc = raw_packet.get_u32();
98
99 let mut csrc = Vec::with_capacity(cc);
100 for _ in 0..cc {
101 csrc.push(raw_packet.get_u32());
102 }
103 let mut extensions_padding: usize = 0;
104 let (extension_profile, extensions) = if extension {
105 let expected = curr_offset + 4;
106 if raw_packet_len < expected {
107 return Err(Error::ErrHeaderSizeInsufficientForExtension);
108 }
109 let extension_profile = raw_packet.get_u16();
110 curr_offset += 2;
111 let extension_length = raw_packet.get_u16() as usize * 4;
112 curr_offset += 2;
113
114 let expected = curr_offset + extension_length;
115 if raw_packet_len < expected {
116 return Err(Error::ErrHeaderSizeInsufficientForExtension);
117 }
118
119 let mut extensions = vec![];
120 match extension_profile {
121 EXTENSION_PROFILE_ONE_BYTE => {
123 let end = curr_offset + extension_length;
124 while curr_offset < end {
125 let b = raw_packet.get_u8();
126 if b == 0x00 {
127 curr_offset += 1;
129 extensions_padding += 1;
130 continue;
131 }
132
133 let extid = b >> 4;
134 let len = ((b & (0xFF ^ 0xF0)) + 1) as usize;
135 curr_offset += 1;
136
137 if extid == EXTENSION_ID_RESERVED {
138 break;
139 }
140
141 extensions.push(Extension {
142 id: extid,
143 payload: raw_packet.copy_to_bytes(len),
144 });
145 curr_offset += len;
146 }
147 }
148 EXTENSION_PROFILE_TWO_BYTE => {
150 let end = curr_offset + extension_length;
151 while curr_offset < end {
152 let b = raw_packet.get_u8();
153 if b == 0x00 {
154 curr_offset += 1;
156 extensions_padding += 1;
157 continue;
158 }
159
160 let extid = b;
161 curr_offset += 1;
162
163 let len = raw_packet.get_u8() as usize;
164 curr_offset += 1;
165
166 extensions.push(Extension {
167 id: extid,
168 payload: raw_packet.copy_to_bytes(len),
169 });
170 curr_offset += len;
171 }
172 }
173 _ => {
175 if raw_packet_len < curr_offset + extension_length {
176 return Err(Error::ErrHeaderSizeInsufficientForExtension);
177 }
178 extensions.push(Extension {
179 id: 0,
180 payload: raw_packet.copy_to_bytes(extension_length),
181 });
182 }
183 };
184
185 (extension_profile, extensions)
186 } else {
187 (0, vec![])
188 };
189
190 Ok(Header {
191 version,
192 padding,
193 extension,
194 marker,
195 payload_type,
196 sequence_number,
197 timestamp,
198 ssrc,
199 csrc,
200 extension_profile,
201 extensions,
202 extensions_padding,
203 })
204 }
205}
206
207impl MarshalSize for Header {
208 fn marshal_size(&self) -> usize {
210 let mut head_size = 12 + (self.csrc.len() * CSRC_LENGTH);
211 if self.extension {
212 let extension_payload_len = self.get_extension_payload_len() + self.extensions_padding;
213 let extension_payload_size = extension_payload_len.div_ceil(4);
214 head_size += 4 + extension_payload_size * 4;
215 }
216 head_size
217 }
218}
219
220impl Marshal for Header {
221 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
223 let remaining_before = buf.remaining_mut();
238 if remaining_before < self.marshal_size() {
239 return Err(Error::ErrBufferTooSmall);
240 }
241
242 let mut b0 = (self.version << VERSION_SHIFT) | self.csrc.len() as u8;
244 if self.padding {
245 b0 |= 1 << PADDING_SHIFT;
246 }
247
248 if self.extension {
249 b0 |= 1 << EXTENSION_SHIFT;
250 }
251 buf.put_u8(b0);
252
253 let mut b1 = self.payload_type;
255 if self.marker {
256 b1 |= 1 << MARKER_SHIFT;
257 }
258 buf.put_u8(b1);
259
260 buf.put_u16(self.sequence_number);
261 buf.put_u32(self.timestamp);
262 buf.put_u32(self.ssrc);
263
264 for csrc in &self.csrc {
265 buf.put_u32(*csrc);
266 }
267
268 if self.extension {
269 buf.put_u16(self.extension_profile);
270
271 let extension_payload_len = self.get_extension_payload_len();
273 if self.extension_profile != EXTENSION_PROFILE_ONE_BYTE
274 && self.extension_profile != EXTENSION_PROFILE_TWO_BYTE
275 && !extension_payload_len.is_multiple_of(4)
276 {
277 return Err(Error::HeaderExtensionPayloadNot32BitWords);
279 }
280 let extension_payload_size = (extension_payload_len as u16).div_ceil(4);
281 buf.put_u16(extension_payload_size);
282
283 match self.extension_profile {
284 EXTENSION_PROFILE_ONE_BYTE => {
286 for extension in &self.extensions {
287 buf.put_u8((extension.id << 4) | (extension.payload.len() as u8 - 1));
288 buf.put(&*extension.payload);
289 }
290 }
291 EXTENSION_PROFILE_TWO_BYTE => {
293 for extension in &self.extensions {
294 buf.put_u8(extension.id);
295 buf.put_u8(extension.payload.len() as u8);
296 buf.put(&*extension.payload);
297 }
298 }
299 _ => {
301 if self.extensions.len() != 1 {
302 return Err(Error::ErrRfc3550headerIdrange);
303 }
304
305 if let Some(extension) = self.extensions.first() {
306 let ext_len = extension.payload.len();
307 if ext_len % 4 != 0 {
308 return Err(Error::HeaderExtensionPayloadNot32BitWords);
309 }
310 buf.put(&*extension.payload);
311 }
312 }
313 };
314
315 for _ in extension_payload_len..extension_payload_size as usize * 4 {
317 buf.put_u8(0);
318 }
319 }
320
321 let remaining_after = buf.remaining_mut();
322 Ok(remaining_before - remaining_after)
323 }
324}
325
326impl Header {
327 pub fn get_extension_payload_len(&self) -> usize {
328 let payload_len: usize = self
329 .extensions
330 .iter()
331 .map(|extension| extension.payload.len())
332 .sum();
333
334 let profile_len = self.extensions.len()
335 * match self.extension_profile {
336 EXTENSION_PROFILE_ONE_BYTE => 1,
337 EXTENSION_PROFILE_TWO_BYTE => 2,
338 _ => 0,
339 };
340
341 payload_len + profile_len
342 }
343
344 pub fn set_extension(&mut self, id: u8, payload: Bytes) -> Result<()> {
346 let payload_len = payload.len() as isize;
347 if self.extension {
348 let extension_profile_len = match self.extension_profile {
349 EXTENSION_PROFILE_ONE_BYTE => {
350 if !(1..=14).contains(&id) {
351 return Err(Error::ErrRfc8285oneByteHeaderIdrange);
352 }
353 if payload_len > 16 {
354 return Err(Error::ErrRfc8285oneByteHeaderSize);
355 }
356 1
357 }
358 EXTENSION_PROFILE_TWO_BYTE => {
359 if id < 1 {
360 return Err(Error::ErrRfc8285twoByteHeaderIdrange);
361 }
362 if payload_len > 255 {
363 return Err(Error::ErrRfc8285twoByteHeaderSize);
364 }
365 2
366 }
367 _ => {
368 if id != 0 {
369 return Err(Error::ErrRfc3550headerIdrange);
370 }
371 0
372 }
373 };
374
375 let delta;
376 if let Some(extension) = self
378 .extensions
379 .iter_mut()
380 .find(|extension| extension.id == id)
381 {
382 delta = payload_len - extension.payload.len() as isize;
383 extension.payload = payload;
384 } else {
385 delta = payload_len + extension_profile_len;
386 self.extensions.push(Extension { id, payload });
387 }
388
389 match delta.cmp(&0) {
390 std::cmp::Ordering::Less => {
391 self.extensions_padding =
392 ((self.extensions_padding as isize - delta) % 4) as usize;
393 }
394 std::cmp::Ordering::Greater => {
395 let extension_padding = (delta % 4) as usize;
396 if self.extensions_padding < extension_padding {
397 self.extensions_padding = (self.extensions_padding + 4) - extension_padding;
398 } else {
399 self.extensions_padding -= extension_padding
400 }
401 }
402 _ => {}
403 }
404 } else {
405 self.extension = true;
407 let mut extension_profile_len = 0;
408 self.extension_profile = match payload_len {
409 0..=16 => {
410 extension_profile_len = 1;
411 EXTENSION_PROFILE_ONE_BYTE
412 }
413 17..=255 => {
414 extension_profile_len = 2;
415 EXTENSION_PROFILE_TWO_BYTE
416 }
417 _ => self.extension_profile,
418 };
419
420 let extension_padding = (payload.len() + extension_profile_len) % 4;
421 if self.extensions_padding < extension_padding {
422 self.extensions_padding = self.extensions_padding + 4 - extension_padding;
423 } else {
424 self.extensions_padding -= extension_padding
425 }
426 self.extensions.push(Extension { id, payload });
427 }
428 Ok(())
429 }
430
431 pub fn get_extension_ids(&self) -> Vec<u8> {
433 if self.extension {
434 self.extensions.iter().map(|e| e.id).collect()
435 } else {
436 vec![]
437 }
438 }
439
440 pub fn get_extension(&self, id: u8) -> Option<Bytes> {
442 if self.extension {
443 self.extensions
444 .iter()
445 .find(|extension| extension.id == id)
446 .map(|extension| extension.payload.clone())
447 } else {
448 None
449 }
450 }
451
452 pub fn del_extension(&mut self, id: u8) -> Result<()> {
454 if self.extension {
455 if let Some(index) = self
456 .extensions
457 .iter()
458 .position(|extension| extension.id == id)
459 {
460 let extension = self.extensions.remove(index);
461
462 let extension_profile_len = match self.extension_profile {
463 EXTENSION_PROFILE_ONE_BYTE => 1,
464 EXTENSION_PROFILE_TWO_BYTE => 2,
465 _ => 0,
466 };
467
468 let extension_padding = (extension.payload.len() + extension_profile_len) % 4;
469 self.extensions_padding = (self.extensions_padding + extension_padding) % 4;
470
471 Ok(())
472 } else {
473 Err(Error::ErrHeaderExtensionNotFound)
474 }
475 } else {
476 Err(Error::ErrHeaderExtensionsNotEnabled)
477 }
478 }
479}