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" | |
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() : RtcpPacket(), sender_ssrc_(0) {} | |
sprang_webrtc
2015/11/12 16:28:31
Don't think you explicit RtcpPacket() call?
danilchap
2015/11/13 09:05:42
Wasn't sure what style is preferred, so left like
| |
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 should have at least 1 src"; | |
sprang_webrtc
2015/11/12 16:28:31
Bye packet must contain SSRC.
danilchap
2015/11/13 09:05:42
Done.
| |
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; | |
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) << "Reason length is unreasonable"; | |
sprang_webrtc
2015/11/12 16:28:31
"Invalid reason length: " << reason_length;
danilchap
2015/11/13 09:05:42
Done.
| |
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(); | |
sprang_webrtc
2015/11/12 16:28:31
Use brackets:
if () {
...
} else {
...
}
danilchap
2015/11/13 09:05:42
Done.
| |
73 | |
74 return true; | |
75 } | |
76 | |
77 bool Bye::Create(uint8_t* packet, | |
78 size_t* index, | |
79 size_t max_length, | |
80 RtcpPacket::PacketReadyCallback* callback) const { | |
81 while (*index + BlockLength() > max_length) { | |
82 if (!OnBufferFull(packet, index, callback)) | |
83 return false; | |
84 } | |
85 const size_t index_end = *index + BlockLength(); | |
86 RTC_DCHECK_EQ(0u, BlockLength() % 4u); | |
87 size_t size_in_32bits = (BlockLength() - kHeaderLength) / 4u; | |
88 | |
89 CreateHeader(1 + csrcs_.size(), kPacketType, size_in_32bits, packet, index); | |
90 // Store srcs of the leaving clients. | |
91 ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], sender_ssrc_); | |
92 *index += sizeof(uint32_t); | |
93 for (uint32_t csrc : csrcs_) { | |
94 ByteWriter<uint32_t>::WriteBigEndian(&packet[*index], csrc); | |
95 *index += sizeof(uint32_t); | |
96 } | |
97 // Store the reason to leave. | |
98 if (!reason_.empty()) { | |
99 uint8_t reason_length = reason_.size(); | |
100 packet[(*index)++] = reason_length; | |
101 memcpy(&packet[*index], reason_.data(), reason_length); | |
102 *index += reason_length; | |
103 // Add padding bytes if needed. | |
104 size_t bytes_to_pad = index_end - *index; | |
105 RTC_DCHECK_LE(bytes_to_pad, 3u); | |
106 if (bytes_to_pad > 0) { | |
107 memset(&packet[*index], 0, bytes_to_pad); | |
108 *index += bytes_to_pad; | |
109 } | |
110 } | |
111 RTC_DCHECK_EQ(index_end, *index); | |
112 return true; | |
113 } | |
114 | |
115 bool Bye::WithCsrc(uint32_t csrc) { | |
116 if (csrcs_.size() >= kMaxNumberOfCsrcs) { | |
117 LOG(LS_WARNING) << "Max CSRC size reached."; | |
118 return false; | |
119 } | |
120 csrcs_.push_back(csrc); | |
121 return true; | |
122 } | |
123 | |
124 bool Bye::WithReason(const std::string& reason) { | |
125 if (reason.size() > 0xff) { | |
126 LOG(LS_WARNING) << "Reason length should fit in one byte," | |
127 " i.e. be less than 256"; | |
128 return false; | |
129 } | |
130 reason_ = reason; | |
131 return true; | |
132 } | |
133 | |
134 } // namespace rtcp | |
135 } // namespace webrtc | |
OLD | NEW |