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