1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/rtp_rtcp/source/rtcp_utility.h"
12
13 #include <assert.h>
14 #include <math.h> // ceil
15 #include <string.h> // memcpy
16
17 namespace webrtc {
18
19 namespace RTCPUtility {
MidNtp(uint32_t ntp_sec,uint32_t ntp_frac)20 uint32_t MidNtp(uint32_t ntp_sec, uint32_t ntp_frac) {
21 return (ntp_sec << 16) + (ntp_frac >> 16);
22 } // end RTCPUtility
23 }
24
25 // RTCPParserV2 : currently read only
RTCPParserV2(const uint8_t * rtcpData,size_t rtcpDataLength,bool rtcpReducedSizeEnable)26 RTCPUtility::RTCPParserV2::RTCPParserV2(const uint8_t* rtcpData,
27 size_t rtcpDataLength,
28 bool rtcpReducedSizeEnable)
29 : _ptrRTCPDataBegin(rtcpData),
30 _RTCPReducedSizeEnable(rtcpReducedSizeEnable),
31 _ptrRTCPDataEnd(rtcpData + rtcpDataLength),
32 _validPacket(false),
33 _ptrRTCPData(rtcpData),
34 _ptrRTCPBlockEnd(NULL),
35 _state(State_TopLevel),
36 _numberOfBlocks(0),
37 _packetType(kRtcpNotValidCode) {
38 Validate();
39 }
40
~RTCPParserV2()41 RTCPUtility::RTCPParserV2::~RTCPParserV2() {
42 }
43
44 ptrdiff_t
LengthLeft() const45 RTCPUtility::RTCPParserV2::LengthLeft() const
46 {
47 return (_ptrRTCPDataEnd- _ptrRTCPData);
48 }
49
50 RTCPUtility::RTCPPacketTypes
PacketType() const51 RTCPUtility::RTCPParserV2::PacketType() const
52 {
53 return _packetType;
54 }
55
56 const RTCPUtility::RTCPPacket&
Packet() const57 RTCPUtility::RTCPParserV2::Packet() const
58 {
59 return _packet;
60 }
61
62 RTCPUtility::RTCPPacketTypes
Begin()63 RTCPUtility::RTCPParserV2::Begin()
64 {
65 _ptrRTCPData = _ptrRTCPDataBegin;
66
67 return Iterate();
68 }
69
70 RTCPUtility::RTCPPacketTypes
Iterate()71 RTCPUtility::RTCPParserV2::Iterate()
72 {
73 // Reset packet type
74 _packetType = kRtcpNotValidCode;
75
76 if (IsValid())
77 {
78 switch (_state)
79 {
80 case State_TopLevel:
81 IterateTopLevel();
82 break;
83 case State_ReportBlockItem:
84 IterateReportBlockItem();
85 break;
86 case State_SDESChunk:
87 IterateSDESChunk();
88 break;
89 case State_BYEItem:
90 IterateBYEItem();
91 break;
92 case State_ExtendedJitterItem:
93 IterateExtendedJitterItem();
94 break;
95 case State_RTPFB_NACKItem:
96 IterateNACKItem();
97 break;
98 case State_RTPFB_TMMBRItem:
99 IterateTMMBRItem();
100 break;
101 case State_RTPFB_TMMBNItem:
102 IterateTMMBNItem();
103 break;
104 case State_PSFB_SLIItem:
105 IterateSLIItem();
106 break;
107 case State_PSFB_RPSIItem:
108 IterateRPSIItem();
109 break;
110 case State_PSFB_FIRItem:
111 IterateFIRItem();
112 break;
113 case State_PSFB_AppItem:
114 IteratePsfbAppItem();
115 break;
116 case State_PSFB_REMBItem:
117 IteratePsfbREMBItem();
118 break;
119 case State_XRItem:
120 IterateXrItem();
121 break;
122 case State_XR_DLLRItem:
123 IterateXrDlrrItem();
124 break;
125 case State_AppItem:
126 IterateAppItem();
127 break;
128 default:
129 assert(false); // Invalid state!
130 break;
131 }
132 }
133 return _packetType;
134 }
135
136 void
IterateTopLevel()137 RTCPUtility::RTCPParserV2::IterateTopLevel()
138 {
139 for (;;)
140 {
141 RTCPCommonHeader header;
142
143 const bool success = RTCPParseCommonHeader(_ptrRTCPData,
144 _ptrRTCPDataEnd,
145 header);
146
147 if (!success)
148 {
149 return;
150 }
151 _ptrRTCPBlockEnd = _ptrRTCPData + header.LengthInOctets;
152 if (_ptrRTCPBlockEnd > _ptrRTCPDataEnd)
153 {
154 // Bad block!
155 return;
156 }
157
158 switch (header.PT)
159 {
160 case PT_SR:
161 {
162 // number of Report blocks
163 _numberOfBlocks = header.IC;
164 ParseSR();
165 return;
166 }
167 case PT_RR:
168 {
169 // number of Report blocks
170 _numberOfBlocks = header.IC;
171 ParseRR();
172 return;
173 }
174 case PT_SDES:
175 {
176 // number of SDES blocks
177 _numberOfBlocks = header.IC;
178 const bool ok = ParseSDES();
179 if (!ok)
180 {
181 // Nothing supported found, continue to next block!
182 break;
183 }
184 return;
185 }
186 case PT_BYE:
187 {
188 _numberOfBlocks = header.IC;
189 const bool ok = ParseBYE();
190 if (!ok)
191 {
192 // Nothing supported found, continue to next block!
193 break;
194 }
195 return;
196 }
197 case PT_IJ:
198 {
199 // number of Report blocks
200 _numberOfBlocks = header.IC;
201 ParseIJ();
202 return;
203 }
204 case PT_RTPFB: // Fall through!
205 case PT_PSFB:
206 {
207 const bool ok = ParseFBCommon(header);
208 if (!ok)
209 {
210 // Nothing supported found, continue to next block!
211 break;
212 }
213 return;
214 }
215 case PT_APP:
216 {
217 const bool ok = ParseAPP(header);
218 if (!ok)
219 {
220 // Nothing supported found, continue to next block!
221 break;
222 }
223 return;
224 }
225 case PT_XR:
226 {
227 const bool ok = ParseXr();
228 if (!ok)
229 {
230 // Nothing supported found, continue to next block!
231 break;
232 }
233 return;
234 }
235 default:
236 // Not supported! Skip!
237 EndCurrentBlock();
238 break;
239 }
240 }
241 }
242
243 void
IterateXrItem()244 RTCPUtility::RTCPParserV2::IterateXrItem()
245 {
246 const bool success = ParseXrItem();
247 if (!success)
248 {
249 Iterate();
250 }
251 }
252
253 void
IterateXrDlrrItem()254 RTCPUtility::RTCPParserV2::IterateXrDlrrItem()
255 {
256 const bool success = ParseXrDlrrItem();
257 if (!success)
258 {
259 Iterate();
260 }
261 }
262
263 void
IterateReportBlockItem()264 RTCPUtility::RTCPParserV2::IterateReportBlockItem()
265 {
266 const bool success = ParseReportBlockItem();
267 if (!success)
268 {
269 Iterate();
270 }
271 }
272
273 void
IterateSDESChunk()274 RTCPUtility::RTCPParserV2::IterateSDESChunk()
275 {
276 const bool success = ParseSDESChunk();
277 if (!success)
278 {
279 Iterate();
280 }
281 }
282
283 void
IterateBYEItem()284 RTCPUtility::RTCPParserV2::IterateBYEItem()
285 {
286 const bool success = ParseBYEItem();
287 if (!success)
288 {
289 Iterate();
290 }
291 }
292
293 void
IterateExtendedJitterItem()294 RTCPUtility::RTCPParserV2::IterateExtendedJitterItem()
295 {
296 const bool success = ParseIJItem();
297 if (!success)
298 {
299 Iterate();
300 }
301 }
302
303 void
IterateNACKItem()304 RTCPUtility::RTCPParserV2::IterateNACKItem()
305 {
306 const bool success = ParseNACKItem();
307 if (!success)
308 {
309 Iterate();
310 }
311 }
312
313 void
IterateTMMBRItem()314 RTCPUtility::RTCPParserV2::IterateTMMBRItem()
315 {
316 const bool success = ParseTMMBRItem();
317 if (!success)
318 {
319 Iterate();
320 }
321 }
322
323 void
IterateTMMBNItem()324 RTCPUtility::RTCPParserV2::IterateTMMBNItem()
325 {
326 const bool success = ParseTMMBNItem();
327 if (!success)
328 {
329 Iterate();
330 }
331 }
332
333 void
IterateSLIItem()334 RTCPUtility::RTCPParserV2::IterateSLIItem()
335 {
336 const bool success = ParseSLIItem();
337 if (!success)
338 {
339 Iterate();
340 }
341 }
342
343 void
IterateRPSIItem()344 RTCPUtility::RTCPParserV2::IterateRPSIItem()
345 {
346 const bool success = ParseRPSIItem();
347 if (!success)
348 {
349 Iterate();
350 }
351 }
352
353 void
IterateFIRItem()354 RTCPUtility::RTCPParserV2::IterateFIRItem()
355 {
356 const bool success = ParseFIRItem();
357 if (!success)
358 {
359 Iterate();
360 }
361 }
362
363 void
IteratePsfbAppItem()364 RTCPUtility::RTCPParserV2::IteratePsfbAppItem()
365 {
366 const bool success = ParsePsfbAppItem();
367 if (!success)
368 {
369 Iterate();
370 }
371 }
372
373 void
IteratePsfbREMBItem()374 RTCPUtility::RTCPParserV2::IteratePsfbREMBItem()
375 {
376 const bool success = ParsePsfbREMBItem();
377 if (!success)
378 {
379 Iterate();
380 }
381 }
382
383 void
IterateAppItem()384 RTCPUtility::RTCPParserV2::IterateAppItem()
385 {
386 const bool success = ParseAPPItem();
387 if (!success)
388 {
389 Iterate();
390 }
391 }
392
393 void
Validate()394 RTCPUtility::RTCPParserV2::Validate()
395 {
396 if (_ptrRTCPData == NULL)
397 {
398 return; // NOT VALID
399 }
400
401 RTCPCommonHeader header;
402 const bool success = RTCPParseCommonHeader(_ptrRTCPDataBegin,
403 _ptrRTCPDataEnd,
404 header);
405
406 if (!success)
407 {
408 return; // NOT VALID!
409 }
410
411 // * if (!reducedSize) : first packet must be RR or SR.
412 //
413 // * The padding bit (P) should be zero for the first packet of a
414 // compound RTCP packet because padding should only be applied,
415 // if it is needed, to the last packet. (NOT CHECKED!)
416 //
417 // * The length fields of the individual RTCP packets must add up
418 // to the overall length of the compound RTCP packet as
419 // received. This is a fairly strong check. (NOT CHECKED!)
420
421 if (!_RTCPReducedSizeEnable)
422 {
423 if ((header.PT != PT_SR) && (header.PT != PT_RR))
424 {
425 return; // NOT VALID
426 }
427 }
428
429 _validPacket = true;
430 }
431
432 bool
IsValid() const433 RTCPUtility::RTCPParserV2::IsValid() const
434 {
435 return _validPacket;
436 }
437
438 void
EndCurrentBlock()439 RTCPUtility::RTCPParserV2::EndCurrentBlock()
440 {
441 _ptrRTCPData = _ptrRTCPBlockEnd;
442 }
443
444 bool
RTCPParseCommonHeader(const uint8_t * ptrDataBegin,const uint8_t * ptrDataEnd,RTCPCommonHeader & parsedHeader)445 RTCPUtility::RTCPParseCommonHeader( const uint8_t* ptrDataBegin,
446 const uint8_t* ptrDataEnd,
447 RTCPCommonHeader& parsedHeader)
448 {
449 if (!ptrDataBegin || !ptrDataEnd)
450 {
451 return false;
452 }
453
454 // 0 1 2 3
455 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
456 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
457 // |V=2|P| IC | PT | length |
458 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
459 //
460 // Common header for all RTCP packets, 4 octets.
461
462 if ((ptrDataEnd - ptrDataBegin) < 4)
463 {
464 return false;
465 }
466
467 parsedHeader.V = ptrDataBegin[0] >> 6;
468 parsedHeader.P = ((ptrDataBegin[0] & 0x20) == 0) ? false : true;
469 parsedHeader.IC = ptrDataBegin[0] & 0x1f;
470 parsedHeader.PT = ptrDataBegin[1];
471
472 parsedHeader.LengthInOctets = (ptrDataBegin[2] << 8) + ptrDataBegin[3] + 1;
473 parsedHeader.LengthInOctets *= 4;
474
475 if(parsedHeader.LengthInOctets == 0)
476 {
477 return false;
478 }
479 // Check if RTP version field == 2
480 if (parsedHeader.V != 2)
481 {
482 return false;
483 }
484
485 return true;
486 }
487
488 bool
ParseRR()489 RTCPUtility::RTCPParserV2::ParseRR()
490 {
491 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
492
493 if (length < 8)
494 {
495 return false;
496 }
497
498
499 _ptrRTCPData += 4; // Skip header
500
501 _packetType = kRtcpRrCode;
502
503 _packet.RR.SenderSSRC = *_ptrRTCPData++ << 24;
504 _packet.RR.SenderSSRC += *_ptrRTCPData++ << 16;
505 _packet.RR.SenderSSRC += *_ptrRTCPData++ << 8;
506 _packet.RR.SenderSSRC += *_ptrRTCPData++;
507
508 _packet.RR.NumberOfReportBlocks = _numberOfBlocks;
509
510 // State transition
511 _state = State_ReportBlockItem;
512
513 return true;
514 }
515
516 bool
ParseSR()517 RTCPUtility::RTCPParserV2::ParseSR()
518 {
519 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
520
521 if (length < 28)
522 {
523 EndCurrentBlock();
524 return false;
525 }
526
527 _ptrRTCPData += 4; // Skip header
528
529 _packetType = kRtcpSrCode;
530
531 _packet.SR.SenderSSRC = *_ptrRTCPData++ << 24;
532 _packet.SR.SenderSSRC += *_ptrRTCPData++ << 16;
533 _packet.SR.SenderSSRC += *_ptrRTCPData++ << 8;
534 _packet.SR.SenderSSRC += *_ptrRTCPData++;
535
536 _packet.SR.NTPMostSignificant = *_ptrRTCPData++ << 24;
537 _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 16;
538 _packet.SR.NTPMostSignificant += *_ptrRTCPData++ << 8;
539 _packet.SR.NTPMostSignificant += *_ptrRTCPData++;
540
541 _packet.SR.NTPLeastSignificant = *_ptrRTCPData++ << 24;
542 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 16;
543 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++ << 8;
544 _packet.SR.NTPLeastSignificant += *_ptrRTCPData++;
545
546 _packet.SR.RTPTimestamp = *_ptrRTCPData++ << 24;
547 _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 16;
548 _packet.SR.RTPTimestamp += *_ptrRTCPData++ << 8;
549 _packet.SR.RTPTimestamp += *_ptrRTCPData++;
550
551 _packet.SR.SenderPacketCount = *_ptrRTCPData++ << 24;
552 _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 16;
553 _packet.SR.SenderPacketCount += *_ptrRTCPData++ << 8;
554 _packet.SR.SenderPacketCount += *_ptrRTCPData++;
555
556 _packet.SR.SenderOctetCount = *_ptrRTCPData++ << 24;
557 _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 16;
558 _packet.SR.SenderOctetCount += *_ptrRTCPData++ << 8;
559 _packet.SR.SenderOctetCount += *_ptrRTCPData++;
560
561 _packet.SR.NumberOfReportBlocks = _numberOfBlocks;
562
563 // State transition
564 if(_numberOfBlocks != 0)
565 {
566 _state = State_ReportBlockItem;
567 }else
568 {
569 // don't go to state report block item if 0 report blocks
570 _state = State_TopLevel;
571 EndCurrentBlock();
572 }
573 return true;
574 }
575
576 bool
ParseReportBlockItem()577 RTCPUtility::RTCPParserV2::ParseReportBlockItem()
578 {
579 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
580
581 if (length < 24 || _numberOfBlocks <= 0)
582 {
583 _state = State_TopLevel;
584
585 EndCurrentBlock();
586 return false;
587 }
588 _packet.ReportBlockItem.SSRC = *_ptrRTCPData++ << 24;
589 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 16;
590 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++ << 8;
591 _packet.ReportBlockItem.SSRC += *_ptrRTCPData++;
592
593 _packet.ReportBlockItem.FractionLost = *_ptrRTCPData++;
594
595 _packet.ReportBlockItem.CumulativeNumOfPacketsLost = *_ptrRTCPData++ << 16;
596 _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++ << 8;
597 _packet.ReportBlockItem.CumulativeNumOfPacketsLost += *_ptrRTCPData++;
598
599 _packet.ReportBlockItem.ExtendedHighestSequenceNumber = *_ptrRTCPData++ << 24;
600 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ << 16;
601 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++ << 8;
602 _packet.ReportBlockItem.ExtendedHighestSequenceNumber += *_ptrRTCPData++;
603
604 _packet.ReportBlockItem.Jitter = *_ptrRTCPData++ << 24;
605 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 16;
606 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++ << 8;
607 _packet.ReportBlockItem.Jitter += *_ptrRTCPData++;
608
609 _packet.ReportBlockItem.LastSR = *_ptrRTCPData++ << 24;
610 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 16;
611 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++ << 8;
612 _packet.ReportBlockItem.LastSR += *_ptrRTCPData++;
613
614 _packet.ReportBlockItem.DelayLastSR = *_ptrRTCPData++ << 24;
615 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 16;
616 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++ << 8;
617 _packet.ReportBlockItem.DelayLastSR += *_ptrRTCPData++;
618
619 _numberOfBlocks--;
620 _packetType = kRtcpReportBlockItemCode;
621 return true;
622 }
623
624 /* From RFC 5450: Transmission Time Offsets in RTP Streams.
625 0 1 2 3
626 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
627 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
628 hdr |V=2|P| RC | PT=IJ=195 | length |
629 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
630 | inter-arrival jitter |
631 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
632 . .
633 . .
634 . .
635 | inter-arrival jitter |
636 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
637 */
638
639 bool
ParseIJ()640 RTCPUtility::RTCPParserV2::ParseIJ()
641 {
642 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
643
644 if (length < 4)
645 {
646 return false;
647 }
648
649 _ptrRTCPData += 4; // Skip header
650
651 _packetType = kRtcpExtendedIjCode;
652
653 // State transition
654 _state = State_ExtendedJitterItem;
655 return true;
656 }
657
658 bool
ParseIJItem()659 RTCPUtility::RTCPParserV2::ParseIJItem()
660 {
661 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
662
663 if (length < 4 || _numberOfBlocks <= 0)
664 {
665 _state = State_TopLevel;
666 EndCurrentBlock();
667 return false;
668 }
669
670 _packet.ExtendedJitterReportItem.Jitter = *_ptrRTCPData++ << 24;
671 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 16;
672 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++ << 8;
673 _packet.ExtendedJitterReportItem.Jitter += *_ptrRTCPData++;
674
675 _numberOfBlocks--;
676 _packetType = kRtcpExtendedIjItemCode;
677 return true;
678 }
679
680 bool
ParseSDES()681 RTCPUtility::RTCPParserV2::ParseSDES()
682 {
683 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
684
685 if (length < 8)
686 {
687 _state = State_TopLevel;
688
689 EndCurrentBlock();
690 return false;
691 }
692 _ptrRTCPData += 4; // Skip header
693
694 _state = State_SDESChunk;
695 _packetType = kRtcpSdesCode;
696 return true;
697 }
698
699 bool
ParseSDESChunk()700 RTCPUtility::RTCPParserV2::ParseSDESChunk()
701 {
702 if(_numberOfBlocks <= 0)
703 {
704 _state = State_TopLevel;
705
706 EndCurrentBlock();
707 return false;
708 }
709 _numberOfBlocks--;
710
711 // Find CName item in a SDES chunk.
712 while (_ptrRTCPData < _ptrRTCPBlockEnd)
713 {
714 const ptrdiff_t dataLen = _ptrRTCPBlockEnd - _ptrRTCPData;
715 if (dataLen < 4)
716 {
717 _state = State_TopLevel;
718
719 EndCurrentBlock();
720 return false;
721 }
722
723 uint32_t SSRC = *_ptrRTCPData++ << 24;
724 SSRC += *_ptrRTCPData++ << 16;
725 SSRC += *_ptrRTCPData++ << 8;
726 SSRC += *_ptrRTCPData++;
727
728 const bool foundCname = ParseSDESItem();
729 if (foundCname)
730 {
731 _packet.CName.SenderSSRC = SSRC; // Add SSRC
732 return true;
733 }
734 }
735 _state = State_TopLevel;
736
737 EndCurrentBlock();
738 return false;
739 }
740
741 bool
ParseSDESItem()742 RTCPUtility::RTCPParserV2::ParseSDESItem()
743 {
744 // Find CName
745 // Only the CNAME item is mandatory. RFC 3550 page 46
746 bool foundCName = false;
747
748 size_t itemOctetsRead = 0;
749 while (_ptrRTCPData < _ptrRTCPBlockEnd)
750 {
751 const uint8_t tag = *_ptrRTCPData++;
752 ++itemOctetsRead;
753
754 if (tag == 0)
755 {
756 // End tag! 4 oct aligned
757 while ((itemOctetsRead++ % 4) != 0)
758 {
759 ++_ptrRTCPData;
760 }
761 return foundCName;
762 }
763
764 if (_ptrRTCPData < _ptrRTCPBlockEnd)
765 {
766 const uint8_t len = *_ptrRTCPData++;
767 ++itemOctetsRead;
768
769 if (tag == 1)
770 {
771 // CNAME
772
773 // Sanity
774 if ((_ptrRTCPData + len) >= _ptrRTCPBlockEnd)
775 {
776 _state = State_TopLevel;
777
778 EndCurrentBlock();
779 return false;
780 }
781 uint8_t i = 0;
782 for (; i < len; ++i)
783 {
784 const uint8_t c = _ptrRTCPData[i];
785 if ((c < ' ') || (c > '{') || (c == '%') || (c == '\\'))
786 {
787 // Illegal char
788 _state = State_TopLevel;
789
790 EndCurrentBlock();
791 return false;
792 }
793 _packet.CName.CName[i] = c;
794 }
795 // Make sure we are null terminated.
796 _packet.CName.CName[i] = 0;
797 _packetType = kRtcpSdesChunkCode;
798
799 foundCName = true;
800 }
801 _ptrRTCPData += len;
802 itemOctetsRead += len;
803 }
804 }
805
806 // No end tag found!
807 _state = State_TopLevel;
808
809 EndCurrentBlock();
810 return false;
811 }
812
813 bool
ParseBYE()814 RTCPUtility::RTCPParserV2::ParseBYE()
815 {
816 _ptrRTCPData += 4; // Skip header
817
818 _state = State_BYEItem;
819
820 return ParseBYEItem();
821 }
822
823 bool
ParseBYEItem()824 RTCPUtility::RTCPParserV2::ParseBYEItem()
825 {
826 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
827 if (length < 4 || _numberOfBlocks == 0)
828 {
829 _state = State_TopLevel;
830
831 EndCurrentBlock();
832 return false;
833 }
834
835 _packetType = kRtcpByeCode;
836
837 _packet.BYE.SenderSSRC = *_ptrRTCPData++ << 24;
838 _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 16;
839 _packet.BYE.SenderSSRC += *_ptrRTCPData++ << 8;
840 _packet.BYE.SenderSSRC += *_ptrRTCPData++;
841
842 // we can have several CSRCs attached
843
844 // sanity
845 if(length >= 4*_numberOfBlocks)
846 {
847 _ptrRTCPData += (_numberOfBlocks -1)*4;
848 }
849 _numberOfBlocks = 0;
850
851 return true;
852 }
853 /*
854 0 1 2 3
855 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
856 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
857 |V=2|P|reserved | PT=XR=207 | length |
858 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
859 | SSRC |
860 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
861 : report blocks :
862 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
863 */
ParseXr()864 bool RTCPUtility::RTCPParserV2::ParseXr()
865 {
866 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
867 if (length < 8)
868 {
869 EndCurrentBlock();
870 return false;
871 }
872
873 _ptrRTCPData += 4; // Skip header
874
875 _packet.XR.OriginatorSSRC = *_ptrRTCPData++ << 24;
876 _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 16;
877 _packet.XR.OriginatorSSRC += *_ptrRTCPData++ << 8;
878 _packet.XR.OriginatorSSRC += *_ptrRTCPData++;
879
880 _packetType = kRtcpXrHeaderCode;
881 _state = State_XRItem;
882 return true;
883 }
884
885 /* Extended report block format (RFC 3611).
886 BT: block type.
887 block length: length of report block in 32-bits words minus one (including
888 the header).
889 0 1 2 3
890 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
891 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
892 | BT | type-specific | block length |
893 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
894 : type-specific block contents :
895 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
896 */
ParseXrItem()897 bool RTCPUtility::RTCPParserV2::ParseXrItem() {
898 const int kBlockHeaderLengthInBytes = 4;
899 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
900 if (length < kBlockHeaderLengthInBytes) {
901 _state = State_TopLevel;
902 EndCurrentBlock();
903 return false;
904 }
905
906 uint8_t block_type = *_ptrRTCPData++;
907 _ptrRTCPData++; // Ignore reserved.
908
909 uint16_t block_length_in_4bytes = *_ptrRTCPData++ << 8;
910 block_length_in_4bytes += *_ptrRTCPData++;
911
912 switch (block_type) {
913 case kBtReceiverReferenceTime:
914 return ParseXrReceiverReferenceTimeItem(block_length_in_4bytes);
915 case kBtDlrr:
916 return ParseXrDlrr(block_length_in_4bytes);
917 case kBtVoipMetric:
918 return ParseXrVoipMetricItem(block_length_in_4bytes);
919 default:
920 return ParseXrUnsupportedBlockType(block_length_in_4bytes);
921 }
922 }
923
924 /* Receiver Reference Time Report Block.
925 0 1 2 3
926 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
927 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
928 | BT=4 | reserved | block length = 2 |
929 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
930 | NTP timestamp, most significant word |
931 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
932 | NTP timestamp, least significant word |
933 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
934 */
ParseXrReceiverReferenceTimeItem(int block_length_4bytes)935 bool RTCPUtility::RTCPParserV2::ParseXrReceiverReferenceTimeItem(
936 int block_length_4bytes) {
937 const int kBlockLengthIn4Bytes = 2;
938 const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4;
939 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
940 if (block_length_4bytes != kBlockLengthIn4Bytes ||
941 length < kBlockLengthInBytes) {
942 _state = State_TopLevel;
943 EndCurrentBlock();
944 return false;
945 }
946
947 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant = *_ptrRTCPData++<<24;
948 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<16;
949 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++<<8;
950 _packet.XRReceiverReferenceTimeItem.NTPMostSignificant+= *_ptrRTCPData++;
951
952 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant = *_ptrRTCPData++<<24;
953 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<16;
954 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++<<8;
955 _packet.XRReceiverReferenceTimeItem.NTPLeastSignificant+= *_ptrRTCPData++;
956
957 _packetType = kRtcpXrReceiverReferenceTimeCode;
958 _state = State_XRItem;
959 return true;
960 }
961
962 /* DLRR Report Block.
963 0 1 2 3
964 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
965 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
966 | BT=5 | reserved | block length |
967 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
968 | SSRC_1 (SSRC of first receiver) | sub-
969 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
970 | last RR (LRR) | 1
971 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
972 | delay since last RR (DLRR) |
973 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
974 | SSRC_2 (SSRC of second receiver) | sub-
975 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ block
976 : ... : 2
977 +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+
978 */
ParseXrDlrr(int block_length_4bytes)979 bool RTCPUtility::RTCPParserV2::ParseXrDlrr(int block_length_4bytes) {
980 const int kSubBlockLengthIn4Bytes = 3;
981 if (block_length_4bytes < 0 ||
982 (block_length_4bytes % kSubBlockLengthIn4Bytes) != 0) {
983 _state = State_TopLevel;
984 EndCurrentBlock();
985 return false;
986 }
987 _packetType = kRtcpXrDlrrReportBlockCode;
988 _state = State_XR_DLLRItem;
989 _numberOfBlocks = block_length_4bytes / kSubBlockLengthIn4Bytes;
990 return true;
991 }
992
ParseXrDlrrItem()993 bool RTCPUtility::RTCPParserV2::ParseXrDlrrItem() {
994 if (_numberOfBlocks == 0) {
995 _state = State_XRItem;
996 return false;
997 }
998 const int kSubBlockLengthInBytes = 12;
999 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1000 if (length < kSubBlockLengthInBytes) {
1001 _state = State_TopLevel;
1002 EndCurrentBlock();
1003 return false;
1004 }
1005
1006 _packet.XRDLRRReportBlockItem.SSRC = *_ptrRTCPData++ << 24;
1007 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 16;
1008 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++ << 8;
1009 _packet.XRDLRRReportBlockItem.SSRC += *_ptrRTCPData++;
1010
1011 _packet.XRDLRRReportBlockItem.LastRR = *_ptrRTCPData++ << 24;
1012 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 16;
1013 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++ << 8;
1014 _packet.XRDLRRReportBlockItem.LastRR += *_ptrRTCPData++;
1015
1016 _packet.XRDLRRReportBlockItem.DelayLastRR = *_ptrRTCPData++ << 24;
1017 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 16;
1018 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++ << 8;
1019 _packet.XRDLRRReportBlockItem.DelayLastRR += *_ptrRTCPData++;
1020
1021 _packetType = kRtcpXrDlrrReportBlockItemCode;
1022 --_numberOfBlocks;
1023 _state = State_XR_DLLRItem;
1024 return true;
1025 }
1026 /* VoIP Metrics Report Block.
1027 0 1 2 3
1028 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1029 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1030 | BT=7 | reserved | block length = 8 |
1031 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1032 | SSRC of source |
1033 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1034 | loss rate | discard rate | burst density | gap density |
1035 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1036 | burst duration | gap duration |
1037 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1038 | round trip delay | end system delay |
1039 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1040 | signal level | noise level | RERL | Gmin |
1041 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1042 | R factor | ext. R factor | MOS-LQ | MOS-CQ |
1043 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1044 | RX config | reserved | JB nominal |
1045 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1046 | JB maximum | JB abs max |
1047 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1048 */
1049
ParseXrVoipMetricItem(int block_length_4bytes)1050 bool RTCPUtility::RTCPParserV2::ParseXrVoipMetricItem(int block_length_4bytes) {
1051 const int kBlockLengthIn4Bytes = 8;
1052 const int kBlockLengthInBytes = kBlockLengthIn4Bytes * 4;
1053 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1054 if (block_length_4bytes != kBlockLengthIn4Bytes ||
1055 length < kBlockLengthInBytes) {
1056 _state = State_TopLevel;
1057 EndCurrentBlock();
1058 return false;
1059 }
1060
1061 _packet.XRVOIPMetricItem.SSRC = *_ptrRTCPData++ << 24;
1062 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 16;
1063 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++ << 8;
1064 _packet.XRVOIPMetricItem.SSRC += *_ptrRTCPData++;
1065
1066 _packet.XRVOIPMetricItem.lossRate = *_ptrRTCPData++;
1067 _packet.XRVOIPMetricItem.discardRate = *_ptrRTCPData++;
1068 _packet.XRVOIPMetricItem.burstDensity = *_ptrRTCPData++;
1069 _packet.XRVOIPMetricItem.gapDensity = *_ptrRTCPData++;
1070
1071 _packet.XRVOIPMetricItem.burstDuration = *_ptrRTCPData++ << 8;
1072 _packet.XRVOIPMetricItem.burstDuration += *_ptrRTCPData++;
1073
1074 _packet.XRVOIPMetricItem.gapDuration = *_ptrRTCPData++ << 8;
1075 _packet.XRVOIPMetricItem.gapDuration += *_ptrRTCPData++;
1076
1077 _packet.XRVOIPMetricItem.roundTripDelay = *_ptrRTCPData++ << 8;
1078 _packet.XRVOIPMetricItem.roundTripDelay += *_ptrRTCPData++;
1079
1080 _packet.XRVOIPMetricItem.endSystemDelay = *_ptrRTCPData++ << 8;
1081 _packet.XRVOIPMetricItem.endSystemDelay += *_ptrRTCPData++;
1082
1083 _packet.XRVOIPMetricItem.signalLevel = *_ptrRTCPData++;
1084 _packet.XRVOIPMetricItem.noiseLevel = *_ptrRTCPData++;
1085 _packet.XRVOIPMetricItem.RERL = *_ptrRTCPData++;
1086 _packet.XRVOIPMetricItem.Gmin = *_ptrRTCPData++;
1087 _packet.XRVOIPMetricItem.Rfactor = *_ptrRTCPData++;
1088 _packet.XRVOIPMetricItem.extRfactor = *_ptrRTCPData++;
1089 _packet.XRVOIPMetricItem.MOSLQ = *_ptrRTCPData++;
1090 _packet.XRVOIPMetricItem.MOSCQ = *_ptrRTCPData++;
1091 _packet.XRVOIPMetricItem.RXconfig = *_ptrRTCPData++;
1092 _ptrRTCPData++; // skip reserved
1093
1094 _packet.XRVOIPMetricItem.JBnominal = *_ptrRTCPData++ << 8;
1095 _packet.XRVOIPMetricItem.JBnominal += *_ptrRTCPData++;
1096
1097 _packet.XRVOIPMetricItem.JBmax = *_ptrRTCPData++ << 8;
1098 _packet.XRVOIPMetricItem.JBmax += *_ptrRTCPData++;
1099
1100 _packet.XRVOIPMetricItem.JBabsMax = *_ptrRTCPData++ << 8;
1101 _packet.XRVOIPMetricItem.JBabsMax += *_ptrRTCPData++;
1102
1103 _packetType = kRtcpXrVoipMetricCode;
1104 _state = State_XRItem;
1105 return true;
1106 }
1107
ParseXrUnsupportedBlockType(int block_length_4bytes)1108 bool RTCPUtility::RTCPParserV2::ParseXrUnsupportedBlockType(
1109 int block_length_4bytes) {
1110 const int32_t kBlockLengthInBytes = block_length_4bytes * 4;
1111 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1112 if (length < kBlockLengthInBytes) {
1113 _state = State_TopLevel;
1114 EndCurrentBlock();
1115 return false;
1116 }
1117 // Skip block.
1118 _ptrRTCPData += kBlockLengthInBytes;
1119 _state = State_XRItem;
1120 return false;
1121 }
1122
1123 bool
ParseFBCommon(const RTCPCommonHeader & header)1124 RTCPUtility::RTCPParserV2::ParseFBCommon(const RTCPCommonHeader& header)
1125 {
1126 assert((header.PT == PT_RTPFB) || (header.PT == PT_PSFB)); // Parser logic check
1127
1128 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1129
1130 if (length < 12) // 4 * 3, RFC4585 section 6.1
1131 {
1132 EndCurrentBlock();
1133 return false;
1134 }
1135
1136 _ptrRTCPData += 4; // Skip RTCP header
1137
1138 uint32_t senderSSRC = *_ptrRTCPData++ << 24;
1139 senderSSRC += *_ptrRTCPData++ << 16;
1140 senderSSRC += *_ptrRTCPData++ << 8;
1141 senderSSRC += *_ptrRTCPData++;
1142
1143 uint32_t mediaSSRC = *_ptrRTCPData++ << 24;
1144 mediaSSRC += *_ptrRTCPData++ << 16;
1145 mediaSSRC += *_ptrRTCPData++ << 8;
1146 mediaSSRC += *_ptrRTCPData++;
1147
1148 if (header.PT == PT_RTPFB)
1149 {
1150 // Transport layer feedback
1151
1152 switch (header.IC)
1153 {
1154 case 1:
1155 {
1156 // NACK
1157 _packetType = kRtcpRtpfbNackCode;
1158 _packet.NACK.SenderSSRC = senderSSRC;
1159 _packet.NACK.MediaSSRC = mediaSSRC;
1160
1161 _state = State_RTPFB_NACKItem;
1162
1163 return true;
1164 }
1165 case 2:
1166 {
1167 // used to be ACK is this code point, which is removed
1168 // conficts with http://tools.ietf.org/html/draft-levin-avt-rtcp-burst-00
1169 break;
1170 }
1171 case 3:
1172 {
1173 // TMMBR
1174 _packetType = kRtcpRtpfbTmmbrCode;
1175 _packet.TMMBR.SenderSSRC = senderSSRC;
1176 _packet.TMMBR.MediaSSRC = mediaSSRC;
1177
1178 _state = State_RTPFB_TMMBRItem;
1179
1180 return true;
1181 }
1182 case 4:
1183 {
1184 // TMMBN
1185 _packetType = kRtcpRtpfbTmmbnCode;
1186 _packet.TMMBN.SenderSSRC = senderSSRC;
1187 _packet.TMMBN.MediaSSRC = mediaSSRC;
1188
1189 _state = State_RTPFB_TMMBNItem;
1190
1191 return true;
1192 }
1193 case 5:
1194 {
1195 // RTCP-SR-REQ Rapid Synchronisation of RTP Flows
1196 // draft-perkins-avt-rapid-rtp-sync-03.txt
1197 // trigger a new RTCP SR
1198 _packetType = kRtcpRtpfbSrReqCode;
1199
1200 // Note: No state transition, SR REQ is empty!
1201 return true;
1202 }
1203 default:
1204 break;
1205 }
1206 EndCurrentBlock();
1207 return false;
1208 }
1209 else if (header.PT == PT_PSFB)
1210 {
1211 // Payload specific feedback
1212 switch (header.IC)
1213 {
1214 case 1:
1215 // PLI
1216 _packetType = kRtcpPsfbPliCode;
1217 _packet.PLI.SenderSSRC = senderSSRC;
1218 _packet.PLI.MediaSSRC = mediaSSRC;
1219
1220 // Note: No state transition, PLI FCI is empty!
1221 return true;
1222 case 2:
1223 // SLI
1224 _packetType = kRtcpPsfbSliCode;
1225 _packet.SLI.SenderSSRC = senderSSRC;
1226 _packet.SLI.MediaSSRC = mediaSSRC;
1227
1228 _state = State_PSFB_SLIItem;
1229
1230 return true;
1231 case 3:
1232 _packetType = kRtcpPsfbRpsiCode;
1233 _packet.RPSI.SenderSSRC = senderSSRC;
1234 _packet.RPSI.MediaSSRC = mediaSSRC;
1235
1236 _state = State_PSFB_RPSIItem;
1237 return true;
1238 case 4:
1239 // FIR
1240 _packetType = kRtcpPsfbFirCode;
1241 _packet.FIR.SenderSSRC = senderSSRC;
1242 _packet.FIR.MediaSSRC = mediaSSRC;
1243
1244 _state = State_PSFB_FIRItem;
1245 return true;
1246 case 15:
1247 _packetType = kRtcpPsfbAppCode;
1248 _packet.PSFBAPP.SenderSSRC = senderSSRC;
1249 _packet.PSFBAPP.MediaSSRC = mediaSSRC;
1250
1251 _state = State_PSFB_AppItem;
1252 return true;
1253 default:
1254 break;
1255 }
1256
1257 EndCurrentBlock();
1258 return false;
1259 }
1260 else
1261 {
1262 assert(false);
1263
1264 EndCurrentBlock();
1265 return false;
1266 }
1267 }
1268
ParseRPSIItem()1269 bool RTCPUtility::RTCPParserV2::ParseRPSIItem() {
1270
1271 // RFC 4585 6.3.3. Reference Picture Selection Indication (RPSI).
1272 //
1273 // 0 1 2 3
1274 // 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1275 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1276 // | PB |0| Payload Type| Native RPSI bit string |
1277 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1278 // | defined per codec ... | Padding (0) |
1279 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1280
1281 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1282
1283 if (length < 4) {
1284 _state = State_TopLevel;
1285
1286 EndCurrentBlock();
1287 return false;
1288 }
1289 if (length > 2 + RTCP_RPSI_DATA_SIZE) {
1290 _state = State_TopLevel;
1291
1292 EndCurrentBlock();
1293 return false;
1294 }
1295
1296 _packetType = kRtcpPsfbRpsiCode;
1297
1298 uint8_t padding_bits = *_ptrRTCPData++;
1299 _packet.RPSI.PayloadType = *_ptrRTCPData++;
1300
1301 memcpy(_packet.RPSI.NativeBitString, _ptrRTCPData, length - 2);
1302 _ptrRTCPData += length - 2;
1303
1304 _packet.RPSI.NumberOfValidBits =
1305 static_cast<uint16_t>(length - 2) * 8 - padding_bits;
1306 return true;
1307 }
1308
1309 bool
ParseNACKItem()1310 RTCPUtility::RTCPParserV2::ParseNACKItem()
1311 {
1312 // RFC 4585 6.2.1. Generic NACK
1313
1314 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1315
1316 if (length < 4)
1317 {
1318 _state = State_TopLevel;
1319
1320 EndCurrentBlock();
1321 return false;
1322 }
1323
1324 _packetType = kRtcpRtpfbNackItemCode;
1325
1326 _packet.NACKItem.PacketID = *_ptrRTCPData++ << 8;
1327 _packet.NACKItem.PacketID += *_ptrRTCPData++;
1328
1329 _packet.NACKItem.BitMask = *_ptrRTCPData++ << 8;
1330 _packet.NACKItem.BitMask += *_ptrRTCPData++;
1331
1332 return true;
1333 }
1334
1335 bool
ParsePsfbAppItem()1336 RTCPUtility::RTCPParserV2::ParsePsfbAppItem()
1337 {
1338 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1339
1340 if (length < 4)
1341 {
1342 _state = State_TopLevel;
1343
1344 EndCurrentBlock();
1345 return false;
1346 }
1347 if(*_ptrRTCPData++ != 'R')
1348 {
1349 _state = State_TopLevel;
1350
1351 EndCurrentBlock();
1352 return false;
1353 }
1354 if(*_ptrRTCPData++ != 'E')
1355 {
1356 _state = State_TopLevel;
1357
1358 EndCurrentBlock();
1359 return false;
1360 }
1361 if(*_ptrRTCPData++ != 'M')
1362 {
1363 _state = State_TopLevel;
1364
1365 EndCurrentBlock();
1366 return false;
1367 }
1368 if(*_ptrRTCPData++ != 'B')
1369 {
1370 _state = State_TopLevel;
1371
1372 EndCurrentBlock();
1373 return false;
1374 }
1375 _packetType = kRtcpPsfbRembCode;
1376 _state = State_PSFB_REMBItem;
1377 return true;
1378 }
1379
1380 bool
ParsePsfbREMBItem()1381 RTCPUtility::RTCPParserV2::ParsePsfbREMBItem()
1382 {
1383 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1384
1385 if (length < 4)
1386 {
1387 _state = State_TopLevel;
1388
1389 EndCurrentBlock();
1390 return false;
1391 }
1392
1393 _packet.REMBItem.NumberOfSSRCs = *_ptrRTCPData++;
1394 const uint8_t brExp = (_ptrRTCPData[0] >> 2) & 0x3F;
1395
1396 uint32_t brMantissa = (_ptrRTCPData[0] & 0x03) << 16;
1397 brMantissa += (_ptrRTCPData[1] << 8);
1398 brMantissa += (_ptrRTCPData[2]);
1399
1400 _ptrRTCPData += 3; // Fwd read data
1401 _packet.REMBItem.BitRate = (brMantissa << brExp);
1402
1403 const ptrdiff_t length_ssrcs = _ptrRTCPBlockEnd - _ptrRTCPData;
1404 if (length_ssrcs < 4 * _packet.REMBItem.NumberOfSSRCs)
1405 {
1406 _state = State_TopLevel;
1407
1408 EndCurrentBlock();
1409 return false;
1410 }
1411
1412 _packetType = kRtcpPsfbRembItemCode;
1413
1414 for (int i = 0; i < _packet.REMBItem.NumberOfSSRCs; i++)
1415 {
1416 _packet.REMBItem.SSRCs[i] = *_ptrRTCPData++ << 24;
1417 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 16;
1418 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++ << 8;
1419 _packet.REMBItem.SSRCs[i] += *_ptrRTCPData++;
1420 }
1421 return true;
1422 }
1423
1424 bool
ParseTMMBRItem()1425 RTCPUtility::RTCPParserV2::ParseTMMBRItem()
1426 {
1427 // RFC 5104 4.2.1. Temporary Maximum Media Stream Bit Rate Request (TMMBR)
1428
1429 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1430
1431 if (length < 8)
1432 {
1433 _state = State_TopLevel;
1434
1435 EndCurrentBlock();
1436 return false;
1437 }
1438
1439 _packetType = kRtcpRtpfbTmmbrItemCode;
1440
1441 _packet.TMMBRItem.SSRC = *_ptrRTCPData++ << 24;
1442 _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 16;
1443 _packet.TMMBRItem.SSRC += *_ptrRTCPData++ << 8;
1444 _packet.TMMBRItem.SSRC += *_ptrRTCPData++;
1445
1446 uint8_t mxtbrExp = (_ptrRTCPData[0] >> 2) & 0x3F;
1447
1448 uint32_t mxtbrMantissa = (_ptrRTCPData[0] & 0x03) << 15;
1449 mxtbrMantissa += (_ptrRTCPData[1] << 7);
1450 mxtbrMantissa += (_ptrRTCPData[2] >> 1) & 0x7F;
1451
1452 uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8;
1453 measuredOH += _ptrRTCPData[3];
1454
1455 _ptrRTCPData += 4; // Fwd read data
1456
1457 _packet.TMMBRItem.MaxTotalMediaBitRate = ((mxtbrMantissa << mxtbrExp) / 1000);
1458 _packet.TMMBRItem.MeasuredOverhead = measuredOH;
1459
1460 return true;
1461 }
1462
1463 bool
ParseTMMBNItem()1464 RTCPUtility::RTCPParserV2::ParseTMMBNItem()
1465 {
1466 // RFC 5104 4.2.2. Temporary Maximum Media Stream Bit Rate Notification (TMMBN)
1467
1468 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1469
1470 if (length < 8)
1471 {
1472 _state = State_TopLevel;
1473
1474 EndCurrentBlock();
1475 return false;
1476 }
1477
1478 _packetType = kRtcpRtpfbTmmbnItemCode;
1479
1480 _packet.TMMBNItem.SSRC = *_ptrRTCPData++ << 24;
1481 _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 16;
1482 _packet.TMMBNItem.SSRC += *_ptrRTCPData++ << 8;
1483 _packet.TMMBNItem.SSRC += *_ptrRTCPData++;
1484
1485 uint8_t mxtbrExp = (_ptrRTCPData[0] >> 2) & 0x3F;
1486
1487 uint32_t mxtbrMantissa = (_ptrRTCPData[0] & 0x03) << 15;
1488 mxtbrMantissa += (_ptrRTCPData[1] << 7);
1489 mxtbrMantissa += (_ptrRTCPData[2] >> 1) & 0x7F;
1490
1491 uint32_t measuredOH = (_ptrRTCPData[2] & 0x01) << 8;
1492 measuredOH += _ptrRTCPData[3];
1493
1494 _ptrRTCPData += 4; // Fwd read data
1495
1496 _packet.TMMBNItem.MaxTotalMediaBitRate = ((mxtbrMantissa << mxtbrExp) / 1000);
1497 _packet.TMMBNItem.MeasuredOverhead = measuredOH;
1498
1499 return true;
1500 }
1501
1502 bool
ParseSLIItem()1503 RTCPUtility::RTCPParserV2::ParseSLIItem()
1504 {
1505 // RFC 5104 6.3.2. Slice Loss Indication (SLI)
1506 /*
1507 0 1 2 3
1508 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
1509 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1510 | First | Number | PictureID |
1511 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
1512 */
1513
1514 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1515
1516 if (length < 4)
1517 {
1518 _state = State_TopLevel;
1519
1520 EndCurrentBlock();
1521 return false;
1522 }
1523 _packetType = kRtcpPsfbSliItemCode;
1524
1525 uint32_t buffer;
1526 buffer = *_ptrRTCPData++ << 24;
1527 buffer += *_ptrRTCPData++ << 16;
1528 buffer += *_ptrRTCPData++ << 8;
1529 buffer += *_ptrRTCPData++;
1530
1531 _packet.SLIItem.FirstMB = uint16_t((buffer>>19) & 0x1fff);
1532 _packet.SLIItem.NumberOfMB = uint16_t((buffer>>6) & 0x1fff);
1533 _packet.SLIItem.PictureId = uint8_t(buffer & 0x3f);
1534
1535 return true;
1536 }
1537
1538 bool
ParseFIRItem()1539 RTCPUtility::RTCPParserV2::ParseFIRItem()
1540 {
1541 // RFC 5104 4.3.1. Full Intra Request (FIR)
1542
1543 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1544
1545 if (length < 8)
1546 {
1547 _state = State_TopLevel;
1548
1549 EndCurrentBlock();
1550 return false;
1551 }
1552
1553 _packetType = kRtcpPsfbFirItemCode;
1554
1555 _packet.FIRItem.SSRC = *_ptrRTCPData++ << 24;
1556 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 16;
1557 _packet.FIRItem.SSRC += *_ptrRTCPData++ << 8;
1558 _packet.FIRItem.SSRC += *_ptrRTCPData++;
1559
1560 _packet.FIRItem.CommandSequenceNumber = *_ptrRTCPData++;
1561 _ptrRTCPData += 3; // Skip "Reserved" bytes.
1562 return true;
1563 }
1564
1565 bool
ParseAPP(const RTCPCommonHeader & header)1566 RTCPUtility::RTCPParserV2::ParseAPP( const RTCPCommonHeader& header)
1567 {
1568 ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1569
1570 if (length < 12) // 4 * 3, RFC 3550 6.7 APP: Application-Defined RTCP Packet
1571 {
1572 EndCurrentBlock();
1573 return false;
1574 }
1575
1576 _ptrRTCPData += 4; // Skip RTCP header
1577
1578 uint32_t senderSSRC = *_ptrRTCPData++ << 24;
1579 senderSSRC += *_ptrRTCPData++ << 16;
1580 senderSSRC += *_ptrRTCPData++ << 8;
1581 senderSSRC += *_ptrRTCPData++;
1582
1583 uint32_t name = *_ptrRTCPData++ << 24;
1584 name += *_ptrRTCPData++ << 16;
1585 name += *_ptrRTCPData++ << 8;
1586 name += *_ptrRTCPData++;
1587
1588 length = _ptrRTCPBlockEnd - _ptrRTCPData;
1589
1590 _packetType = kRtcpAppCode;
1591
1592 _packet.APP.SubType = header.IC;
1593 _packet.APP.Name = name;
1594
1595 _state = State_AppItem;
1596 return true;
1597 }
1598
1599 bool
ParseAPPItem()1600 RTCPUtility::RTCPParserV2::ParseAPPItem()
1601 {
1602 const ptrdiff_t length = _ptrRTCPBlockEnd - _ptrRTCPData;
1603 if (length < 4)
1604 {
1605 _state = State_TopLevel;
1606
1607 EndCurrentBlock();
1608 return false;
1609 }
1610 _packetType = kRtcpAppItemCode;
1611
1612 if(length > kRtcpAppCode_DATA_SIZE)
1613 {
1614 memcpy(_packet.APP.Data, _ptrRTCPData, kRtcpAppCode_DATA_SIZE);
1615 _packet.APP.Size = kRtcpAppCode_DATA_SIZE;
1616 _ptrRTCPData += kRtcpAppCode_DATA_SIZE;
1617 }else
1618 {
1619 memcpy(_packet.APP.Data, _ptrRTCPData, length);
1620 _packet.APP.Size = (uint16_t)length;
1621 _ptrRTCPData += length;
1622 }
1623 return true;
1624 }
1625
RTCPPacketIterator(uint8_t * rtcpData,size_t rtcpDataLength)1626 RTCPUtility::RTCPPacketIterator::RTCPPacketIterator(uint8_t* rtcpData,
1627 size_t rtcpDataLength)
1628 : _ptrBegin(rtcpData),
1629 _ptrEnd(rtcpData + rtcpDataLength),
1630 _ptrBlock(NULL) {
1631 memset(&_header, 0, sizeof(_header));
1632 }
1633
~RTCPPacketIterator()1634 RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() {
1635 }
1636
1637 const RTCPUtility::RTCPCommonHeader*
Begin()1638 RTCPUtility::RTCPPacketIterator::Begin()
1639 {
1640 _ptrBlock = _ptrBegin;
1641
1642 return Iterate();
1643 }
1644
1645 const RTCPUtility::RTCPCommonHeader*
Iterate()1646 RTCPUtility::RTCPPacketIterator::Iterate()
1647 {
1648 const bool success = RTCPParseCommonHeader(_ptrBlock, _ptrEnd, _header);
1649 if (!success)
1650 {
1651 _ptrBlock = NULL;
1652 return NULL;
1653 }
1654 _ptrBlock += _header.LengthInOctets;
1655
1656 if (_ptrBlock > _ptrEnd)
1657 {
1658 _ptrBlock = NULL;
1659 return NULL;
1660 }
1661
1662 return &_header;
1663 }
1664
1665 const RTCPUtility::RTCPCommonHeader*
Current()1666 RTCPUtility::RTCPPacketIterator::Current()
1667 {
1668 if (!_ptrBlock)
1669 {
1670 return NULL;
1671 }
1672
1673 return &_header;
1674 }
1675 } // namespace webrtc
1676