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