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
17namespace webrtc {
18
19namespace RTCPUtility {
20uint32_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
26RTCPUtility::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
41RTCPUtility::RTCPParserV2::~RTCPParserV2() {
42}
43
44ptrdiff_t
45RTCPUtility::RTCPParserV2::LengthLeft() const
46{
47    return (_ptrRTCPDataEnd- _ptrRTCPData);
48}
49
50RTCPUtility::RTCPPacketTypes
51RTCPUtility::RTCPParserV2::PacketType() const
52{
53    return _packetType;
54}
55
56const RTCPUtility::RTCPPacket&
57RTCPUtility::RTCPParserV2::Packet() const
58{
59    return _packet;
60}
61
62RTCPUtility::RTCPPacketTypes
63RTCPUtility::RTCPParserV2::Begin()
64{
65    _ptrRTCPData = _ptrRTCPDataBegin;
66
67    return Iterate();
68}
69
70RTCPUtility::RTCPPacketTypes
71RTCPUtility::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
136void
137RTCPUtility::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
243void
244RTCPUtility::RTCPParserV2::IterateXrItem()
245{
246    const bool success = ParseXrItem();
247    if (!success)
248    {
249        Iterate();
250    }
251}
252
253void
254RTCPUtility::RTCPParserV2::IterateXrDlrrItem()
255{
256    const bool success = ParseXrDlrrItem();
257    if (!success)
258    {
259        Iterate();
260    }
261}
262
263void
264RTCPUtility::RTCPParserV2::IterateReportBlockItem()
265{
266    const bool success = ParseReportBlockItem();
267    if (!success)
268    {
269        Iterate();
270    }
271}
272
273void
274RTCPUtility::RTCPParserV2::IterateSDESChunk()
275{
276    const bool success = ParseSDESChunk();
277    if (!success)
278    {
279        Iterate();
280    }
281}
282
283void
284RTCPUtility::RTCPParserV2::IterateBYEItem()
285{
286    const bool success = ParseBYEItem();
287    if (!success)
288    {
289        Iterate();
290    }
291}
292
293void
294RTCPUtility::RTCPParserV2::IterateExtendedJitterItem()
295{
296    const bool success = ParseIJItem();
297    if (!success)
298    {
299        Iterate();
300    }
301}
302
303void
304RTCPUtility::RTCPParserV2::IterateNACKItem()
305{
306    const bool success = ParseNACKItem();
307    if (!success)
308    {
309        Iterate();
310    }
311}
312
313void
314RTCPUtility::RTCPParserV2::IterateTMMBRItem()
315{
316    const bool success = ParseTMMBRItem();
317    if (!success)
318    {
319        Iterate();
320    }
321}
322
323void
324RTCPUtility::RTCPParserV2::IterateTMMBNItem()
325{
326    const bool success = ParseTMMBNItem();
327    if (!success)
328    {
329        Iterate();
330    }
331}
332
333void
334RTCPUtility::RTCPParserV2::IterateSLIItem()
335{
336    const bool success = ParseSLIItem();
337    if (!success)
338    {
339        Iterate();
340    }
341}
342
343void
344RTCPUtility::RTCPParserV2::IterateRPSIItem()
345{
346    const bool success = ParseRPSIItem();
347    if (!success)
348    {
349        Iterate();
350    }
351}
352
353void
354RTCPUtility::RTCPParserV2::IterateFIRItem()
355{
356    const bool success = ParseFIRItem();
357    if (!success)
358    {
359        Iterate();
360    }
361}
362
363void
364RTCPUtility::RTCPParserV2::IteratePsfbAppItem()
365{
366    const bool success = ParsePsfbAppItem();
367    if (!success)
368    {
369        Iterate();
370    }
371}
372
373void
374RTCPUtility::RTCPParserV2::IteratePsfbREMBItem()
375{
376    const bool success = ParsePsfbREMBItem();
377    if (!success)
378    {
379        Iterate();
380    }
381}
382
383void
384RTCPUtility::RTCPParserV2::IterateAppItem()
385{
386    const bool success = ParseAPPItem();
387    if (!success)
388    {
389        Iterate();
390    }
391}
392
393void
394RTCPUtility::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
432bool
433RTCPUtility::RTCPParserV2::IsValid() const
434{
435    return _validPacket;
436}
437
438void
439RTCPUtility::RTCPParserV2::EndCurrentBlock()
440{
441    _ptrRTCPData = _ptrRTCPBlockEnd;
442}
443
444bool
445RTCPUtility::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
488bool
489RTCPUtility::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
516bool
517RTCPUtility::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
576bool
577RTCPUtility::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
639bool
640RTCPUtility::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
658bool
659RTCPUtility::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
680bool
681RTCPUtility::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
699bool
700RTCPUtility::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
741bool
742RTCPUtility::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
813bool
814RTCPUtility::RTCPParserV2::ParseBYE()
815{
816    _ptrRTCPData += 4; // Skip header
817
818    _state = State_BYEItem;
819
820    return ParseBYEItem();
821}
822
823bool
824RTCPUtility::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*/
864bool 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*/
897bool 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*/
935bool 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*/
979bool 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
993bool 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
1050bool 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
1108bool 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
1123bool
1124RTCPUtility::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
1269bool 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
1309bool
1310RTCPUtility::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
1335bool
1336RTCPUtility::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
1380bool
1381RTCPUtility::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
1424bool
1425RTCPUtility::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
1463bool
1464RTCPUtility::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
1502bool
1503RTCPUtility::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
1538bool
1539RTCPUtility::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
1565bool
1566RTCPUtility::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
1599bool
1600RTCPUtility::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
1626RTCPUtility::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
1634RTCPUtility::RTCPPacketIterator::~RTCPPacketIterator() {
1635}
1636
1637const RTCPUtility::RTCPCommonHeader*
1638RTCPUtility::RTCPPacketIterator::Begin()
1639{
1640    _ptrBlock = _ptrBegin;
1641
1642    return Iterate();
1643}
1644
1645const RTCPUtility::RTCPCommonHeader*
1646RTCPUtility::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
1665const RTCPUtility::RTCPCommonHeader*
1666RTCPUtility::RTCPPacketIterator::Current()
1667{
1668    if (!_ptrBlock)
1669    {
1670        return NULL;
1671    }
1672
1673    return &_header;
1674}
1675}  // namespace webrtc
1676