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 if len > raw_packet.remaining() {
142 return Err(Error::ErrHeaderSizeInsufficientForExtension);
143 }
144
145 extensions.push(Extension {
146 id: extid,
147 payload: raw_packet.copy_to_bytes(len),
148 });
149 curr_offset += len;
150 }
151 }
152 EXTENSION_PROFILE_TWO_BYTE => {
154 let end = curr_offset + extension_length;
155 while curr_offset < end {
156 let b = raw_packet.get_u8();
157 if b == 0x00 {
158 curr_offset += 1;
160 extensions_padding += 1;
161 continue;
162 }
163
164 let extid = b;
165 curr_offset += 1;
166
167 if curr_offset >= end {
168 return Err(Error::ErrHeaderSizeInsufficientForExtension);
169 }
170
171 let len = raw_packet.get_u8() as usize;
172 curr_offset += 1;
173
174 if len > raw_packet.remaining() {
175 return Err(Error::ErrHeaderSizeInsufficientForExtension);
176 }
177
178 extensions.push(Extension {
179 id: extid,
180 payload: raw_packet.copy_to_bytes(len),
181 });
182 curr_offset += len;
183 }
184 }
185 _ => {
187 if raw_packet_len < curr_offset + extension_length {
188 return Err(Error::ErrHeaderSizeInsufficientForExtension);
189 }
190 extensions.push(Extension {
191 id: 0,
192 payload: raw_packet.copy_to_bytes(extension_length),
193 });
194 }
195 };
196
197 (extension_profile, extensions)
198 } else {
199 (0, vec![])
200 };
201
202 Ok(Header {
203 version,
204 padding,
205 extension,
206 marker,
207 payload_type,
208 sequence_number,
209 timestamp,
210 ssrc,
211 csrc,
212 extension_profile,
213 extensions,
214 extensions_padding,
215 })
216 }
217}
218
219impl MarshalSize for Header {
220 fn marshal_size(&self) -> usize {
222 let mut head_size = 12 + (self.csrc.len() * CSRC_LENGTH);
223 if self.extension {
224 let extension_payload_len = self.get_extension_payload_len() + self.extensions_padding;
225 let extension_payload_size = extension_payload_len.div_ceil(4);
226 head_size += 4 + extension_payload_size * 4;
227 }
228 head_size
229 }
230}
231
232impl Marshal for Header {
233 fn marshal_to(&self, mut buf: &mut [u8]) -> Result<usize> {
235 let remaining_before = buf.remaining_mut();
250 if remaining_before < self.marshal_size() {
251 return Err(Error::ErrBufferTooSmall);
252 }
253
254 let mut b0 = (self.version << VERSION_SHIFT) | self.csrc.len() as u8;
256 if self.padding {
257 b0 |= 1 << PADDING_SHIFT;
258 }
259
260 if self.extension {
261 b0 |= 1 << EXTENSION_SHIFT;
262 }
263 buf.put_u8(b0);
264
265 let mut b1 = self.payload_type;
267 if self.marker {
268 b1 |= 1 << MARKER_SHIFT;
269 }
270 buf.put_u8(b1);
271
272 buf.put_u16(self.sequence_number);
273 buf.put_u32(self.timestamp);
274 buf.put_u32(self.ssrc);
275
276 for csrc in &self.csrc {
277 buf.put_u32(*csrc);
278 }
279
280 if self.extension {
281 buf.put_u16(self.extension_profile);
282
283 let extension_payload_len = self.get_extension_payload_len();
285 if self.extension_profile != EXTENSION_PROFILE_ONE_BYTE
286 && self.extension_profile != EXTENSION_PROFILE_TWO_BYTE
287 && !extension_payload_len.is_multiple_of(4)
288 {
289 return Err(Error::HeaderExtensionPayloadNot32BitWords);
291 }
292 let extension_payload_size = (extension_payload_len as u16).div_ceil(4);
293 buf.put_u16(extension_payload_size);
294
295 match self.extension_profile {
296 EXTENSION_PROFILE_ONE_BYTE => {
298 for extension in &self.extensions {
299 buf.put_u8((extension.id << 4) | (extension.payload.len() as u8 - 1));
300 buf.put(&*extension.payload);
301 }
302 }
303 EXTENSION_PROFILE_TWO_BYTE => {
305 for extension in &self.extensions {
306 buf.put_u8(extension.id);
307 buf.put_u8(extension.payload.len() as u8);
308 buf.put(&*extension.payload);
309 }
310 }
311 _ => {
313 if self.extensions.len() != 1 {
314 return Err(Error::ErrRfc3550headerIdrange);
315 }
316
317 if let Some(extension) = self.extensions.first() {
318 let ext_len = extension.payload.len();
319 if ext_len % 4 != 0 {
320 return Err(Error::HeaderExtensionPayloadNot32BitWords);
321 }
322 buf.put(&*extension.payload);
323 }
324 }
325 };
326
327 for _ in extension_payload_len..extension_payload_size as usize * 4 {
329 buf.put_u8(0);
330 }
331 }
332
333 let remaining_after = buf.remaining_mut();
334 Ok(remaining_before - remaining_after)
335 }
336}
337
338impl Header {
339 pub fn get_extension_payload_len(&self) -> usize {
340 let payload_len: usize = self
341 .extensions
342 .iter()
343 .map(|extension| extension.payload.len())
344 .sum();
345
346 let profile_len = self.extensions.len()
347 * match self.extension_profile {
348 EXTENSION_PROFILE_ONE_BYTE => 1,
349 EXTENSION_PROFILE_TWO_BYTE => 2,
350 _ => 0,
351 };
352
353 payload_len + profile_len
354 }
355
356 pub fn set_extension(&mut self, id: u8, payload: Bytes) -> Result<()> {
358 let payload_len = payload.len() as isize;
359 if self.extension {
360 let extension_profile_len = match self.extension_profile {
361 EXTENSION_PROFILE_ONE_BYTE => {
362 if !(1..=14).contains(&id) {
363 return Err(Error::ErrRfc8285oneByteHeaderIdrange);
364 }
365 if payload_len > 16 {
366 return Err(Error::ErrRfc8285oneByteHeaderSize);
367 }
368 1
369 }
370 EXTENSION_PROFILE_TWO_BYTE => {
371 if id < 1 {
372 return Err(Error::ErrRfc8285twoByteHeaderIdrange);
373 }
374 if payload_len > 255 {
375 return Err(Error::ErrRfc8285twoByteHeaderSize);
376 }
377 2
378 }
379 _ => {
380 if id != 0 {
381 return Err(Error::ErrRfc3550headerIdrange);
382 }
383 0
384 }
385 };
386
387 let delta;
388 if let Some(extension) = self
390 .extensions
391 .iter_mut()
392 .find(|extension| extension.id == id)
393 {
394 delta = payload_len - extension.payload.len() as isize;
395 extension.payload = payload;
396 } else {
397 delta = payload_len + extension_profile_len;
398 self.extensions.push(Extension { id, payload });
399 }
400
401 match delta.cmp(&0) {
402 std::cmp::Ordering::Less => {
403 self.extensions_padding =
404 ((self.extensions_padding as isize - delta) % 4) as usize;
405 }
406 std::cmp::Ordering::Greater => {
407 let extension_padding = (delta % 4) as usize;
408 if self.extensions_padding < extension_padding {
409 self.extensions_padding = (self.extensions_padding + 4) - extension_padding;
410 } else {
411 self.extensions_padding -= extension_padding
412 }
413 }
414 _ => {}
415 }
416 } else {
417 self.extension = true;
419 let mut extension_profile_len = 0;
420 self.extension_profile = match payload_len {
421 0..=16 => {
422 extension_profile_len = 1;
423 EXTENSION_PROFILE_ONE_BYTE
424 }
425 17..=255 => {
426 extension_profile_len = 2;
427 EXTENSION_PROFILE_TWO_BYTE
428 }
429 _ => self.extension_profile,
430 };
431
432 let extension_padding = (payload.len() + extension_profile_len) % 4;
433 if self.extensions_padding < extension_padding {
434 self.extensions_padding = self.extensions_padding + 4 - extension_padding;
435 } else {
436 self.extensions_padding -= extension_padding
437 }
438 self.extensions.push(Extension { id, payload });
439 }
440 Ok(())
441 }
442
443 pub fn get_extension_ids(&self) -> Vec<u8> {
445 if self.extension {
446 self.extensions.iter().map(|e| e.id).collect()
447 } else {
448 vec![]
449 }
450 }
451
452 pub fn get_extension(&self, id: u8) -> Option<Bytes> {
454 if self.extension {
455 self.extensions
456 .iter()
457 .find(|extension| extension.id == id)
458 .map(|extension| extension.payload.clone())
459 } else {
460 None
461 }
462 }
463
464 pub fn del_extension(&mut self, id: u8) -> Result<()> {
466 if self.extension {
467 if let Some(index) = self
468 .extensions
469 .iter()
470 .position(|extension| extension.id == id)
471 {
472 let extension = self.extensions.remove(index);
473
474 let extension_profile_len = match self.extension_profile {
475 EXTENSION_PROFILE_ONE_BYTE => 1,
476 EXTENSION_PROFILE_TWO_BYTE => 2,
477 _ => 0,
478 };
479
480 let extension_padding = (extension.payload.len() + extension_profile_len) % 4;
481 self.extensions_padding = (self.extensions_padding + extension_padding) % 4;
482
483 Ok(())
484 } else {
485 Err(Error::ErrHeaderExtensionNotFound)
486 }
487 } else {
488 Err(Error::ErrHeaderExtensionsNotEnabled)
489 }
490 }
491}