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