// Copyright (C) 2002 Federico Montesino Pouzols <fedemp@altern.org>.
//
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
//
// As a special exception, you may use this file as part of a free software
// library without restriction.  Specifically, if other files instantiate
// templates or use macros or inline functions from this file, or you compile
// this file and link it with other files to produce an executable, this
// file does not by itself cause the resulting executable to be covered by
// the GNU General Public License.  This exception does not however
// invalidate any other reasons why the executable file might be covered by
// the GNU General Public License.
//
// This exception applies only to the code released under the name GNU
// ccRTP.  If you copy code from other releases into a copy of GNU
// ccRTP, as the General Public License permits, the exception does
// not apply to the code that you add in this way.  To avoid misleading
// anyone as to the status of such modified files, you must delete
// this exception notice from them.
//
// If you write modifications of your own for GNU ccRTP, it is your choice
// whether to permit this exception to apply to your modifications.
// If you do not wish that, delete this exception notice.
//

#ifndef CCXX_RTP_RTPPKT_H_
#define CCXX_RTP_RTPPKT_H_

#include <ccrtp/base.h>
#include <ccrtp/formats.h>
#include <ccrtp/CryptoContext.h>

NAMESPACE_COMMONCPP

/**
 * @file rtppkt.h
 *
 * @short RTP packets handling.
 **/

/**
 * @defgroup rtppacket RTP data packets manipulation.
 * @{
 **/

/**
 * @class RTPPacket
 * @short A base class for both IncomingRTPPkt and OutgoingRTPPkt.
 *
 * Provides common low level header structures and related
 * methods. This class provides an interface that allows for partial
 * and generic manipulation of RTP data packets. Values are returned
 * in host order, except raw structures, which are returned as they
 * are sent through the network.
 *
 * @author David Sugar <dyfet@ostel.com>
 **/

class CryptoContext;

class  __EXPORT RTPPacket
{
private:
    struct RTPFixedHeader;
    struct RTPHeaderExt;

public:
    /**
     * Constructor, construct a packet object given the memory
     * zone its content (header and payload) is stored. Commonly
     * used to build RTPPacket objects from incoming data.
     *
     * @param block whole packet
     * @param len total length (header + payload + padding) of the
     *        packet
     * @param duplicate whether to memcopy the packet. At present,
     *        this feature is not used.
     * @note used in IncomingRTPPkt.
     **/
    RTPPacket(const unsigned char* const block, size_t len,
          bool duplicate = false);

    /**
     * Construct a packet object without specifying its real
     * content yet. Commonly used for outgoing packets. Header
     * fields and payload must be filled in by another methods or
     * by a derived constructor.
     *
     * @param hdrlen length of the header (including CSRC and extension).
     * @param plen payload length.
     * @param paddinglen pad packet to a multiple of paddinglen
     * @note used in OutgoingRTPPkt.
     */
        RTPPacket(size_t hdrlen, size_t plen, uint8 paddinglen, CryptoContext* pcc= NULL);

    /**
     * Get the length of the header, including contributing
     * sources identifiers and header extension, if present.
     *
     * @return number of octets.
     **/
    inline uint32
    getHeaderSize() const
    { return hdrSize; }

    /**
     * @return pointer to the payload section of the packet.
     **/
    inline const uint8* const
    getPayload() const
    { return (uint8*)(buffer + getHeaderSize()); }

    /**
     * @return length of the payload section, in octets.
     **/
    inline uint32
    getPayloadSize() const
    { return payloadSize; }

    /**
     * @return value of the PT header field.
     **/
    inline PayloadType
    getPayloadType() const
    { return static_cast<PayloadType>(getHeader()->payload); }

    /**
     * @return value of the sequence number header field, in host order.
     **/
    inline uint16
    getSeqNum() const
    { return cachedSeqNum; }

    /**
     * @return packet timestamp in host order.
     **/
    inline uint32
    getTimestamp() const
    { return cachedTimestamp; }

    /**
     * @return RTP protocol version of packet.
     **/
    inline uint8
    getProtocolVersion() const
    { return getHeader()->version; }

    /**
     * Ask whether the packet contains padding bytes at the end
     * @return true if the header padding bit is 1.
     **/
    inline bool
    isPadded() const
    { return getHeader()->padding; }

    /**
     * Get the number of octets padding the end of the payload
     * section.
     *
     * @return Padding length in octets.
     **/
    inline uint8
    getPaddingSize() const
    { return buffer[total - 1]; }

    /**
     * Ask whether the packet is marked (for isntance, is a new
     * talk spurt in some audio profiles).
     *
     * @return true is the header marker bit is 1.
     **/
    inline bool
    isMarked() const
    { return getHeader()->marker; }

    /**
     * Ask whether the packet contains header extensions.
     *
     * @return true if the header extension bit is 1.
     **/
    inline bool
    isExtended() const
    { return getHeader()->extension; }

    /**
     * Get the number of contributing sources specified in the
     * packet header.
     **/
    inline uint16
    getCSRCsCount() const
    { return getHeader()->cc; }

    /**
     * Get the 32-bit identifiers of the contributing sources for
     * the packet as an array, of length getCSRCsCount().
     *
     * @return An array of CSRC identifiers as they are in the
     * packet (in network order).
     **/
    inline const uint32*
    getCSRCs() const
    { return static_cast<const uint32*>(&(getHeader()->sources[1])); }

    /**
     * Get the first 16 bits (in network order) of the header of
     * the RTP header extension. Its meaning is undefined at this
     * level.
     *
     * @return 0 if the packet has no header extension, otherwise
     *         the first 16 bits of the header extension, in
     *         network order.
     *
     * @note 0 could be a valid value for the first 16 bits, in
     *         that case RTPPacket::isExtended() should be use.
     **/
    inline uint16
    getHdrExtUndefined() const
    { return (isExtended()? getHeaderExt()->undefined : 0); }

    /**
     * Get the length (in octets) of the data contained in the
     * header extension. Note that this length does not include
     * the four octets at the beginning of the header extension.
     *
     * @return 0 if the packet has no header extension, otherwise
     *         the length.
     *
     * @note 0 is a valid value for this field, so
     *       RTPPacket::isExtended() should be used.
     **/
    inline uint32
    getHdrExtSize() const
    { return (isExtended()?
          (static_cast<uint32>(ntohs(getHeaderExt()->length)) << 2) :
          0); }

    /**
     * Get the content of the header extension.
     *
     * @return NULL if the packet has no header extension, otherwise
     *         a pointer to the packet header extension content.
     **/
    inline const unsigned char*
    getHdrExtContent() const
    { return (isExtended() ?
          (reinterpret_cast<const unsigned char*>(getHeaderExt()) +
           sizeof(RTPHeaderExt)) :
          NULL); }

    /**
     * Get the raw packet as it will be sent through the network.
     *
     * @return memory zone where the raw packet structure is
     *         stored in.
     **/
    inline const unsigned char* const
    getRawPacket() const
    { return buffer; }

    /**
     * Get the raw packet length, including header, extension,
     * payload and padding.
     *
     * @return size of the raw packet structure.
     **/
    inline uint32
    getRawPacketSize() const
    { return total; }

        inline uint32
        getRawPacketSizeSrtp() const
        { return total + srtpLength; }

        inline size_t
    getSizeOfFixedHeader() const
    { return sizeof(RTPFixedHeader); }

    /**
     * Re-compute payload length.
     *
     * This recomputation may be necessary in case of SRTP. We need to decrypt
     * the packet before we can handle padding. See @c takeInDataPacket in
     * @c incqueue.cpp
     *
     * @param padding
     *     If true then set padding flag in RTP header and re-compute
     *     payloadSize.
     */
    void reComputePayLength(bool padding);

protected:
    /**
     * Destructor, free the buffer provided in the constructor.
     **/
    inline virtual ~RTPPacket()
    { endPacket(); }

    /**
     * Free memory allocated for the packet.
     **/
    void
    endPacket();

    /**
     * Return low level structure for the header of the packet.
     *
     * @return RTPFixedHeader pointer to the header of the packet.
     **/
    inline RTPFixedHeader*
    getHeader() const
    { return reinterpret_cast<RTPFixedHeader*>(buffer); }

    inline void
    setExtension(bool e)
    { getHeader()->extension = e; }

    /**
     * Get a pointer to RTPHeaderExt pointing after the RTP header
     * (fixed part plus contributing sources). No check for
     * for the X bit is done.
     *
     * @return header extension if present, garbage if not.
     **/
    inline const RTPHeaderExt*
    getHeaderExt() const
    {
         uint32 fixsize = sizeof(RTPFixedHeader) + (getHeader()->cc << 2);
     return (reinterpret_cast<RTPHeaderExt*>(buffer + fixsize));
    }

    /**
     * Obtain the absolute timestamp carried in the packet header.
     *
     * @return 32-bit timestamp in host order.
     **/
    inline uint32
    getRawTimestamp() const
    { return ntohl(getHeader()->timestamp); }

    inline void
    setbuffer(const void* src, size_t len, size_t pos)
    { memcpy(buffer + pos,src,len); }

    /// Packet sequence number in host order.
    uint16 cachedSeqNum;
    /// Packet timestamp in host order (includes initial shift).
    uint32 cachedTimestamp;

        /**
         * Offset into packet memory pointing to area for SRTP data.
         *
         * This offset points to the memory where the SRTP protect will
         * store the authentication and MKI data.
         */
        uint32 srtpDataOffset;

        /**
         * Lebgth of additional SRTP data.
         *
         * Covers the SRTP authentication and MKI data.
         */
        int32 srtpLength;

        /// total length, including header, payload and padding
        uint32 total;

        /// note: payload (not full packet) size.
        uint32 payloadSize;

private:
    /// packet in memory
    unsigned char* buffer;
    /// size of the header, including contributing sources and extensions
    uint32 hdrSize;
    /// whether the object was contructed with duplicated = true
    bool duplicated;

#ifdef  CCXX_PACKED
#pragma pack(1)
#endif
    /**
     * @struct RTPFixedHeader
     * @short RTP fixed header as it is send through the network.
     *
     * A low-level representation for generic RTP packet header as
     * defined in RFC 1889. A packet consists of the fixed RTP
     * header, a possibly empty list of contributing sources and
     * the payload. Header contents are kept in network (big
     * endian) order.
     **/
    struct RTPFixedHeader
    {
#if __BYTE_ORDER == __BIG_ENDIAN
        /// For big endian boxes
        unsigned char version:2;       ///< Version, currently 2
        unsigned char padding:1;       ///< Padding bit
        unsigned char extension:1;     ///< Extension bit
        unsigned char cc:4;            ///< CSRC count
        unsigned char marker:1;        ///< Marker bit
        unsigned char payload:7;       ///< Payload type
#else
        /// For little endian boxes
        unsigned char cc:4;            ///< CSRC count
        unsigned char extension:1;     ///< Extension bit
        unsigned char padding:1;       ///< Padding bit
        unsigned char version:2;       ///< Version, currently 2
        unsigned char payload:7;       ///< Payload type
        unsigned char marker:1;        ///< Marker bit
#endif
        uint16 sequence;        ///< sequence number
        uint32 timestamp;       ///< timestamp
        uint32 sources[1];      ///< contributing sources
    };

    /**
     * @struct RFC2833Payload
     * @short a structure defining RFC2833 Telephony events.
     *
     * structure to define RFC2833 telephony events in RTP.  You can
     * use this by recasing the pointer returned by getPayload().
     */

public:
    struct RFC2833Payload
    {
#if __BYTE_ORDER == __BIG_ENDIAN
            uint8 event : 8;
            bool ebit : 1;
            bool rbit : 1;
            uint8 vol : 6;
            uint16 duration : 16;
#else
            uint8 event : 8;
            uint8 vol : 6;
            bool rbit : 1;
            bool ebit : 1;
            uint16 duration : 16;
#endif
    };

private:
    /**
     * @struct RTPHeaderExt
     *
     * Fixed component of the variable-length header extension,
     * appended to the fixed header, after the CSRC list, when X
     * == 1.
     **/
    struct RTPHeaderExt
    {
        uint16 undefined; ///< to be defined
        uint16 length;    ///< number of 32-bit words in the extension
    };
#ifdef  CCXX_PACKED
#pragma pack()
#endif

    /* definitions for access to most common 2833 fields... */

public:
    /**
     * Fetch a raw 2833 packet.
     *
     * @return low level 2833 data structure.
     */
    inline struct RFC2833Payload *getRaw2833Payload(void)
        {return (struct RFC2833Payload *)getPayload();}

    /**
     * Fetch 2833 duration field.
     *
     * @return 2833 duration in native host machine byte order.
     */
    inline uint16 get2833Duration(void)
        {return ntohs(getRaw2833Payload()->duration);}

    /**
     * Set 2833 duration field.
     *
     * @param timestamp to use, native host machine byte order.
     */
    inline void set2833Duration(uint16 timestamp)
        {getRaw2833Payload()->duration = htons(timestamp);}
};

/**
 * @class OutgoingRTPPkt
 * @short RTP packets being sent.
 *
 * This class is intented to construct packet objects just before they
 * are inserted into the sending queue, so that they are processed in
 * a understandable and format independent manner inside the stack.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT OutgoingRTPPkt : public RTPPacket
{
public:
    /**
     * Construct a new packet to be sent, containing several
     * contributing source identifiers, header extensions and
     * payload.
         *
         * A new copy in memory (holding all this components
     * along with the fixed header) is created. If the pointer
         * to the SRTP CryptoContext is not NULL and holds a CryptoContext
         * for the SSRC take the SSRC data into account when computing
         * the required memory buffer.
     *
     * @param csrcs array of countributing source 32-bit
     *        identifiers, in host order.
     * @param numcsrc number of CSRC identifiers in the array.
     * @param hdrext whole header extension.
     * @param hdrextlen size of whole header extension, in octets.
     * @param data payload.
     * @param datalen payload length, in octets.
     * @param paddinglen pad packet to a multiple of paddinglen.
         * @param pcc Pointer to the SRTP CryptoContext, defaults to NULL
         * if not specified.
     *
     * @note For efficiency purposes, since this constructor is
     * valid for all packets but is too complex for the common
     * case, two simpler others are provided.
     **/
    OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
               const unsigned char* const hdrext, uint32 hdrextlen,
               const unsigned char* const data, size_t datalen,
                       uint8 paddinglen= 0, CryptoContext* pcc= NULL);

    /**
     * Construct a new packet to be sent, containing several
     * contributing source identifiers and payload.
         *
         * A new copy in
     * memory (holding all this components along with the fixed
         * header) is created. If the pointer
         * to the SRTP CryptoContext is not NULL and holds a CryptoContext
         * for the SSRC take the SSRC data into account when computing
         * the required memory buffer.
     *
     * @param csrcs array of countributing source 32-bit
     * identifiers, in host order.
     * @param numcsrc number of CSRC identifiers in the array.
     * @param data payload.
     * @param datalen payload length, in octets.
     * @param paddinglen pad packet to a multiple of paddinglen.
         * @param pcc Pointer to the SRTP CryptoContext, defaults to NULL
         * if not specified.
         **/
    OutgoingRTPPkt(const uint32* const csrcs, uint16 numcsrc,
               const unsigned char* const data, size_t datalen,
                       uint8 paddinglen= 0, CryptoContext* pcc= NULL);

    /**
     * Construct a new packet (fast variant, with no contributing
     * sources and no header extension) to be sent.
         *
         * A new copy in
         * memory (holding the whole packet) is created. If the pointer
         * to the SRTP CryptoContext is not NULL and holds a CryptoContext
         * for the SSRC take the SSRC data into account when computing
         * the required memory buffer.
     *
     * @param data payload.
     * @param datalen payload length, in octets.
     * @param paddinglen pad packet to a multiple of paddinglen.
         * @param pcc Pointer to the SRTP CryptoContext, defaults to NULL
         * if not specified.
         **/
    OutgoingRTPPkt(const unsigned char* const data, size_t datalen,
                       uint8 paddinglen= 0, CryptoContext* pcc= NULL);

    ~OutgoingRTPPkt()
    { }

    /**
     * @param pt Packet payload type.
     **/
    inline void
    setPayloadType(PayloadType pt)
    { getHeader()->payload = pt; }

    /**
         * Sets the sequence number in the header.
         *
     * @param seq Packet sequence number, in host order.
     **/
    inline void
    setSeqNum(uint16 seq)
    {
        cachedSeqNum = seq;
        getHeader()->sequence = htons(seq);
    }

    /**
     * @param pts Packet timestamp, in host order.
     **/
    inline void
    setTimestamp(uint32 pts)
    {
        cachedTimestamp = pts;
        getHeader()->timestamp = htonl(pts);
    }

    /**
     * Set synchronization source numeric identifier.
     *
     * @param ssrc 32-bit Synchronization SouRCe numeric
     * identifier, in host order.
     **/
    inline void
    setSSRC(uint32 ssrc) const
    { getHeader()->sources[0] = htonl(ssrc); }

    /**
     * Set synchronization source numeric identifier. Special
     * version to save endianness conversion.
     *
     * @param ssrc 32-bit Synchronization SouRCe numeric
     * identifier, in network order.
     **/
    inline void
    setSSRCNetwork(uint32 ssrc) const
    { getHeader()->sources[0] = ssrc; }

    /**
     * Specify the value of the marker bit. By default, the marker
     * bit of outgoing packets is false/0. This method allows to
     * explicity specify and change that value.
     *
     * @param mark value for the market bit.
     */
    inline void
    setMarker(bool mark)
    { getHeader()->marker = mark; }

        /**
         * Called packet is setup.
         *
         * This private method computes the SRTP data and stores it in the
         * packet. Then encrypt the payload data (ex padding).
         */
        void protect(uint32 ssrc, CryptoContext* pcc);

    /**
     * Outgoing packets are equal if their sequence numbers match.
     **/
    inline bool
    operator==(const OutgoingRTPPkt &p) const
    { return ( this->getSeqNum() == p.getSeqNum() ); }

    /**
     * Outgoing packets are not equal if their sequence numbers differ.
     **/
    inline bool
    operator!=(const OutgoingRTPPkt &p) const
    { return ( this->getSeqNum() != p.getSeqNum() ); }

private:
    /**
     * Copy constructor from objects of its same kind, declared
     * private to avoid its use.
     **/
    OutgoingRTPPkt(const OutgoingRTPPkt &o);

    /**
     * Assignment operator from objects of its same kind, declared
     * private to avoid its use.
     **/
    OutgoingRTPPkt&
    operator=(const OutgoingRTPPkt &o);

    /**
     * Set the list of CSRC identifiers in an RTP packet,
     * switching host to network order.
     */
    void setCSRCArray(const uint32* const csrcs, uint16 numcsrc);

};

/**
 * @class IncomingRTPPkt
 *
 * @short RTP packets received from other participants.
 *
 * This class is intented to construct a packet object just after
 * every packet is received by the scheduled queue, so that they are
 * processed in an understandable and format independent manner inside
 * the stack.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 */
class __EXPORT IncomingRTPPkt : public RTPPacket
{
public:
    /**
     * Build an RTP packet object from a data buffer. This
     * constructor first performs a generic RTP data packet header
     * check, whose result can be checked via isHeaderValid().
     *
     * @param block pointer to the buffer the whole packet is stored in.
     * @param len length of the whole packet, expressed in octets.
     *
     * @note If check fails, the packet object is
     * incomplete. checking isHeaderValid() is recommended before
     * using a new RTPPacket object.
     **/
    IncomingRTPPkt(const unsigned char* block, size_t len);

    ~IncomingRTPPkt()
    { }

    /**
     * Get validity of this packet
     * @return whether the header check performed at construction
     *         time ended successfully.
     **/
    inline bool
    isHeaderValid()
    { return headerValid; }

    /**
     * Get synchronization source numeric identifier.
     *
     * @return 32-bits Synchronization SouRCe numeric identifier,
     * in host order.
     **/
    inline uint32
    getSSRC() const
    { return cachedSSRC; }

        /**
         * Unprotect a received packet.
         *
         * Perform SRTP processing on this packet.
         *
         * @param pcc Pointer to SRTP CryptoContext.
         * @return
         *     one if no errors, -1 if authentication failed, -2 if
         *     replay check failed
         */
        int32
        unprotect(CryptoContext* pcc);

    /**
     * Two incoming packets are equal if they come from sources
     * with the same SSRC and have the same sequence number.
     **/
    inline bool
    operator==(const IncomingRTPPkt &p) const
    { return ( (this->getSeqNum() == p.getSeqNum()) &&
           (this->getSSRC() == p.getSSRC()) ); }

    /**
     * Two incoming packets are not equal if they come from
     * different sources or have different sequence numbers.
     **/
    inline bool
    operator!=(const IncomingRTPPkt &p) const
    { return !( *this == p ); }

private:
    /**
     * Copy constructor from objects of its same kind, declared
     * private to avoid its use.
     **/
    IncomingRTPPkt(const IncomingRTPPkt &ip);

    /**
     * Assignment operator from objects of its same kind, declared
     * private to avoid its use.
     */
    IncomingRTPPkt&
    operator=(const IncomingRTPPkt &ip);

    /// Header validity, checked at construction time.
    bool headerValid;
    /// SSRC 32-bit identifier in host order.
    uint32 cachedSSRC;
    // Masks for RTP header validation: types matching RTCP SR or
    // RR must be rejected to avoid accepting misaddressed RTCP
    // packets.
    static const uint16 RTP_INVALID_PT_MASK;
    static const uint16 RTP_INVALID_PT_VALUE;
};

/** @}*/ // rtppacket

END_NAMESPACE

#endif  // ndef CCXX_RTP_RTPPKT_H_

/** EMACS **
 * Local variables:
 * mode: c++
 * c-basic-offset: 8
 * End:
 */
