// Copyright (C) 2001,2002,2004 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.
//

/**
 * @file cqueue.h
 *
 * @short Generic RTCP control queues.
 **/

#ifndef CCXX_RTP_CQUEUE_H_
#define CCXX_RTP_CQUEUE_H_

#include <ccrtp/ioqueue.h>
#include <ccrtp/CryptoContextCtrl.h>
#include <list>

NAMESPACE_COMMONCPP

/**
 * @defgroup cqueue Generic RTCP control queues.
 * @{
 **/

/**
 * @class QueueRTCPManager
 * @short Adds generic management of RTCP functions to an RTP data
 * queue.
 *
 * Extends an RTP data i/o queue adding management of RTCP functions:
 *
 * Provide feedback on the quality of the data distribution.
 *
 * Convey the CNAME (persistent transport-level identifier) for every
 * RTP source.
 *
 * Control the sending rate of RTCP packets
 *
 * Convey minimal control information about the participants
 *
 * This class implements generic RTCP behaviour (as specified in RFC
 * 1889/draft-ietf-avt-rtp-new) and may be specialized for specific
 * profiles (see AVPQueue) or particular RTCP extensions.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT QueueRTCPManager : public RTPDataQueue,
    protected RTCPCompoundHandler
{
public:
    /**
     * Get the most recent sender report received from a
     * synchronization source.
     *
     * @param src Synchronization source of the sender info.
     * @return Most recent sender info received from src.
     * @retval NULL when no sender report has been received from
     * the specified source.
     **/
    RTCPSenderInfo* getMRSenderInfo(SyncSource& src);

    /**
     * Ask for the info in the most recent receiver report about
     * the local source received from the source given as
     * parameter.
     *
     * @param srcFrom Source of the receiver info.
     * @return most recent receiver info received from src.
     * @retval NULL when no receiver report has been received from
     * the specified source.
     */
    RTCPReceiverInfo* getMRReceiverInfo(SyncSource& srcFrom);

    /**
     * Set how much time the stack will wait before deleting a
     * synchronization source that has sent an RTCP BYE packet.
     *
     * @param delay delay in microseconds.
     *
     * @note The default delay is 1000000 microseconds
     **/
    void setLeavingDelay(microtimeout_t delay)
    { leavingDelay = delay; }

    /**
     * This method sets the maximum end to end delay allowed. If
     * the processing delay plus the trip time for a packet is
     * greater than the end to end delay, the packet is discarded,
     * and the application cannot get it.
     *
     * This is a way of setting an upper bound to the end to end
     * delay, computed as the elapsed time between the packet
     * timestamping at the sender side, and the picking of the
     * packet at the receiver side.
     *
     * @param t maximum end to end delay allowed. A value of 0
     * implies there is no limit and is the default
     */
    inline void
    setEnd2EndDelay(microtimeout_t t)
        { end2EndDelay = t; }

    inline microtimeout_t
    getDefaultEnd2EndDelay() const
    { return defaultEnd2EndDelay; }

    inline microtimeout_t
    getEnd2EndDelay() const
    { return end2EndDelay; }

    /**
     * Specify the fraction of the total control bandwith to be
     * dedicated to senders reports.
     *
     * @param fraction fraction of bandwidth, must be between 0 an 1.
     *
     * This method sets the fraction of the global control
     * bandwidth that will be dedicated to senders reports. Of
     * course, <code>1 - fraction</code> will be dedicated to
     * receivers reports.
     *
     * @see setControlBandwidth
     */
    inline void
    setSendersControlFraction(float fraction)
    { sendControlBwFract = fraction; recvControlBwFract = 1 - fraction;}

    /**
     * Manually set the minimum interval for sending RTP compound
     * packets
     *
     * @param interval minimum interval between RTCP packets, in
     * microseconds.
     *
     * @see computeRTCPInterval()
     **/
    void
    setMinRTCPInterval(microtimeout_t interval)
    { rtcpMinInterval = interval; }

    /**
     * Get the total number of RTCP packets sent until now
     **/
    inline uint32
    getSendRTCPPacketCount() const
    { return ctrlSendCount; }

    /**
     * Set ouput queue CryptoContext.
     *
     * The endQueue method (provided by RTPQueue) deletes all
     * registered CryptoContexts.
     *
     * @param cc Pointer to initialized CryptoContext.
     */
    void
    setOutQueueCryptoContextCtrl(CryptoContextCtrl* cc);

    /**
     * Remove output queue CryptoContext.
     *
     * The endQueue method (provided by RTPQueue) also deletes all
     * registered CryptoContexts.
     *
     * @param cc Pointer to initialized CryptoContext to remove.
     */
    void
    removeOutQueueCryptoContextCtrl(CryptoContextCtrl* cc);

    /**
     * Get an output queue CryptoContext identified by SSRC
     *
     * @param ssrc Request CryptoContext for this incoming SSRC
     * @return Pointer to CryptoContext of the SSRC of NULL if no context
     * available for this SSRC.
     */
    CryptoContextCtrl*
    getOutQueueCryptoContextCtrl(uint32 ssrc);


    /**
     * Set input queue CryptoContext.
     *
     * The endQueue method (provided by RTPQueue) deletes all
     * registered CryptoContexts.
     *
     * @param cc Pointer to initialized CryptoContext.
     */
    void
    setInQueueCryptoContextCtrl(CryptoContextCtrl* cc);

    /**
     * Remove input queue CryptoContext.
     *
     * The endQueue method (provided by RTPQueue) also deletes all
     * registered CryptoContexts.
     *
     * @param cc
     *     Pointer to initialized CryptoContext to remove. If pointer
     *     if <code>NULL</code> then delete the whole queue
     */
    void
    removeInQueueCryptoContextCtrl(CryptoContextCtrl* cc);

    /**
     * Get an input queue CryptoContext identified by SSRC
     *
     * @param ssrc Request CryptoContext for this incoming SSRC
     * @return Pointer to CryptoContext of the SSRC of NULL if no context
     * available for this SSRC.
     */
    CryptoContextCtrl*
    getInQueueCryptoContextCtrl(uint32 ssrc);

protected:
    QueueRTCPManager(uint32 size = RTPDataQueue::defaultMembersHashSize,
             RTPApplication& app = defaultApplication());

    QueueRTCPManager(uint32 ssrc,
             uint32 size = RTPDataQueue::defaultMembersHashSize,
             RTPApplication& app = defaultApplication());

    virtual
    ~QueueRTCPManager();

    const RTPApplication&
    getApplication()
    { return queueApplication; }

    inline void
    setControlBandwidth(float fraction)
    { controlBwFract = fraction; }

    float
    getControlBandwidth() const
    { return controlBwFract; }

    /**
     * Build and send RTCP packets following timing rules
     * (including the "timer reconsideration" algorithm).
     **/
    void
    controlTransmissionService();

    /**
     * Process incoming RTCP packets pending in the control
     * reception socket.
     **/
    void
    controlReceptionService();

    /**
     * Appy collision and loop detection and correction algorithm
     * when receiving RTCP packets. Follows section 8.2 in
     * draft-ietf-avp-rtp-new.
     *
     * @param sourceLink link to the source object.
     * @param is_new whether the source has been just recorded.
     * @param na RTCP packet network address.
     * @param tp RTCP packet source transport port.
     *
     * @return whether the packet must not be discarded.
     **/
    bool checkSSRCInRTCPPkt(SyncSourceLink& sourceLink, bool is_new,
                InetAddress& na, tpport_t tp);

    void
    endQueueRTCPManager();

    /**
     * Plug-in for processing (acquire information carried in) an
     * incoming RTCP Sender Report. The default implementation in
     * this class only processes the sender information and the
     * receiver report blocks about the local source.
     *
     * @param source Synchronization source this report comes from.
     * @param SR Sender report structure.
     * @param blocks Number of report blocks in the packet.
     **/
    virtual void
    onGotSR(SyncSource& source, SendReport& SR, uint8 blocks);

    /**
     * Plug-in for processing (acquire information carried in) an
     * incoming RTCP Receiver Report. The default implementation
     * in this class only processes the receiver report blocks
     * about the local source.
     *
     * @param source Synchronization source this report comes from.
     * @param RR Receiver report structure
     * @param blocks Number of report blocks in the packet
     **/
    virtual void
    onGotRR(SyncSource& source, RecvReport& RR, uint8 blocks);

    /**
     * @param source Synchronization source of SDES RTCP packet.
     * @param pkt SDES RTCP packet received.
     **/
    bool
    onGotSDES(SyncSource& source, RTCPPacket& pkt);

    /**
     * Plug-in for handling of SDES chunks.
     *
     * @param source Synchronization source of SDES chunk.
     * @param chunk SDES chunk structure.
     * @param len Length of chunk, in octets.
     *
     * @return whether there was a CNAME.
     **/
    virtual bool
    onGotSDESChunk(SyncSource& source, SDESChunk& chunk, size_t len);

    /**
     * Plug-in for handling of APP (application specific) RTCP
     * packets.
     *
     * @param - Synchronization source of this packet.
     * @param - RTCP APP packet struct.
     * @param - Length of the app data packet, including ssrc.
     * name and app. specific data.
     **/
    inline virtual void
    onGotAPP(SyncSource&, RTCPCompoundHandler::APPPacket&,
         size_t)
    { return; }

    inline timeval
    getRTCPCheckInterval()
    { return rtcpCheckInterval; }

    /**
     * Get the number of data packets sent at the time the last SR
     * was generated.
     **/
    uint32
    getLastSendPacketCount() const
    { return lastSendPacketCount; }

    /**
     * @param n Number of members.
     **/
    inline void
    setPrevMembersNum(uint32 n)
    { reconsInfo.rtcpPMembers = n; }

    inline uint32
    getPrevMembersCount() const
    { return reconsInfo.rtcpPMembers; }

    /**
     * This method is used to send an RTCP BYE packet.  An RTCP
     * BYE packet is sent when one of the the following
     * circumstances occur:
     * - when leaving the session
     * - when we have detected that another synchronization source
     * in the same session is using the same SSRC identifier as
     * us.
     *
     * Try to post a BYE message. It will send a BYE packet as
     * long as at least one RTP or RTCP packet has been sent
     * before. If the number of members in the session is more
     * than 50, the algorithm described in section 6.3.7 of
     * RFC 3550 is applied in order to avoid a flood
     * of BYE messages.
     *
     * @param reason reason to specify in the BYE packet.
     **/
    size_t
    dispatchBYE(const std::string& reason);

    size_t
    sendControlToDestinations(unsigned char* buffer, size_t len);

private:
    QueueRTCPManager(const QueueRTCPManager &o);

    QueueRTCPManager&
    operator=(const QueueRTCPManager &o);

    /**
     * Posting of RTCP messages.
     *
     * @return std::size_t number of octets sent
     */
    size_t
    dispatchControlPacket();

    /**
     * For picking up incoming RTCP packets if they are waiting. A
     * timeout for the maximum interval since the last RTCP packet
     * had been received is also returned. This is checked every
     * rtcpCheckInterval seconds.
     *
     * This method decomposes all incoming RTCP compound packets
     * pending in the control socket and processes each RTCP
     * packet.
     *
     **/
    void
    takeInControlPacket();

    /**
     * Computes the interval for sending RTCP compound packets,
     * based on the average size of RTCP packets sent and
     * received, and the current estimated number of participants
     * in the session.
     *
     * @note This currently follows the rules in section 6 of
     *       RFC 3550
     * @todo make it more flexible as recommended in the draft. For now,
     * we have setMinRTCPInterval.
     *
     * @return interval for sending RTCP compound packets
     **/
    virtual timeval
    computeRTCPInterval();

    /**
     * Choose which should be the type of the next SDES item
     * sent. This method is called when packing SDES chunks in a
     * new RTCP packet.
     *
     * @return type of the next SDES item to be sent
     **/
    virtual SDESItemType
    scheduleSDESItem();

    /**
     * Plug-in for SSRC collision handling.
     *
     * @param - previously identified source.
     **/
    inline virtual void
    onSSRCCollision(const SyncSource&)
    { }

    /**
     * Virtual reimplemented from RTPDataQueue
     **/
    virtual bool
    end2EndDelayed(IncomingRTPPktLink& p);

    /**
     * Plug-in for processing of SR/RR RTCP packet
     * profile-specific extensions (third part of SR reports or
     * second part of RR reports).
     *
     * @param - Content of the profile extension.
     * @param - Length of the extension, in octets.
     **/
    inline virtual void
    onGotRRSRExtension(unsigned char*, size_t)
    { return; }

    /**
     * A plugin point for goodbye message.  Called when a BYE RTCP
     * packet has been received from a valid synchronization
     * source.
     *
     * @param - synchronization source from what a BYE RTCP
     * packet has been just received.
     * @param - reason string the source has provided.
     **/
    inline virtual void
    onGotGoodbye(const SyncSource&, const std::string&)
    { return; }

    /**
     * Process a BYE packet just received and identified.
     *
     * @param pkt previously identified RTCP BYE packet
     * @param pointer octet number in the RTCP reception buffer
     *        where the packet is stored
     * @param len total length of the compount RTCP packet the BYE
     *        packet to process is contained
     *
     * @bug if the bye packet contains several SSRCs,
     *      eventSourceLeaving is only called for the last one
     **/
    bool
    getBYE(RTCPPacket &pkt, size_t &pointer, size_t len);

    /**
     * @return number of Report Blocks packed
     **/
    uint8
    packReportBlocks(RRBlock* blocks, uint16& len, uint16& available);

    /**
     * Builds an SDES RTCP packet. Each chunk is built following
     * appendix A.4 in draft-ietf-avt-rtp-new.
     *
     * @param len provisionary length of the RTCP compound packet
     *
     * @return
     **/
    void
    packSDES(uint16& len);

    /**
     * This must be called in order to update the average RTCP compound
     * packet size estimation when:
     *
     * a compoung RTCP packet is received (6.3.3).
     *
     * a compound RTCP packet is transmitted (6.3.6).
     *
     * @param len length in octets of the compound RTCP packet
     * just received/transmitted.
     **/
    void
    updateAvgRTCPSize(size_t len);

    /**
     * Apply reverse reconsideration adjustment to timing
     * parameters when receiving BYE packets and not waiting to
     * send a BYE.
     **/
    void
    reverseReconsideration();

    bool
    timerReconsideration();

    /**
     * Purge sources that do not seem active any more.
     *
     * @note MUST be perform at least every RTCP transmission
     *       interval
     * @todo implement it. It may be dangerous and anyway should
     * be optional.
     **/
    void
    expireSSRCs();

    /**
     * To be executed when whe are leaving the session.
     **/
    void
    getOnlyBye();

    /**
     * Set item value from a string without null termination (as
     * it is transported in RTCP packets).
     **/
    void
    setSDESItem(Participant* part, SDESItemType type,
            const char* const value, size_t len);

    /**
     * Set PRIV item previx value from a string without null
     * termination (as it is transported in RTCP packets).
     **/
    void
    setPRIVPrefix(Participant* part, const char* const value, size_t len);

    /**
     * For certain control calculations in RTCP, the size of the
     * underlying network and transport protocols is needed. This
     * method provides the size of the network level header for
     * the default case of IP (20 octets). In case other protocol
     * with different header size is used, this method should be
     * redefined in a new specialized class.
     *
     * @return size of the headers of the network level. IP (20) by
     *        default.
     **/
    inline virtual uint16
    networkHeaderSize()
    { return 20; }

    /**
     * For certain control calculations in RTCP, the size of the
     * underlying network and transport protocols is needed. This
     * method provides the size of the transport level header for
     * the default case of UDP (8 octets). In case other protocol
     * with different header size is used, this method should be
     * redefined in a new specialized class.
     *
     * return size of the headers of the transport level. UDP (8)
     *        by default
     **/
    inline virtual uint16
    transportHeaderSize()
    { return 8; }


    int32 protect(uint8* pkt, size_t len, CryptoContextCtrl* cc);
    int32 unprotect(uint8* pkt, size_t len, CryptoContextCtrl* cc);
    
    
    SDESItemType
    nextSDESType(SDESItemType t);

    virtual size_t
    sendControl(const unsigned char* const buffer, size_t len) = 0;

    virtual size_t
    recvControl(unsigned char* buffer, size_t len,
            InetHostAddress& na, tpport_t& tp) = 0;

    virtual bool
    isPendingControl(microtimeout_t timeout) = 0;

    // whether the RTCP service is active
    volatile bool controlServiceActive;
    float controlBwFract, sendControlBwFract, recvControlBwFract;
    // number of RTCP packets sent since the beginning
    uint32 ctrlSendCount;

    // Network + transport headers size, typically size of IP +
    // UDP headers
    uint16 lowerHeadersSize;

    SDESItemType nextScheduledSDESItem;
    static const SDESItemType firstSchedulable;
    static const SDESItemType lastSchedulable;

    // state for rtcp timing. Its meaning is defined in
    // draft-ietf-avt-rtp-new, 6.3.

    // Parameters for timer reconsideration algorithm
    struct {
        timeval rtcpTp, rtcpTc, rtcpTn;
        uint32 rtcpPMembers;
    } reconsInfo;
    bool rtcpWeSent;
    uint16 rtcpAvgSize;
    bool rtcpInitial;
    // last time we checked if there were incoming RTCP packets
    timeval rtcpLastCheck;
    // interval to check if there are incoming RTCP packets
    timeval rtcpCheckInterval;
    // next time to check if there are incoming RTCP packets
    timeval rtcpNextCheck;

    // number of RTP data packets sent at the time of the last
    // RTCP packet transmission.
    uint32 lastSendPacketCount;

    // minimum interval for transmission of RTCP packets. The
    // result of computeRTCPInterval will always be >= (times a
    // random number between 0.5 and 1.5).
    microtimeout_t rtcpMinInterval;

    microtimeout_t leavingDelay;
    static const microtimeout_t defaultEnd2EndDelay;
    // Maximum delay allowed between packet timestamping and
    // packet availability for the application.
    microtimeout_t end2EndDelay;
    // Application this queue is bound to.
    RTPApplication& queueApplication;

    // an empty RTPData
    static const uint16 TIMEOUT_MULTIPLIER;
    static const double RECONSIDERATION_COMPENSATION;
    
    mutable Mutex outCryptoMutex;
    std::list<CryptoContextCtrl *> outCryptoContexts;
    uint32 srtcpIndex;

    mutable Mutex inCryptoMutex;
    std::list<CryptoContextCtrl *> inCryptoContexts;

};

/**
 * This class, an RTP/RTCP queue, adds audio/video profile (AVP)
 * specific methods to the generic RTCP service queue
 * (QueueRTCPManager).
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
class __EXPORT AVPQueue : public QueueRTCPManager
{
public:
    /**
     * Specify the bandwith available for control (RTCP) packets.
     * This method sets the global control bandwidth for both
     * sender and receiver reports. As recommended in RFC 1890,
     * 1/4 of the total control bandwidth is dedicated to senders,
     * whereas 3/4 are dedicated to receivers.
     *
     * @param fraction fraction of the session bandwidth, between
     * 0 and 1
     *
     * @note If this method is not called, it is assumed that the
     * control bandwidth is equal to 5% of the session
     * bandwidth. Note also that the RFC RECOMMENDS the 5%.
     *
     **/
    inline void
    setControlBandwidth(float fraction)
    { QueueRTCPManager::setControlBandwidth(fraction); }

    float
    getControlBandwidth() const
    { return QueueRTCPManager::getControlBandwidth(); }

protected:
    AVPQueue(uint32 size = RTPDataQueue::defaultMembersHashSize,
         RTPApplication& app = defaultApplication()) :
        QueueRTCPManager(size,app)
    { }

    /**
     * Local SSRC is given instead of computed by the queue.
     **/
    AVPQueue(uint32 ssrc, uint32 size =
         RTPDataQueue::defaultMembersHashSize,
         RTPApplication& app = defaultApplication()) :
        QueueRTCPManager(ssrc,size,app)
    { }
    inline virtual ~AVPQueue()
    { }
};

/** @}*/ // cqueue

END_NAMESPACE

#endif  //CCXX_RTP_CQUEUE_H_

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