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