// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef MEDIA_CAST_NET_RTCP_RTCP_UTILITY_H_
#define MEDIA_CAST_NET_RTCP_RTCP_UTILITY_H_

#include <stddef.h>
#include <stdint.h>

#include "base/big_endian.h"
#include "base/macros.h"
#include "media/cast/logging/logging_defines.h"
#include "media/cast/net/cast_transport_config.h"
#include "media/cast/net/rtcp/rtcp_defines.h"

namespace media {
namespace cast {

// RFC 3550 page 44, including end null.
static const size_t kRtcpCnameSize = 256;

static const uint32_t kCast = ('C' << 24) + ('A' << 16) + ('S' << 8) + 'T';

static const uint32_t kCst2 = ('C' << 24) + ('S' << 16) + ('T' << 8) + '2';

static const uint8_t kReceiverLogSubtype = 2;

static const size_t kRtcpMaxReceiverLogMessages = 256;
static const size_t kRtcpMaxCastLossFields = 100;

struct RtcpCommonHeader {
  uint8_t V;   // Version.
  bool P;    // Padding.
  uint8_t IC;  // Item count / subtype.
  uint8_t PT;  // Packet Type.
  size_t length_in_octets;
};

class RtcpParser {
 public:
  RtcpParser(uint32_t local_ssrc, uint32_t remote_ssrc);
  ~RtcpParser();

  // Gets/Sets the ID of the latest frame that could possibly be ACK'ed.  This
  // is used when expanding truncated frame IDs during Parse().  This only needs
  // to be called if the client uses cast_message().
  FrameId max_valid_frame_id() const { return max_valid_frame_id_; }
  void SetMaxValidFrameId(FrameId max_valid_frame_id);

  // Parse the RTCP packet.
  bool Parse(base::BigEndianReader* reader);

  bool has_sender_report() const { return has_sender_report_; }
  const RtcpSenderInfo& sender_report() const {
    return sender_report_;
  }

  bool has_last_report() const { return has_last_report_; }
  uint32_t last_report() const { return last_report_; }
  uint32_t delay_since_last_report() const { return delay_since_last_report_; }

  bool has_receiver_log() const { return !receiver_log_.empty(); }
  const RtcpReceiverLogMessage& receiver_log() const { return receiver_log_; }
  RtcpReceiverLogMessage* mutable_receiver_log() { return & receiver_log_; }

  bool has_cast_message() const { return has_cast_message_; }
  const RtcpCastMessage& cast_message() const { return cast_message_; }
  RtcpCastMessage* mutable_cast_message() { return &cast_message_; }
  // Return if successfully parsed the extended feedback.
  bool has_cst2_message() const { return has_cst2_message_; }

  bool has_receiver_reference_time_report() const {
    return has_receiver_reference_time_report_;
  }
  const RtcpReceiverReferenceTimeReport&
  receiver_reference_time_report() const {
    return receiver_reference_time_report_;
  }

  bool has_picture_loss_indicator() const {
    return has_picture_loss_indicator_;
  }

 private:
  bool ParseCommonHeader(base::BigEndianReader* reader,
                         RtcpCommonHeader* parsed_header);
  bool ParseSR(base::BigEndianReader* reader, const RtcpCommonHeader& header);
  bool ParseRR(base::BigEndianReader* reader, const RtcpCommonHeader& header);
  bool ParseReportBlock(base::BigEndianReader* reader);
  bool ParsePli(base::BigEndianReader* reader, const RtcpCommonHeader& header);
  bool ParseApplicationDefined(base::BigEndianReader* reader,
                               const RtcpCommonHeader& header);
  bool ParseCastReceiverLogFrameItem(base::BigEndianReader* reader);
  bool ParseFeedbackCommon(base::BigEndianReader* reader,
                           const RtcpCommonHeader& header);
  bool ParseExtendedReport(base::BigEndianReader* reader,
                           const RtcpCommonHeader& header);
  bool ParseExtendedReportReceiverReferenceTimeReport(
      base::BigEndianReader* reader,
      uint32_t remote_ssrc);
  bool ParseExtendedReportDelaySinceLastReceiverReport(
      base::BigEndianReader* reader);

  const uint32_t local_ssrc_;
  const uint32_t remote_ssrc_;

  bool has_sender_report_;
  RtcpSenderInfo sender_report_;

  uint32_t last_report_;
  uint32_t delay_since_last_report_;
  bool has_last_report_;

  // |receiver_log_| is a vector vector, no need for has_*.
  RtcpReceiverLogMessage receiver_log_;

  bool has_cast_message_;
  RtcpCastMessage cast_message_;
  bool has_cst2_message_;

  bool has_receiver_reference_time_report_;
  RtcpReceiverReferenceTimeReport receiver_reference_time_report_;

  // Tracks recently-parsed RTP timestamps so that the truncated values can be
  // re-expanded into full-form.
  RtpTimeTicks last_parsed_sr_rtp_timestamp_;
  RtpTimeTicks last_parsed_frame_log_rtp_timestamp_;

  // The maximum possible re-expanded frame ID value.
  FrameId max_valid_frame_id_;

  // Indicates if sender received the Pli message from the receiver.
  bool has_picture_loss_indicator_;

  DISALLOW_COPY_AND_ASSIGN(RtcpParser);
};

// Converts a log event type to an integer value.
// NOTE: We have only allocated 4 bits to represent the type of event over the
// wire. Therefore, this function can only return values from 0 to 15.
uint8_t ConvertEventTypeToWireFormat(CastLoggingEvent event);

// The inverse of |ConvertEventTypeToWireFormat()|.
CastLoggingEvent TranslateToLogEventFromWireFormat(uint8_t event);

// Splits an NTP timestamp having a microsecond timebase into the standard two
// 32-bit integer wire format.
void ConvertTimeToFractions(int64_t ntp_time_us,
                            uint32_t* seconds,
                            uint32_t* fractions);

// Maps a base::TimeTicks value to an NTP timestamp comprised of two components.
void ConvertTimeTicksToNtp(const base::TimeTicks& time,
                           uint32_t* ntp_seconds,
                           uint32_t* ntp_fractions);

// Create a NTP diff from seconds and fractions of seconds; delay_fraction is
// fractions of a second where 0x80000000 is half a second.
uint32_t ConvertToNtpDiff(uint32_t delay_seconds, uint32_t delay_fraction);

// Maps an NTP timestamp, comprised of two components, to a base::TimeTicks
// value.
base::TimeTicks ConvertNtpToTimeTicks(uint32_t ntp_seconds,
                                      uint32_t ntp_fractions);

bool IsRtcpPacket(const uint8_t* packet, size_t length);

uint32_t GetSsrcOfSender(const uint8_t* rtcp_buffer, size_t length);

}  // namespace cast
}  // namespace media

#endif  // MEDIA_CAST_NET_RTCP_RTCP_UTILITY_H_
