Home | History | Annotate | Download | only in rtcp_packet
      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/app.h"
     12 
     13 #include "webrtc/base/checks.h"
     14 #include "webrtc/base/logging.h"
     15 #include "webrtc/modules/rtp_rtcp/source/byte_io.h"
     16 
     17 using webrtc::RTCPUtility::RtcpCommonHeader;
     18 
     19 namespace webrtc {
     20 namespace rtcp {
     21 
     22 // Application-Defined packet (APP) (RFC 3550).
     23 //
     24 //     0                   1                   2                   3
     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| subtype |   PT=APP=204  |             length            |
     28 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     29 //  0 |                           SSRC/CSRC                           |
     30 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     31 //  4 |                          name (ASCII)                         |
     32 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     33 //  8 |                   application-dependent data                ...
     34 //    +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
     35 bool App::Parse(const RtcpCommonHeader& header, const uint8_t* payload) {
     36   RTC_DCHECK(header.packet_type == kPacketType);
     37 
     38   sub_type_ = header.count_or_format;
     39   ssrc_ = ByteReader<uint32_t>::ReadBigEndian(&payload[0]);
     40   name_ = ByteReader<uint32_t>::ReadBigEndian(&payload[4]);
     41   data_.SetData(&payload[8], header.payload_size_bytes - 8);
     42   return true;
     43 }
     44 
     45 void App::WithSubType(uint8_t subtype) {
     46   RTC_DCHECK_LE(subtype, 0x1f);
     47   sub_type_ = subtype;
     48 }
     49 
     50 void App::WithData(const uint8_t* data, size_t data_length) {
     51   RTC_DCHECK(data);
     52   RTC_DCHECK_EQ(0u, data_length % 4) << "Data must be 32 bits aligned.";
     53   RTC_DCHECK(data_length <= kMaxDataSize) << "App data size << " << data_length
     54                                           << "exceed maximum of "
     55                                           << kMaxDataSize << " bytes.";
     56   data_.SetData(data, data_length);
     57 }
     58 
     59 bool App::Create(uint8_t* packet,
     60                  size_t* index,
     61                  size_t max_length,
     62                  RtcpPacket::PacketReadyCallback* callback) const {
     63   while (*index + BlockLength() > max_length) {
     64     if (!OnBufferFull(packet, index, callback))
     65       return false;
     66   }
     67   const size_t index_end = *index + BlockLength();
     68   CreateHeader(sub_type_, kPacketType, HeaderLength(), packet, index);
     69 
     70   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 0], ssrc_);
     71   ByteWriter<uint32_t>::WriteBigEndian(&packet[*index + 4], name_);
     72   memcpy(&packet[*index + 8], data_.data(), data_.size());
     73   *index += (8 + data_.size());
     74   RTC_DCHECK_EQ(index_end, *index);
     75   return true;
     76 }
     77 
     78 }  // namespace rtcp
     79 }  // namespace webrtc
     80