|  | /* | 
|  | *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #include "webrtc/base/checks.h" | 
|  | #include "webrtc/base/logging.h" | 
|  | #include "webrtc/test/rtcp_packet_parser.h" | 
|  |  | 
|  | namespace webrtc { | 
|  | namespace test { | 
|  |  | 
|  | RtcpPacketParser::RtcpPacketParser() = default; | 
|  | RtcpPacketParser::~RtcpPacketParser() = default; | 
|  |  | 
|  | bool RtcpPacketParser::Parse(const void* data, size_t length) { | 
|  | const uint8_t* const buffer = static_cast<const uint8_t*>(data); | 
|  | const uint8_t* const buffer_end = buffer + length; | 
|  | rtcp::CommonHeader header; | 
|  | for (const uint8_t* next_packet = buffer; next_packet != buffer_end; | 
|  | next_packet = header.NextPacket()) { | 
|  | RTC_DCHECK_GT(buffer_end - next_packet, 0); | 
|  | if (!header.Parse(next_packet, buffer_end - next_packet)) { | 
|  | LOG(LS_WARNING) | 
|  | << "Invalid rtcp header or unaligned rtcp packet at position " | 
|  | << (next_packet - buffer); | 
|  | return false; | 
|  | } | 
|  | switch (header.type()) { | 
|  | case rtcp::App::kPacketType: | 
|  | app_.Parse(header); | 
|  | break; | 
|  | case rtcp::Bye::kPacketType: | 
|  | bye_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::ExtendedReports::kPacketType: | 
|  | xr_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::ExtendedJitterReport::kPacketType: | 
|  | ij_.Parse(header); | 
|  | break; | 
|  | case rtcp::Psfb::kPacketType: | 
|  | switch (header.fmt()) { | 
|  | case rtcp::Fir::kFeedbackMessageType: | 
|  | fir_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::Pli::kFeedbackMessageType: | 
|  | pli_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::Remb::kFeedbackMessageType: | 
|  | remb_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::Rpsi::kFeedbackMessageType: | 
|  | rpsi_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::Sli::kFeedbackMessageType: | 
|  | sli_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | default: | 
|  | LOG(LS_WARNING) << "Unknown rtcp payload specific feedback type " | 
|  | << header.fmt(); | 
|  | break; | 
|  | } | 
|  | break; | 
|  | case rtcp::ReceiverReport::kPacketType: | 
|  | receiver_report_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::Rtpfb::kPacketType: | 
|  | switch (header.fmt()) { | 
|  | case rtcp::Nack::kFeedbackMessageType: | 
|  | nack_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::RapidResyncRequest::kFeedbackMessageType: | 
|  | rrr_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::Tmmbn::kFeedbackMessageType: | 
|  | tmmbn_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::Tmmbr::kFeedbackMessageType: | 
|  | tmmbr_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | case rtcp::TransportFeedback::kFeedbackMessageType: | 
|  | transport_feedback_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | default: | 
|  | LOG(LS_WARNING) << "Unknown rtcp transport feedback type " | 
|  | << header.fmt(); | 
|  | break; | 
|  | } | 
|  | break; | 
|  | case rtcp::Sdes::kPacketType: | 
|  | sdes_.Parse(header); | 
|  | break; | 
|  | case rtcp::SenderReport::kPacketType: | 
|  | sender_report_.Parse(header, &sender_ssrc_); | 
|  | break; | 
|  | default: | 
|  | LOG(LS_WARNING) << "Unknown rtcp packet type " << header.type(); | 
|  | break; | 
|  | } | 
|  | } | 
|  | return true; | 
|  | } | 
|  |  | 
|  | }  // namespace test | 
|  | }  // namespace webrtc |