• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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