OLD | NEW |
(Empty) | |
| 1 /* |
| 2 * Copyright (c) 2016 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/sdes.h" |
| 12 |
| 13 #include "webrtc/base/logging.h" |
| 14 #include "webrtc/modules/rtp_rtcp/source/byte_io.h" |
| 15 |
| 16 using webrtc::RTCPUtility::PT_SDES; |
| 17 |
| 18 namespace webrtc { |
| 19 namespace rtcp { |
| 20 namespace { |
| 21 void AssignUWord8(uint8_t* buffer, size_t* offset, uint8_t value) { |
| 22 buffer[(*offset)++] = value; |
| 23 } |
| 24 |
| 25 void AssignUWord32(uint8_t* buffer, size_t* offset, uint32_t value) { |
| 26 ByteWriter<uint32_t>::WriteBigEndian(buffer + *offset, value); |
| 27 *offset += 4; |
| 28 } |
| 29 // Source Description (SDES) (RFC 3550). |
| 30 // |
| 31 // 0 1 2 3 |
| 32 // 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 |
| 33 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 34 // header |V=2|P| SC | PT=SDES=202 | length | |
| 35 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 36 // chunk | SSRC/CSRC_1 | |
| 37 // 1 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 38 // | SDES items | |
| 39 // | ... | |
| 40 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 41 // chunk | SSRC/CSRC_2 | |
| 42 // 2 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 43 // | SDES items | |
| 44 // | ... | |
| 45 // +=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+=+ |
| 46 // |
| 47 // Canonical End-Point Identifier SDES Item (CNAME) |
| 48 // |
| 49 // 0 1 2 3 |
| 50 // 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 |
| 51 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 52 // | CNAME=1 | length | user and domain name ... |
| 53 // +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ |
| 54 void CreateSdes(const std::vector<Sdes::Chunk>& chunks, |
| 55 uint8_t* buffer, |
| 56 size_t* pos) { |
| 57 const uint8_t kSdesItemType = 1; |
| 58 for (std::vector<Sdes::Chunk>::const_iterator it = chunks.begin(); |
| 59 it != chunks.end(); ++it) { |
| 60 AssignUWord32(buffer, pos, (*it).ssrc); |
| 61 AssignUWord8(buffer, pos, kSdesItemType); |
| 62 AssignUWord8(buffer, pos, (*it).name.length()); |
| 63 memcpy(buffer + *pos, (*it).name.data(), (*it).name.length()); |
| 64 *pos += (*it).name.length(); |
| 65 memset(buffer + *pos, 0, (*it).null_octets); |
| 66 *pos += (*it).null_octets; |
| 67 } |
| 68 } |
| 69 } // namespace |
| 70 |
| 71 bool Sdes::Create(uint8_t* packet, |
| 72 size_t* index, |
| 73 size_t max_length, |
| 74 RtcpPacket::PacketReadyCallback* callback) const { |
| 75 assert(!chunks_.empty()); |
| 76 while (*index + BlockLength() > max_length) { |
| 77 if (!OnBufferFull(packet, index, callback)) |
| 78 return false; |
| 79 } |
| 80 CreateHeader(chunks_.size(), PT_SDES, HeaderLength(), packet, index); |
| 81 CreateSdes(chunks_, packet, index); |
| 82 return true; |
| 83 } |
| 84 |
| 85 bool Sdes::WithCName(uint32_t ssrc, const std::string& cname) { |
| 86 assert(cname.length() <= 0xff); |
| 87 if (chunks_.size() >= kMaxNumberOfChunks) { |
| 88 LOG(LS_WARNING) << "Max SDES chunks reached."; |
| 89 return false; |
| 90 } |
| 91 // In each chunk, the list of items must be terminated by one or more null |
| 92 // octets. The next chunk must start on a 32-bit boundary. |
| 93 // CNAME (1 byte) | length (1 byte) | name | padding. |
| 94 int null_octets = 4 - ((2 + cname.length()) % 4); |
| 95 Chunk chunk; |
| 96 chunk.ssrc = ssrc; |
| 97 chunk.name = cname; |
| 98 chunk.null_octets = null_octets; |
| 99 chunks_.push_back(chunk); |
| 100 return true; |
| 101 } |
| 102 |
| 103 size_t Sdes::BlockLength() const { |
| 104 // Header (4 bytes). |
| 105 // Chunk: |
| 106 // SSRC/CSRC (4 bytes) | CNAME (1 byte) | length (1 byte) | name | padding. |
| 107 size_t length = kHeaderLength; |
| 108 for (const Chunk& chunk : chunks_) |
| 109 length += 6 + chunk.name.length() + chunk.null_octets; |
| 110 assert(length % 4 == 0); |
| 111 return length; |
| 112 } |
| 113 } // namespace rtcp |
| 114 } // namespace webrtc |
OLD | NEW |