Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 /* | |
| 2 * Copyright (c) 2015 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_packet/bye.h" | |
| 12 | |
| 13 #include "webrtc/base/checks.h" | |
| 14 #include "webrtc/base/logging.h" | |
| 15 #include "webrtc/modules/rtp_rtcp/source/rtp_utility.h" | |
| 16 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" | |
|
åsapersson
2015/11/20 09:44:58
alphabetic order
danilchap
2015/11/20 11:03:21
Done.
| |
| 17 | |
| 18 using webrtc::RTCPUtility::RtcpCommonHeader; | |
| 19 | |
| 20 namespace webrtc { | |
| 21 namespace rtcp { | |
| 22 | |
| 23 // Bye packet (BYE) (RFC 3550). | |
| 24 // | |
| 25 // 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 | |
| 26 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 27 // |V=2|P| SC | PT=BYE=203 | length | | |
| 28 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 29 // | SSRC/CSRC | | |
| 30 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 31 // : ... : | |
| 32 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ | |
| 33 // (opt) | length | reason for leaving ... | |
| 34 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | |
| 35 Bye::Bye() : sender_ssrc_(0) {} | |
| 36 | |
| 37 bool Bye::Parse(const RtcpCommonHeader& header, const uint8_t* payload) { | |
| 38 RTC_DCHECK(header.packet_type == kPacketType); | |
| 39 | |
| 40 const uint8_t src_count = header.count_or_format; | |
| 41 // Validate packet. | |
| 42 if (src_count == 0) { | |
| 43 LOG(LS_WARNING) << "Bye packet must contain SSRC."; | |
|
åsapersson
2015/11/20 09:44:58
I think a SC value of zero is valid.
danilchap
2015/11/20 11:03:21
Yes, "A count value of zero is valid, but useless.
| |
| 44 return false; | |
| 45 } | |
| 46 if (header.payload_size_bytes < 4u * src_count) { | |
| 47 LOG(LS_WARNING) | |
| 48 << "Packet is too small to contain CSRCs it promise to have."; | |
| 49 return false; | |
| 50 } | |
| 51 bool has_reason = (header.payload_size_bytes > 4u * src_count); | |
| 52 uint8_t reason_length; | |
|
åsapersson
2015/11/20 09:44:58
initialize to 0 and remove else?
danilchap
2015/11/20 11:03:21
Wasn't sure if logic 'assign to correct value as s
| |
| 53 if (has_reason) { | |
| 54 reason_length = payload[4u * src_count]; | |
| 55 if (header.payload_size_bytes - 4u * src_count < 1u + reason_length) { | |
| 56 LOG(LS_WARNING) << "Invalid reason length: " << reason_length; | |
| 57 return false; | |
| 58 } | |
| 59 } else { | |
| 60 reason_length = 0; | |
| 61 } | |
| 62 // Once sure packet is valid, copy values. | |
| 63 sender_ssrc_ = ByteReader<uint32_t>::ReadBigEndian(payload); | |
| 64 csrcs_.resize(src_count - 1); | |
| 65 for (size_t i = 1; i < src_count; ++i) | |
| 66 csrcs_[i - 1] = ByteReader<uint32_t>::ReadBigEndian(&payload[4 * i]); | |
| 67 | |
| 68 if (has_reason) { | |
| 69 reason_.assign(reinterpret_cast<const char*>(&payload[4u * src_count + 1]), | |
| 70 reason_length); | |
| 71 } else { | |
| 72 reason_.clear(); | |
| 73 } | |
| 74 | |
| 75 return true; | |
| 76 } | |
| 77 | |
| 78 bool Bye::Create(uint8_t* packet, | |
| 79 size_t* index, | |
| 80 size_t max_length, | |
| 81 RtcpPacket::PacketReadyCallback* callback) const { | |
| 82 while (*index + BlockLength() > max_length) { | |
| 83 if (!OnBufferFull(packet, index, callback)) | |
| 84 return false; | |
| 85 } | |
| 86 const size_t index_end = *index + BlockLength(); | |
| 87 RTC_DCHECK_EQ(0u, BlockLength() % 4u); | |
| 88 size_t size_in_32bits = (BlockLength() - kHeaderLength) / 4u; | |
|
åsapersson
2015/11/20 09:44:58
Can use HeaderLength() instead?
danilchap
2015/11/20 11:03:21
Done.
| |
| 89 | |
| 90 CreateHeader(1 + csrcs_.size(), kPacketType, size_in_32bits, packet, index); | |
| 91 // Store srcs of the leaving clients. | |
| 92 ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], sender_ssrc_); | |
| 93 *index += sizeof(uint32_t); | |
| 94 for (uint32_t csrc : csrcs_) { | |
| 95 ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], csrc); | |
| 96 *index += sizeof(uint32_t); | |
| 97 } | |
| 98 // Store the reason to leave. | |
| 99 if (!reason_.empty()) { | |
| 100 uint8_t reason_length = reason_.size(); | |
| 101 packet[(*index)++] = reason_length; | |
| 102 memcpy(&packet[*index], reason_.data(), reason_length); | |
| 103 *index += reason_length; | |
| 104 // Add padding bytes if needed. | |
| 105 size_t bytes_to_pad = index_end - *index; | |
| 106 RTC_DCHECK_LE(bytes_to_pad, 3u); | |
| 107 if (bytes_to_pad > 0) { | |
| 108 memset(&packet[*index], 0, bytes_to_pad); | |
| 109 *index += bytes_to_pad; | |
| 110 } | |
| 111 } | |
| 112 RTC_DCHECK_EQ(index_end, *index); | |
| 113 return true; | |
| 114 } | |
| 115 | |
| 116 bool Bye::WithCsrc(uint32_t csrc) { | |
| 117 if (csrcs_.size() >= kMaxNumberOfCsrcs) { | |
| 118 LOG(LS_WARNING) << "Max CSRC size reached."; | |
| 119 return false; | |
| 120 } | |
| 121 csrcs_.push_back(csrc); | |
| 122 return true; | |
| 123 } | |
| 124 | |
| 125 bool Bye::WithReason(const std::string& reason) { | |
| 126 if (reason.size() > 0xff) { | |
|
åsapersson
2015/11/20 09:44:58
should we use RTC_DCHECK
danilchap
2015/11/20 11:03:21
Done.
| |
| 127 LOG(LS_WARNING) << "Reason length should be less than 256."; | |
| 128 return false; | |
| 129 } | |
| 130 reason_ = reason; | |
| 131 return true; | |
| 132 } | |
| 133 | |
| 134 size_t Bye::BlockLength() const { | |
| 135 size_t source_count = (1 + csrcs_.size()); | |
|
åsapersson
2015/11/20 09:44:58
maybe use same name for source count in Parse and
danilchap
2015/11/20 11:03:21
Done.
| |
| 136 size_t reason_size_in_32bits = reason_.empty() ? 0 : (reason_.size() / 4 + 1); | |
| 137 return kHeaderLength + 4 * (source_count + reason_size_in_32bits); | |
| 138 } | |
| 139 | |
| 140 } // namespace rtcp | |
| 141 } // namespace webrtc | |
| OLD | NEW |