1use crate::rtp::*;
2use crate::rtp_header_extension::*;
3
4extern crate nom;
5use nom::bits::bits;
6use nom::bits::complete::take as bits_take;
7use nom::bytes::complete::take as bytes_take;
8use nom::combinator::rest;
9use nom::error::make_error;
10use nom::error::ErrorKind;
11use nom::multi::count;
12use nom::number::complete::{be_u16, be_u32};
13use nom::sequence::tuple;
14use nom::Err;
15use nom::IResult;
16
17pub fn parse_rtp_packet(input: &[u8]) -> IResult<&[u8], RtpPacket> {
19 let (
20 input,
21 (
22 (version, padding, extension, csrc_count),
23 (marker, payload_type),
24 sequence_number,
25 timestamp,
26 ssrc,
27 ),
28 ) = tuple((parse_vpxcc, parse_mpt, be_u16, be_u32, be_u32))(input)?;
29
30 let (input, csrc) = parse_csrc(input, csrc_count as usize)?;
31 let (input, header_extension) = parse_header_extension(input, extension)?;
32 let (input, (payload, padding_bytes)) = parse_payload(input, padding)?;
33
34 Ok((
35 input,
36 RtpPacket {
37 version,
38 padding,
39 extension,
40 csrc_count,
41 marker,
42 payload_type,
43 sequence_number,
44 timestamp,
45 ssrc,
46 csrc,
47 header_extension,
48 payload,
49 padding_bytes,
50 },
51 ))
52}
53
54fn parse_vpxcc(input: &[u8]) -> IResult<&[u8], (u8, u8, u8, u8)> {
55 bits(tuple((
56 bits_take::<_, _, _, (_, _)>(2usize),
57 bits_take::<_, _, _, (_, _)>(1usize),
58 bits_take::<_, _, _, (_, _)>(1usize),
59 bits_take::<_, _, _, (_, _)>(4usize),
60 )))(input)
61}
62
63fn parse_mpt(input: &[u8]) -> IResult<&[u8], (u8, u8)> {
64 bits(tuple((
65 bits_take::<_, _, _, (_, _)>(1usize),
66 bits_take::<_, _, _, (_, _)>(7usize),
67 )))(input)
68}
69
70fn parse_csrc(input: &[u8], csrc_count: usize) -> IResult<&[u8], Vec<u32>> {
71 count(be_u32, csrc_count)(input)
72}
73
74fn parse_header_extension(
75 input: &[u8],
76 extension: u8,
77) -> IResult<&[u8], Option<RtpPacketHeaderExtension>> {
78 if extension == 0 {
79 Ok((input, None))
80 } else {
81 let (input, (profile, length)) = tuple((be_u16, be_u16))(input)?;
82 let (input, data) = bytes_take(length * 4)(input)?;
83
84 Ok((
85 input,
86 Some(RtpPacketHeaderExtension {
87 profile,
88 length,
89 data,
90 }),
91 ))
92 }
93}
94
95fn parse_payload_no_padding(input: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
96 let (input, payload) = rest::<_, (_, _)>(input)?;
97 Ok((input, (payload, &[])))
98}
99
100fn parse_payload_padding(input: &[u8]) -> IResult<&[u8], (&[u8], &[u8])> {
101 let num_padding_bytes = input.last().map(|i| *i as usize).unwrap_or(usize::MAX);
102
103 if num_padding_bytes <= input.len() {
104 tuple((
105 bytes_take(input.len() - num_padding_bytes),
106 bytes_take(num_padding_bytes),
107 ))(input)
108 } else {
109 Err(Err::Error(make_error(input, ErrorKind::Eof)))
110 }
111}
112
113fn parse_payload(input: &[u8], padding: u8) -> IResult<&[u8], (&[u8], &[u8])> {
114 if padding == 0x00 {
115 parse_payload_no_padding(input)
116 } else {
117 parse_payload_padding(input)
118 }
119}
120
121#[cfg(test)]
122mod tests {
123 use super::*;
124
125 fn parse_vpxcc_helper(value: u8) -> (u8, u8, u8, u8) {
127 let input: [u8; 1] = [value];
128 let result = parse_vpxcc(&input);
129
130 assert!(result.is_ok());
132
133 let data = result.ok().unwrap();
135 assert_eq!(data.0.len(), 0);
136 return data.1;
137 }
138
139 #[test]
140 fn parse_vpxcc_all_one() {
141 assert_eq!(parse_vpxcc_helper(0xFF), (0x03, 0x01, 0x01, 0x0F));
142 }
143
144 #[test]
145 fn parse_vpxcc_all_zero() {
146 assert_eq!(parse_vpxcc_helper(0x00), (0x00, 0x00, 0x00, 0x00));
147 }
148
149 #[test]
150 fn parse_vpxcc_mixed() {
151 assert_eq!(parse_vpxcc_helper(0xA5), (0x02, 0x01, 0x00, 0x05));
152 }
153
154 #[test]
155 fn parse_vpxcc_missing_data() {
156 let input: [u8; 0] = [];
157 let result = parse_vpxcc(&input);
158
159 assert!(result.is_err());
160 }
161
162 fn parse_mpt_helper(value: u8) -> (u8, u8) {
163 let input: [u8; 1] = [value];
164 let result = parse_mpt(&input);
165
166 assert!(result.is_ok());
168
169 let data = result.ok().unwrap();
171 assert_eq!(data.0.len(), 0);
172 return data.1;
173 }
174
175 #[test]
176 fn parse_mpt_all_zero() {
177 assert_eq!(parse_mpt_helper(0x00), (0x00, 0x00));
178 }
179
180 #[test]
181 fn parse_mpt_all_one() {
182 assert_eq!(parse_mpt_helper(0xFF), (0x01, 0x7F));
183 }
184
185 #[test]
186 fn parse_mpt_mixed() {
187 assert_eq!(parse_mpt_helper(0xA5), (0x01, 0x25));
188 }
189
190 #[test]
191 fn parse_mpt_missing_data() {
192 let input: [u8; 0] = [];
193 let result = parse_mpt(&input);
194
195 assert!(result.is_err());
196 }
197
198 #[test]
199 fn parse_csrc_empty() {
200 let input: [u8; 0] = [];
201 let result = parse_csrc(&input, 0);
202
203 assert!(result.is_ok());
204 assert_eq!(result.ok().unwrap().1.len(), 0);
205 }
206
207 #[test]
208 fn parse_csrc_non_empty() {
209 let input: [u8; 9] = [0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xA5];
210
211 let result = parse_csrc(&input, 2);
212 assert!(result.is_ok());
213
214 let data = result.ok().unwrap();
215
216 assert_eq!(data.0.len(), 1);
218
219 assert_eq!(data.1, vec!(0x12345678, 0x90ABCDEF));
221 }
222
223 #[test]
224 fn parse_csrc_not_enough_data() {
225 let input: [u8; 0] = [];
226 let result = parse_csrc(&input, 2);
227 assert!(result.is_err());
228 }
229
230 #[test]
231 fn parse_header_extension_empty_valid() {
232 let input: [u8; 0] = [];
233 let result = parse_header_extension(&input, 0);
234 assert!(result.is_ok());
235
236 let data = result.ok().unwrap();
237 assert!(data.1.is_none());
238 }
239
240 #[test]
241 fn parse_header_extension_empty_invalid() {
242 let input: [u8; 0] = [];
243 let result = parse_header_extension(&input, 1);
244 assert!(result.is_err());
245 }
246
247 #[test]
248 fn parse_header_extension_non_empty() {
249 let input: [u8; 8] = [0x12, 0x34, 0x00, 0x01, 0x56, 0x78, 0x90, 0xAB];
250 let result = parse_header_extension(&input, 1);
251 assert!(result.is_ok());
252
253 let data = result.ok().unwrap();
254 assert_eq!(data.0.len(), 0);
255 assert!(data.1.is_some());
256
257 let header_extension = data.1.unwrap();
258 assert_eq!(header_extension.profile, 0x1234);
259 assert_eq!(header_extension.length, 0x0001);
260 assert_eq!(header_extension.data, [0x56, 0x78, 0x90, 0xAB]);
261 }
262
263 #[test]
264 fn parse_payload_no_padding() {
265 let input: [u8; 1] = [0x12];
266 let result = parse_payload(&input, 0);
267 assert!(result.is_ok());
268 let data = result.ok().unwrap();
269 assert_eq!(data.0.len(), 0);
270
271 let (payload, padding_bytes) = data.1;
272 assert_eq!(payload, [0x12]);
273 assert_eq!(padding_bytes, []);
274 }
275
276 #[test]
277 fn parse_payload_padding_valid() {
278 let input: [u8; 4] = [0x12, 0x00, 0x00, 0x03];
279 let result = parse_payload(&input, 1);
280 assert!(result.is_ok());
281 let data = result.ok().unwrap();
282 assert_eq!(data.0.len(), 0);
283
284 let (payload, padding_bytes) = data.1;
285 assert_eq!(payload, [0x12]);
286 assert_eq!(padding_bytes, [0x00, 0x00, 0x03]);
287 }
288
289 #[test]
290 fn parse_payload_padding_valid_no_payload() {
291 let input: [u8; 4] = [0x12, 0x00, 0x00, 0x04];
292 let result = parse_payload(&input, 1);
293 assert!(result.is_ok());
294 let data = result.ok().unwrap();
295 assert_eq!(data.0.len(), 0);
296
297 let (payload, padding_bytes) = data.1;
298 assert_eq!(payload, []);
299 assert_eq!(padding_bytes, [0x12, 0x00, 0x00, 0x04]);
300 }
301
302 #[test]
303 fn parse_payload_padding_invalid() {
304 let input: [u8; 4] = [0x12, 0x00, 0x00, 0x05];
306 let result = parse_payload(&input, 1);
307 assert!(result.is_err());
308 }
309
310 #[test]
311 fn parse_payload_padding_empty() {
312 let input: [u8; 0] = [];
313 let result = parse_payload(&input, 1);
314 assert!(result.is_err());
315 }
316
317 #[test]
318 fn parse_rtp_packet_no_csrc_no_header_extension() {
319 let data = vec![
320 0x80, 0x11, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x09,
321 ];
322 let result = parse_rtp_packet(&data);
323
324 assert!(result.is_ok());
325
326 let data = result.ok().unwrap();
327 assert_eq!(data.0.len(), 0);
328
329 let packet = data.1;
330 assert_eq!(packet.version, 0x02);
331 assert_eq!(packet.padding, 0x00);
332 assert_eq!(packet.extension, 0x00);
333 assert_eq!(packet.csrc_count, 0x00);
334 assert_eq!(packet.marker, 0x00);
335 assert_eq!(packet.payload_type, 0x11);
336 assert_eq!(packet.sequence_number, 0x1234);
337 assert_eq!(packet.timestamp, 0x567890AB);
338 assert_eq!(packet.ssrc, 0xCDEFFEDC);
339 assert_eq!(packet.csrc, vec![]);
340 assert!(packet.header_extension.is_none());
341 assert_eq!(packet.payload, [0xBA, 0x09]);
342 assert_eq!(packet.padding_bytes, []);
343 }
344
345 #[test]
346 fn parse_rtp_packet_csrc() {
347 let data = vec![
348 0x81, 0x11, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x09,
349 0x87, 0x65, 0x43,
350 ];
351 let result = parse_rtp_packet(&data);
352
353 assert!(result.is_ok());
354
355 let data = result.ok().unwrap();
356 assert_eq!(data.0.len(), 0);
357
358 let packet = data.1;
359 assert_eq!(packet.version, 0x02);
360 assert_eq!(packet.padding, 0x00);
361 assert_eq!(packet.extension, 0x00);
362 assert_eq!(packet.csrc_count, 0x01);
363 assert_eq!(packet.marker, 0x00);
364 assert_eq!(packet.payload_type, 0x11);
365 assert_eq!(packet.sequence_number, 0x1234);
366 assert_eq!(packet.timestamp, 0x567890AB);
367 assert_eq!(packet.ssrc, 0xCDEFFEDC);
368 assert_eq!(packet.csrc, vec![0xBA098765]);
369 assert!(packet.header_extension.is_none());
370 assert_eq!(packet.payload, [0x43]);
371 assert_eq!(packet.padding_bytes, []);
372 }
373
374 #[test]
375 fn parse_rtp_packet_header_ext() {
376 let data = vec![
377 0x90, 0x11, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x09,
378 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11, 0x43,
379 ];
380 let result = parse_rtp_packet(&data);
381
382 assert!(result.is_ok());
383
384 let data = result.ok().unwrap();
385 assert_eq!(data.0.len(), 0);
386
387 let packet = data.1;
388 assert_eq!(packet.version, 0x02);
389 assert_eq!(packet.padding, 0x00);
390 assert_eq!(packet.extension, 0x01);
391 assert_eq!(packet.csrc_count, 0x00);
392 assert_eq!(packet.marker, 0x00);
393 assert_eq!(packet.payload_type, 0x11);
394 assert_eq!(packet.sequence_number, 0x1234);
395 assert_eq!(packet.timestamp, 0x567890AB);
396 assert_eq!(packet.ssrc, 0xCDEFFEDC);
397 assert_eq!(packet.csrc, vec![]);
398 assert!(packet.header_extension.is_some());
399
400 let header_extension = packet.header_extension.unwrap();
401 assert_eq!(header_extension.profile, 0xBA09);
402 assert_eq!(header_extension.length, 0x0002);
403 assert_eq!(
404 header_extension.data,
405 [0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11]
406 );
407
408 assert_eq!(packet.payload, [0x43]);
409 assert_eq!(packet.padding_bytes, []);
410 }
411
412 #[test]
413 fn parse_rtp_packet_csrc_header_ext() {
414 let data = vec![
415 0x91, 0x11, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x09,
416 0x87, 0x65, 0x43, 0x21, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11,
417 0x43,
418 ];
419 let result = parse_rtp_packet(&data);
420
421 assert!(result.is_ok());
422
423 let data = result.ok().unwrap();
424 assert_eq!(data.0.len(), 0);
425
426 let packet = data.1;
427 assert_eq!(packet.version, 0x02);
428 assert_eq!(packet.padding, 0x00);
429 assert_eq!(packet.extension, 0x01);
430 assert_eq!(packet.csrc_count, 0x01);
431 assert_eq!(packet.marker, 0x00);
432 assert_eq!(packet.payload_type, 0x11);
433 assert_eq!(packet.sequence_number, 0x1234);
434 assert_eq!(packet.timestamp, 0x567890AB);
435 assert_eq!(packet.ssrc, 0xCDEFFEDC);
436 assert_eq!(packet.csrc, vec![0xBA098765]);
437 assert!(packet.header_extension.is_some());
438
439 let header_extension = packet.header_extension.unwrap();
440 assert_eq!(header_extension.profile, 0x4321);
441 assert_eq!(header_extension.length, 0x0002);
442 assert_eq!(
443 header_extension.data,
444 [0x00, 0x00, 0x00, 0x00, 0x11, 0x11, 0x11, 0x11]
445 );
446
447 assert_eq!(packet.payload, [0x43]);
448 assert_eq!(packet.padding_bytes, []);
449 }
450
451 #[test]
452 fn parse_rtp_packet_padding() {
453 let data = vec![
454 0xA0, 0x11, 0x12, 0x34, 0x56, 0x78, 0x90, 0xAB, 0xCD, 0xEF, 0xFE, 0xDC, 0xBA, 0x09,
455 0x03,
456 ];
457 let result = parse_rtp_packet(&data);
458
459 assert!(result.is_ok());
460
461 let data = result.ok().unwrap();
462 assert_eq!(data.0.len(), 0);
463
464 let packet = data.1;
465 assert_eq!(packet.version, 0x02);
466 assert_eq!(packet.padding, 0x01);
467 assert_eq!(packet.extension, 0x00);
468 assert_eq!(packet.csrc_count, 0x00);
469 assert_eq!(packet.marker, 0x00);
470 assert_eq!(packet.payload_type, 0x11);
471 assert_eq!(packet.sequence_number, 0x1234);
472 assert_eq!(packet.timestamp, 0x567890AB);
473 assert_eq!(packet.ssrc, 0xCDEFFEDC);
474 assert_eq!(packet.csrc, vec![]);
475 assert!(packet.header_extension.is_none());
476 assert_eq!(packet.payload, []);
477 assert_eq!(packet.padding_bytes, [0xBA, 0x09, 0x03]);
478 }
479}