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