blob: ecce5ef34c5e7c3dc10bb67134ef612638ba4ef4 [file] [log] [blame]
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +00001/*
2 * Copyright (c) 2014 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
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020011#include "modules/rtp_rtcp/source/rtcp_packet.h"
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000012
Danil Chapovalov5c3cc412017-12-07 10:15:53 +010013#include "modules/rtp_rtcp/include/rtp_rtcp_defines.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020014#include "rtc_base/checks.h"
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000015
16namespace webrtc {
17namespace rtcp {
danilchapc1f40b72016-10-17 01:44:44 -070018constexpr size_t RtcpPacket::kHeaderLength;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000019
danilchap69e59e62016-02-17 03:11:42 -080020rtc::Buffer RtcpPacket::Build() const {
danilchapc1f40b72016-10-17 01:44:44 -070021 rtc::Buffer packet(BlockLength());
22
asapersson@webrtc.org4b12d402014-06-16 14:09:28 +000023 size_t length = 0;
danilchapc1f40b72016-10-17 01:44:44 -070024 bool created = Create(packet.data(), &length, packet.capacity(), nullptr);
25 RTC_DCHECK(created) << "Invalid packet is not supported.";
26 RTC_DCHECK_EQ(length, packet.size())
27 << "BlockLength mispredicted size used by Create";
Erik Språngc1b9d4e2015-06-08 09:54:14 +020028
Erik Språngc1b9d4e2015-06-08 09:54:14 +020029 return packet;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000030}
31
Danil Chapovalov5c3cc412017-12-07 10:15:53 +010032bool RtcpPacket::Build(size_t max_length, PacketReadyCallback callback) const {
33 RTC_CHECK_LE(max_length, IP_PACKET_SIZE);
34 uint8_t buffer[IP_PACKET_SIZE];
Erik Språngc1b9d4e2015-06-08 09:54:14 +020035 size_t index = 0;
danilchap7a4116a2016-03-14 08:19:28 -070036 if (!Create(buffer, &index, max_length, callback))
Erik Språngc1b9d4e2015-06-08 09:54:14 +020037 return false;
38 return OnBufferFull(buffer, &index, callback);
39}
40
Erik Språngc1b9d4e2015-06-08 09:54:14 +020041bool RtcpPacket::OnBufferFull(uint8_t* packet,
42 size_t* index,
Danil Chapovalov5c3cc412017-12-07 10:15:53 +010043 PacketReadyCallback callback) const {
Erik Språngc1b9d4e2015-06-08 09:54:14 +020044 if (*index == 0)
45 return false;
danilchapc1f40b72016-10-17 01:44:44 -070046 RTC_DCHECK(callback) << "Fragmentation not supported.";
Danil Chapovalov5c3cc412017-12-07 10:15:53 +010047 callback(rtc::ArrayView<const uint8_t>(packet, *index));
Erik Språngc1b9d4e2015-06-08 09:54:14 +020048 *index = 0;
49 return true;
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000050}
51
Erik Språnga3b87692015-07-29 10:46:54 +020052size_t RtcpPacket::HeaderLength() const {
53 size_t length_in_bytes = BlockLength();
kwibergaf476c72016-11-28 15:21:39 -080054 RTC_DCHECK_GT(length_in_bytes, 0);
55 RTC_DCHECK_EQ(length_in_bytes % 4, 0) << "Padding not supported";
danilchapc1f40b72016-10-17 01:44:44 -070056 // Length in 32-bit words without common header.
57 return (length_in_bytes - kHeaderLength) / 4;
Erik Språnga3b87692015-07-29 10:46:54 +020058}
59
60// From RFC 3550, RTP: A Transport Protocol for Real-Time Applications.
61//
62// RTP header format.
63// 0 1 2 3
64// 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
65// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
66// |V=2|P| RC/FMT | PT | length |
67// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Erik Språnga3b87692015-07-29 10:46:54 +020068void RtcpPacket::CreateHeader(
Danil Chapovalov6c170572017-09-15 16:48:14 +020069 size_t count_or_format, // Depends on packet type.
Erik Språnga3b87692015-07-29 10:46:54 +020070 uint8_t packet_type,
71 size_t length,
72 uint8_t* buffer,
sprang73a93e82015-09-14 12:50:39 -070073 size_t* pos) {
danilchapc1f40b72016-10-17 01:44:44 -070074 RTC_DCHECK_LE(length, 0xffffU);
75 RTC_DCHECK_LE(count_or_format, 0x1f);
76 constexpr uint8_t kVersionBits = 2 << 6;
77 constexpr uint8_t kNoPaddingBit = 0 << 5;
Danil Chapovalov6c170572017-09-15 16:48:14 +020078 buffer[*pos + 0] = kVersionBits | kNoPaddingBit |
79 static_cast<uint8_t>(count_or_format);
danilchapc1f40b72016-10-17 01:44:44 -070080 buffer[*pos + 1] = packet_type;
81 buffer[*pos + 2] = (length >> 8) & 0xff;
82 buffer[*pos + 3] = length & 0xff;
83 *pos += kHeaderLength;
Erik Språnga3b87692015-07-29 10:46:54 +020084}
85
asapersson@webrtc.org0f2809a2014-02-21 08:14:45 +000086} // namespace rtcp
87} // namespace webrtc