// Copyright (C) 1999-2005 Open Source Telecom Corporation.
//
// 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 rtp.h
 *
 * @short Generic and audio/video profile specific RTP interface of
 * ccRTP.
 *
 * The classes and types in this header provide general RTP
 * functionality (following RFC 3550) as well as audio/video RTP
 * profile specific functionality (following RFC 3551).
 **/

#ifndef CCXX_RTP_RTP_H_
#define CCXX_RTP_RTP_H_

#include <ccrtp/cqueue.h>
#include <ccrtp/channel.h>

NAMESPACE_COMMONCPP

/**
 * @defgroup sessions RTP sessions.
 * @{
 **/

/**
 * @class RTPSessionBase
 *
 * Generic RTP protocol stack for exchange of realtime data.  This
 * stack uses the concept of packet send and receive queues to schedule
 * and buffer outgoing packets and to arrange or reorder incoming packets
 * as they arrive.
 *
 * This is a template class that allows customization of two aspects:
 * the underlying network and the control protocol. The RTPDataChannel
 * and RTCPChannel template parameters specify the socket types to
 * use. The ServiceQueue template parameter specify which packet queue
 * is used.
 *
 * RTPSessionBase objects do not have any threading policy, thus
 * allowing to customize this aspect in derived classes (see
 * SingleThreadRTPSession or RTPSessionPoolBase).
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short RTP protocol stack based on Common C++.
 **/
    template <class RTPDataChannel = DualRTPUDPIPv4Channel,
          class RTCPChannel = DualRTPUDPIPv4Channel,
          class ServiceQueue = AVPQueue>
    class __EXPORT TRTPSessionBase : public ServiceQueue
    {
    public:
        /**
         * Builds a session waiting for packets in a host address.
         *
         * @param ia Network address this socket is to be bound.
         * @param dataPort Transport port the data socket is to be bound.
         * @param controlPort Transport port the control socket is to be bound.
         * @param membersSize Initial size of the membership table.
         * @param app Application this session is associated to.
         * */
        TRTPSessionBase(const InetHostAddress& ia, tpport_t dataPort,
                tpport_t controlPort, uint32 membersSize,
                RTPApplication& app) :
            ServiceQueue(membersSize,app)
            { build(ia,dataPort,controlPort); }

        /**
         * Builds a session with the specified ssrc identifier for the
         * local source.
         *
         * @param ssrc SSRC identifier for the local source.
         * @param ia Network address this socket is to be bound.
         * @param dataPort Transport port the data socket is to be bound.
         * @param controlPort Transport port the control socket is to be bound.
         * @param membersSize Initial size of the membership table.
         * @param app Application this session is associated to.
         **/
        TRTPSessionBase(uint32 ssrc,
                const InetHostAddress& ia,
                tpport_t dataPort, tpport_t controlPort,
                uint32 membersSize, RTPApplication& app):
            ServiceQueue(ssrc,membersSize,app)
            { build(ia,dataPort,controlPort); }

        /**
         * Builds a session waiting for packets in a multicast address.
         * TODO: ssrc constructor for multicast!
         *
         * @param ia Multicast address this socket is to be bound.
         * @param dataPort Transport port the data socket is to be bound.
         * @param controlPort Transport port the control socket is to be bound.
         * @param membersSize Initial size of the membership table.
         * @param app Application this session is associated to.
         * @param iface Index (from 0 to n) of network interface to join to
         * multicast group.
         **/
        TRTPSessionBase(const InetMcastAddress& ia, tpport_t dataPort,
                tpport_t controlPort, uint32 membersSize,
                RTPApplication& app, uint32 iface) :
            ServiceQueue(membersSize,app)
            { build(ia,dataPort,controlPort,iface); }

        /**
         * Builds a session waiting for packets in a multicast
         * address, with the specified ssrc identifier for the local
         * source.
         *
         * @param ssrc SSRC identifier for the local source.
         * @param ia Multicast address this socket is to be bound.
         * @param dataPort Transport port the data socket is to be bound.
         * @param controlPort Transport port the control socket is to be bound.
         * @param membersSize Initial size of the membership table.
         * @param app Application this session is associated to.
         * @param iface Index (from 0 to n) of network interface to join to
         * multicast group.
         **/
        TRTPSessionBase(uint32 ssrc,
                const InetMcastAddress& ia, tpport_t dataPort,
                tpport_t controlPort, uint32 membersSize,
                RTPApplication& app, uint32 iface) :
            ServiceQueue(ssrc,membersSize,app)
            { build(ia,dataPort,controlPort,iface); }

        virtual size_t dispatchBYE(const std::string &str)
            {
                return QueueRTCPManager::dispatchBYE(str);
            }

        /**
         * Set the value of the TTL field in the sent packets.
         *
         * @param ttl Time To Live
         * @return error code from the socket operation
         */
        inline Socket::Error
        setMcastTTL(uint8 ttl)
            {
                Socket::Error error = dso->setMulticast(true);
                if ( error ) return error;
                error = dso->setTimeToLive(ttl);
                if ( error ) return error;
                error = cso->setMulticast(true);
                if ( error ) return error;
                return cso->setTimeToLive(ttl);
            }

        inline virtual
        ~TRTPSessionBase()
            {
                endSocket();
            }

        inline RTPDataChannel *getDSO(void)
            {return dso;}

    protected:
        /**
         * @param timeout maximum timeout to wait, in microseconds
         */
        inline bool
        isPendingData(microtimeout_t timeout)
            { return dso->isPendingRecv(timeout); }

        InetHostAddress
        getDataSender(tpport_t *port = NULL) const
            { return dso->getSender(port); }

        inline size_t
        getNextDataPacketSize() const
            { return dso->getNextPacketSize(); }

        /**
         * Receive data from the data channel/socket.
         *
         * @param buffer Memory region to read to.
         * @param len Maximum number of octets to get.
         * @param na Source network address.
         * @param tp Source transport port.
         * @return Number of octets actually read.
         */
        inline size_t
        recvData(unsigned char* buffer, size_t len,
             InetHostAddress& na, tpport_t& tp)
            { na = dso->getSender(tp); return dso->recv(buffer, len); }

        inline void
        setDataPeer(const InetAddress &host, tpport_t port)
            { dso->setPeer(host,port); }


        /**
         * @param buffer memory region to write from
         * @param len number of octets to write
         */
        inline size_t
        sendData(const unsigned char* const buffer, size_t len)
            { return dso->send(buffer, len); }

        inline SOCKET getDataRecvSocket() const
            { return dso->getRecvSocket(); }

        /**
         * @param timeout maximum timeout to wait, in microseconds
         * @return whether there are packets waiting to be picked
         */
        inline bool
        isPendingControl(microtimeout_t timeout)
            { return cso->isPendingRecv(timeout); }

        InetHostAddress
        getControlSender(tpport_t *port = NULL) const
            { return cso->getSender(port); }

        /**
         * Receive data from the control channel/socket.
         *
         * @param buffer Buffer where to get data.
         * @param len Maximum number of octets to get.
         * @param na Source network address.
         * @param tp Source transport port.
         * @return Number of octets actually read.
         **/
        inline size_t
        recvControl(unsigned char *buffer, size_t len,
                InetHostAddress& na, tpport_t& tp)
            { na = cso->getSender(tp); return cso->recv(buffer,len); }

        inline void
        setControlPeer(const InetAddress &host, tpport_t port)
            { cso->setPeer(host,port); }

        /**
         * @return number of octets actually written
         * @param buffer
         * @param len
         */
        inline size_t
        sendControl(const unsigned char* const buffer, size_t len)
            { return cso->send(buffer,len); }

        inline SOCKET getControlRecvSocket() const
            { return cso->getRecvSocket(); }

        /**
         * Join a multicast group.
         *
         * @param ia address of the multicast group
         * @return error code from the socket operation
         */
        inline Socket::Error
        joinGroup(const InetMcastAddress& ia, uint32 iface)
            {
                Socket::Error error  = dso->setMulticast(true);
                if ( error ) return error;
                error = dso->join(ia,iface);
                if ( error ) return error;
                error = cso->setMulticast(true);
                if ( error ) {
                    dso->drop(ia);
                    return error;
                }
                error = cso->join(ia,iface);
                if ( error ) {
                    dso->drop(ia);
                    return error;
                }
                return Socket::errSuccess;
            }

        /**
         * Leave a multicast group.
         *
         * @param ia address of the multicast group
         * @return error code from the socket operation
         */
        inline Socket::Error
        leaveGroup(const InetMcastAddress& ia)
            {
                Socket::Error error = dso->setMulticast(false);
                if ( error ) return error;
                error = dso->leaveGroup(ia);
                if ( error ) return error;
                error = cso->setMulticast(false);
                if ( error ) return error;
                return cso->leaveGroup(ia);
            }

        inline void
        endSocket()
            {
                if (dso) {
                    dso->endSocket();
                    delete dso;
                }
                dso = NULL;
                if (cso) {
                    cso->endSocket();
                    delete cso;
                }
                cso = NULL;
            }

    private:
        void
        build(const InetHostAddress& ia, tpport_t dataPort,
              tpport_t controlPort)
            {
                if ( 0 == controlPort ) {
                    dataBasePort = even_port(dataPort);
                    controlBasePort = dataBasePort + 1;
                } else {
                    dataBasePort = dataPort;
                    controlBasePort = controlPort;
                }
                dso = new RTPDataChannel(ia,dataBasePort);
                cso = new RTCPChannel(ia,controlBasePort);
            }

        void
        build(const InetMcastAddress& ia, tpport_t dataPort,
              tpport_t controlPort, uint32 iface)
            {
                if ( 0 == controlPort ) {
                    dataBasePort = even_port(dataPort);
                    controlBasePort = dataBasePort + 1;
                } else {
                    dataBasePort = dataPort;
                    controlBasePort = controlPort;
                }
                dso = new RTPDataChannel(InetHostAddress("0.0.0.0"),dataBasePort);
                cso = new RTCPChannel(InetHostAddress("0.0.0.0"),controlBasePort);
                joinGroup(ia,iface);
            }

        /**
         * Ensure a port number is odd. If it is an even number, return
         * the next lower (odd) port number.
         *
         * @param port number to filter
         * @return filtered (odd) port number
         */
        inline tpport_t
        odd_port(tpport_t port)
            { return (port & 0x01)? (port) : (port - 1); }

        /**
         * Ensure a port number is even. If it is an odd number, return
         * the next lower (even) port number.
         *
         * @param port number to filter
         * @return filtered (even) port number
         */
        inline tpport_t
        even_port(tpport_t port)
            { return (port & 0x01)? (port - 1) : (port); }

        tpport_t dataBasePort;
        tpport_t controlBasePort;

    protected:
        RTPDataChannel* dso;
        RTCPChannel* cso;
        friend class RTPSessionBaseHandler;
    };

/**
 * @class SingleThreadRTPSession
 *
 * This template class adds the threading aspect to the RTPSessionBase
 * template in one of the many possible ways. It inherits from a
 * single execution thread that schedules sending of outgoing packets
 * and receipt of incoming packets.
 *
 * @author Federico Montesino Pouzols <fedemp@altern.org>
 **/
    template
    <class RTPDataChannel = DualRTPUDPIPv4Channel,
     class RTCPChannel = DualRTPUDPIPv4Channel,
     class ServiceQueue = AVPQueue>
    class __EXPORT SingleThreadRTPSession :
        protected Thread,
        public TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
    {
    public:
        SingleThreadRTPSession(const InetHostAddress& ia,
                       tpport_t dataPort = DefaultRTPDataPort,
                       tpport_t controlPort = 0,
                       int pri = 0,
                       uint32 memberssize =
                       MembershipBookkeeping::defaultMembersHashSize,
                       RTPApplication& app = defaultApplication()
#if defined(_MSC_VER) && _MSC_VER >= 1300
            );
#else
        ):
        Thread(pri),
        TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
        (ia,dataPort,controlPort,memberssize,app)
        { }
#endif

        SingleThreadRTPSession(uint32 ssrc, const InetHostAddress& ia,
                               tpport_t dataPort = DefaultRTPDataPort,
                               tpport_t controlPort = 0,
                               int pri = 0,
                               uint32 memberssize =
                               MembershipBookkeeping::defaultMembersHashSize,
                               RTPApplication& app = defaultApplication()
#if defined(_MSC_VER) && _MSC_VER >= 1300
        );
#else
    ):
    Thread(pri),
    TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
    (ssrc, ia,dataPort,controlPort,memberssize,app)
{ }
#endif

SingleThreadRTPSession(const InetMcastAddress& ia,
               tpport_t dataPort = DefaultRTPDataPort,
               tpport_t controlPort = 0,
               int pri = 0,
               uint32 memberssize =
               MembershipBookkeeping::defaultMembersHashSize,
               RTPApplication& app = defaultApplication(),
               uint32 iface = 0
#if defined(_MSC_VER) && _MSC_VER >= 1300
           );
#else
        ):
        Thread(pri),
        TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
        (ia,dataPort,controlPort,memberssize,app,iface)
        { }
#endif

SingleThreadRTPSession(uint32 ssrc, const InetMcastAddress& ia,
               tpport_t dataPort = DefaultRTPDataPort,
               tpport_t controlPort = 0,
               int pri = 0,
               uint32 memberssize =
               MembershipBookkeeping::defaultMembersHashSize,
               RTPApplication& app = defaultApplication(),
               uint32 iface = 0
#if defined(_MSC_VER) && _MSC_VER >= 1300
                      );
#else
                ):
                Thread(pri),
                TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>
                (ssrc,ia,dataPort,controlPort,memberssize,app,iface)
{ }
#endif


~SingleThreadRTPSession()
{
    if (isRunning()) {
        disableStack(); Thread::join();
    }
}

#if defined(_MSC_VER) && _MSC_VER >= 1300
virtual void startRunning();
#else
/**
 * Activate stack and start service thread.
 **/
void
startRunning()
{ enableStack(); Thread::start(); }
#endif


protected:
inline void disableStack(void)
{TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}

inline void enableStack(void)
{TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}

inline microtimeout_t getSchedulingTimeout(void)
{return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}

inline void controlReceptionService(void)
{TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}

inline void controlTransmissionService(void)
{TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}

inline timeval getRTCPCheckInterval(void)
{return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();}

inline size_t dispatchDataPacket(void)
{return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();}

#if defined(_MSC_VER) && _MSC_VER >= 1300
virtual void run(void);

virtual void timerTick(void);

virtual bool isPendingData(microtimeout_t timeout);
#else

virtual void timerTick(void)
{return;}

virtual bool isPendingData(microtimeout_t timeout)
{return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}

/**
 * Single runnable method for this RTP stacks, schedules
 * outgoing and incoming RTP data and RTCP packets.
 **/
virtual void run(void)
{
    microtimeout_t timeout = 0;
    while ( ServiceQueue::isActive() ) {
        if ( timeout < 1000 ){ // !(timeout/1000)
            timeout = getSchedulingTimeout();
        }
        controlReceptionService();
        controlTransmissionService();
        microtimeout_t maxWait =
            timeval2microtimeout(getRTCPCheckInterval());
        // make sure the scheduling timeout is
        // <= the check interval for RTCP
        // packets
        timeout = (timeout > maxWait)? maxWait : timeout;
        if ( timeout < 1000 ) { // !(timeout/1000)
            dispatchDataPacket();
            timerTick();
        } else {
            if ( isPendingData(timeout/1000) ) {
                                if (ServiceQueue::isActive()) { // take in only if active
                                    takeInDataPacket();
                                }
            }
            timeout = 0;
        }
    }
    dispatchBYE("GNU ccRTP stack finishing.");
//        Thread::exit();
}

#endif

inline size_t takeInDataPacket(void)
{return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}

inline size_t dispatchBYE(const std::string &str)
{return TRTPSessionBase<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
};

/**
 * @typedef RTPSession
 *
 * Uses two pairs of sockets for RTP data and RTCP
 * transmission/reception.
 *
 * @short UDP/IPv4 RTP Session scheduled by one thread of execution.
 **/
typedef SingleThreadRTPSession<> RTPSession;

/**
 * @typedef RTPSocket
 *
 * Alias for RTPSession.
 **/
typedef RTPSession RTPSocket;

/**
 * @typedef SymmetricRTPSession
 *
 * Uses one pair of sockets, (1) for RTP data and (2) for RTCP
 * transmission/reception.
 *
 * @short Symmetric UDP/IPv4 RTP session scheduled by one thread of execution.
 **/
typedef SingleThreadRTPSession<SymmetricRTPChannel,
                   SymmetricRTPChannel> SymmetricRTPSession;

#ifdef  CCXX_IPV6

/**
 * @class RTPSessionBaseIPV6
 *
 * Generic RTP protocol stack for exchange of realtime data.  This
 * stack uses the concept of packet send and receive queues to schedule
 * and buffer outgoing packets and to arrange or reorder incoming packets
 * as they arrive.
 *
 * This is a template class that allows customization of two aspects:
 * the underlying network and the control protocol. The RTPDataChannel
 * and RTCPChannel template parameters specify the socket types to
 * use. The ServiceQueue template parameter specify which packet queue
 * is used.
 *
 * RTPSessionBase objects do not have any threading policy, thus
 * allowing to customize this aspect in derived classes (see
 * SingleThreadRTPSession or RTPSessionPoolBase).
 *
 * @author David Sugar <dyfet@ostel.com>
 * @short RTP protocol stack based on Common C++.
 **/
template <class RTPDataChannel = DualRTPUDPIPv6Channel,
      class RTCPChannel = DualRTPUDPIPv6Channel,
      class ServiceQueue = AVPQueue>
class __EXPORT TRTPSessionBaseIPV6 : public ServiceQueue
{
public:
/**
 * Builds a session waiting for packets in a host address.
 *
 * @param ia Network address this socket is to be bound.
 * @param dataPort Transport port the data socket is to be bound.
 * @param controlPort Transport port the control socket is to be bound.
 * @param membersSize Initial size of the membership table.
 * @param app Application this session is associated to.
 * */
TRTPSessionBaseIPV6(const IPV6Host& ia, tpport_t dataPort,
    tpport_t controlPort, uint32 membersSize,
    RTPApplication& app) :
    ServiceQueue(membersSize,app)
{ build(ia,dataPort,controlPort); }

    /**
     * Builds a session with the specified ssrc identifier for the
     * local source.
     *
     * @param ssrc SSRC identifier for the local source.
     * @param ia Network address this socket is to be bound.
     * @param dataPort Transport port the data socket is to be bound.
     * @param controlPort Transport port the control socket is to be bound.
     * @param membersSize Initial size of the membership table.
     * @param app Application this session is associated to.
     **/
    TRTPSessionBaseIPV6(uint32 ssrc,
                const IPV6Host& ia,
                tpport_t dataPort, tpport_t controlPort,
                uint32 membersSize, RTPApplication& app):
        ServiceQueue(ssrc,membersSize,app)
        { build(ia,dataPort,controlPort); }

    /**
     * Builds a session waiting for packets in a multicast address.
     * TODO: ssrc constructor for multicast!
     *
     * @param ia Multicast address this socket is to be bound.
     * @param dataPort Transport port the data socket is to be bound.
     * @param controlPort Transport port the control socket is to be bound.
     * @param membersSize Initial size of the membership table.
     * @param app Application this session is associated to.
     * @param iface Index (from 0 to n) of network interface to join to
     * multicast group.
     **/
    TRTPSessionBaseIPV6(const IPV6Multicast& ia, tpport_t dataPort,
                tpport_t controlPort, uint32 membersSize,
                RTPApplication& app, uint32 iface) :
        ServiceQueue(membersSize,app)
        { build(ia,dataPort,controlPort,iface); }

    /**
     * Builds a session waiting for packets in a multicast
     * address, with the specified ssrc identifier for the local
     * source.
     *
     * @param ssrc SSRC identifier for the local source.
     * @param ia Multicast address this socket is to be bound.
     * @param dataPort Transport port the data socket is to be bound.
     * @param controlPort Transport port the control socket is to be bound.
     * @param membersSize Initial size of the membership table.
     * @param app Application this session is associated to.
     * @param iface Index (from 0 to n) of network interface to join to
     * multicast group.
     **/
    TRTPSessionBaseIPV6(uint32 ssrc,
                const IPV6Multicast& ia, tpport_t dataPort,
                tpport_t controlPort, uint32 membersSize,
                RTPApplication& app, uint32 iface) :
        ServiceQueue(ssrc,membersSize,app)
        { build(ia,dataPort,controlPort,iface); }

    virtual size_t dispatchBYE(const std::string &str)
        {
            return QueueRTCPManager::dispatchBYE(str);
        }

    inline virtual
    ~TRTPSessionBaseIPV6()
        {
            endSocket();
        }

    inline RTPDataChannel *getDSO(void)
        {return dso;}

protected:
    /**
     * @param timeout maximum timeout to wait, in microseconds
     */
    inline bool
    isPendingData(microtimeout_t timeout)
        { return dso->isPendingRecv(timeout); }

    inline IPV6Host
    getDataSender(tpport_t *port = NULL) const
        { return dso->getSender(port); }

    inline size_t
    getNextDataPacketSize() const
        { return dso->getNextPacketSize(); }

    /**
     * Receive data from the data channel/socket.
     *
     * @param buffer Memory region to read to.
     * @param len Maximum number of octets to get.
     * @param na Source network address.
     * @param tp Source transport port.
     * @return Number of octets actually read.
     */
    inline size_t
    recvData(unsigned char* buffer, size_t len,
         IPV6Host& na, tpport_t& tp)
        { na = dso->getSender(tp); return dso->recv(buffer, len); }

        inline void
        setDataPeerIPV6(const IPV6Host &host, tpport_t port)
        { dso->setPeer(host,port); }

    /**
     * @param buffer memory region to write from
     * @param len number of octets to write
     */
    inline size_t
    sendDataIPV6(const unsigned char* const buffer, size_t len)
        { return dso->send(buffer, len); }

    inline SOCKET getDataRecvSocket() const
        { return dso->getRecvSocket(); }

    /**
     * @param timeout maximum timeout to wait, in microseconds
     * @return whether there are packets waiting to be picked
     */
        inline bool
    isPendingControl(microtimeout_t timeout)
        { return cso->isPendingRecv(timeout); }

    inline IPV6Host
    getControlSender(tpport_t *port = NULL) const
        { return cso->getSender(port); }

    /**
     * Receive data from the control channel/socket.
     *
     * @param buffer Buffer where to get data.
     * @param len Maximum number of octets to get.
     * @param na Source network address.
     * @param tp Source transport port.
     * @return Number of octets actually read.
     **/
        inline size_t
    recvControl(unsigned char *buffer, size_t len,
            IPV6Host& na, tpport_t& tp)
        { na = cso->getSender(tp); return cso->recv(buffer,len); }

        inline void
        setControlPeerIPV6(const IPV6Host &host, tpport_t port)
        { cso->setPeer(host,port); }

    /**
     * @return number of octets actually written
     * @param buffer
     * @param len
     */
        inline size_t
    sendControl(const unsigned char* const buffer, size_t len)
        { return cso->send(buffer,len); }

    inline SOCKET getControlRecvSocket() const
        { return cso->getRecvSocket(); }

    inline void
    endSocket()
        {
            dso->endSocket();
            cso->endSocket();
            if (dso) delete dso;
            dso = NULL;
            if (cso) delete cso;
            cso = NULL;
        }

private:
    void
    build(const IPV6Host& ia, tpport_t dataPort,
          tpport_t controlPort)
        {
            if ( 0 == controlPort ) {
                dataBasePort = even_port(dataPort);
                controlBasePort = dataBasePort + 1;
            } else {
                dataBasePort = dataPort;
                controlBasePort = controlPort;
            }
            dso = new RTPDataChannel(ia,dataBasePort);
            cso = new RTCPChannel(ia,controlBasePort);
        }

    void
    build(const IPV6Multicast& ia, tpport_t dataPort,
          tpport_t controlPort, uint32 iface)
        {
            if ( 0 == controlPort ) {
                dataBasePort = even_port(dataPort);
                controlBasePort = dataBasePort + 1;
            } else {
                dataBasePort = dataPort;
                controlBasePort = controlPort;
            }
            dso = new RTPDataChannel(IPV6Host("0.0.0.0"),dataBasePort);
            cso = new RTCPChannel(IPV6Host("0.0.0.0"),controlBasePort);
            joinGroup(ia,iface);
        }

    /**
     * Join a multicast group.
     *
     * @param ia address of the multicast group
     * @return error code from the socket operation
     */
    inline Socket::Error
    joinGroup(const IPV6Multicast& ia, uint32 iface)
        {
            Socket::Error error  = dso->setMulticast(true);
            if ( error ) return error;
            error = dso->join(ia,iface);
            if ( error ) return error;
            error = cso->setMulticast(true);
            if ( error ) {
                dso->drop(ia);
                return error;
            }
            error = cso->join(ia,iface);
            if ( error ) {
                dso->drop(ia);
                return error;
            }
            return Socket::errSuccess;
        }

    /**
     * Leave a multicast group.
     *
     * @param ia address of the multicast group
     * @return error code from the socket operation
     */
    inline Socket::Error
    leaveGroup(const IPV6Multicast& ia)
        {
            Socket::Error error = dso->setMulticast(false);
            if ( error ) return error;
            error = dso->leaveGroup(ia);
            if ( error ) return error;
            error = cso->setMulticast(false);
            if ( error ) return error;
            return cso->leaveGroup(ia);
        }

    /**
     * Set the value of the TTL field in the sent packets.
     *
     * @param ttl Time To Live
     * @return error code from the socket operation
     */
    inline Socket::Error
    setMcastTTL(uint8 ttl)
        {
            Socket::Error error = dso->setMulticast(true);
            if ( error ) return error;
            error = dso->setTimeToLive(ttl);
            if ( error ) return error;
            error = cso->setMulticast(true);
            if ( error ) return error;
            return cso->setTimeToLive(ttl);
        }

    /**
     * Ensure a port number is odd. If it is an even number, return
     * the next lower (odd) port number.
     *
     * @param port number to filter
     * @return filtered (odd) port number
     */
    inline tpport_t
    odd_port(tpport_t port)
        { return (port & 0x01)? (port) : (port - 1); }

    /**
     * Ensure a port number is even. If it is an odd number, return
     * the next lower (even) port number.
     *
     * @param port number to filter
     * @return filtered (even) port number
     */
    inline tpport_t
    even_port(tpport_t port)
        { return (port & 0x01)? (port - 1) : (port); }

    tpport_t dataBasePort;
    tpport_t controlBasePort;

protected:
    RTPDataChannel* dso;
    RTCPChannel* cso;
    friend class RTPSessionBaseHandler;
};

/**
 * @class SingleThreadRTPSessionIPV6
 *
 * This template class adds the threading aspect to the RTPSessionBase
 * template in one of the many possible ways. It inherits from a
 * single execution thread that schedules sending of outgoing packets
 * and receipt of incoming packets.
 *
 * @author David Sugar <dyfet@gnutelephony.org>
 **/
template
<class RTPDataChannel = DualRTPUDPIPv6Channel,
 class RTCPChannel = DualRTPUDPIPv6Channel,
 class ServiceQueue = AVPQueue>
class __EXPORT SingleThreadRTPSessionIPV6 :
    protected Thread,
    public TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
{
public:
    SingleThreadRTPSessionIPV6(const IPV6Host& ia,
                   tpport_t dataPort = DefaultRTPDataPort,
                   tpport_t controlPort = 0,
                   int pri = 0,
                   uint32 memberssize =
                   MembershipBookkeeping::defaultMembersHashSize,
                   RTPApplication& app = defaultApplication()
#if defined(_MSC_VER) && _MSC_VER >= 1300
        );
#else
    ):
    Thread(pri),
    TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
    (ia,dataPort,controlPort,memberssize,app)
{ }
#endif

SingleThreadRTPSessionIPV6(const IPV6Multicast& ia,
               tpport_t dataPort = DefaultRTPDataPort,
               tpport_t controlPort = 0,
               int pri = 0,
               uint32 memberssize =
               MembershipBookkeeping::defaultMembersHashSize,
               RTPApplication& app = defaultApplication(),
               uint32 iface = 0
#if defined(_MSC_VER) && _MSC_VER >= 1300
    );
#else
        ):
        Thread(pri),
        TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>
        (ia,dataPort,controlPort,memberssize,app,iface)
{ }
#endif

~SingleThreadRTPSessionIPV6()
{
    if (isRunning()) {
        disableStack(); Thread::join();
    }
}

#if defined(_MSC_VER) && _MSC_VER >= 1300
virtual void startRunning();
#else
/**
 * Activate stack and start service thread.
 **/
void
startRunning()
{ enableStack(); Thread::start(); }
#endif


protected:
inline void enableStack(void)
{TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::enableStack();}

inline void disableStack(void)
{TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::disableStack();}

inline microtimeout_t getSchedulingTimeout(void)
{return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::getSchedulingTimeout();}

inline void controlReceptionService(void)
{TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::controlReceptionService();}

inline void controlTransmissionService(void)
{TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::controlTransmissionService();}

inline timeval getRTCPCheckInterval(void)
{return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::getRTCPCheckInterval();}

inline size_t dispatchDataPacket(void)
{return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchDataPacket();}

#if defined(_MSC_VER) && _MSC_VER >= 1300
virtual void run(void);

virtual void timerTick(void);

virtual bool isPendingData(microtimeout_t timeout);
#else

virtual void timerTick(void)
{return;}

virtual bool isPendingData(microtimeout_t timeout)
{return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::isPendingData(timeout);}

/**
 * Single runnable method for this RTP stacks, schedules
 * outgoing and incoming RTP data and RTCP packets.
 **/
virtual void run(void)
{
    microtimeout_t timeout = 0;
    while ( ServiceQueue::isActive() ) {
        if ( timeout < 1000 ){ // !(timeout/1000)
            timeout = getSchedulingTimeout();
        }
        controlReceptionService();
        controlTransmissionService();
        microtimeout_t maxWait =
            timeval2microtimeout(getRTCPCheckInterval());
        // make sure the scheduling timeout is
        // <= the check interval for RTCP
        // packets
        timeout = (timeout > maxWait)? maxWait : timeout;
        if ( timeout < 1000 ) { // !(timeout/1000)
            dispatchDataPacket();
            timerTick();
        } else {
            if ( isPendingData(timeout/1000) ) {
                takeInDataPacket();
            }
            timeout = 0;
        }
    }
    dispatchBYE("GNU ccRTP stack finishing.");
        Thread::exit();
}

#endif

inline size_t takeInDataPacket(void)
{return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::takeInDataPacket();}

inline size_t dispatchBYE(const std::string &str)
{return TRTPSessionBaseIPV6<RTPDataChannel,RTCPChannel,ServiceQueue>::dispatchBYE(str);}
};

/**
 * @typedef RTPSession
 *
 * Uses two pairs of sockets for RTP data and RTCP
 * transmission/reception.
 *
 * @short UDP/IPv6 RTP Session scheduled by one thread of execution.
 **/
typedef SingleThreadRTPSessionIPV6<> RTPSessionIPV6;

/**
 * @typedef RTPSocket
 *
 * Alias for RTPSession.
 **/
typedef RTPSessionIPV6 RTPSocketIPV6;

/**
 * @typedef SymmetricRTPSession
 *
 * Uses one pair of sockets, (1) for RTP data and (2) for RTCP
 * transmission/reception.
 *
 * @short Symmetric UDP/IPv6 RTP session scheduled by one thread of execution.
 **/
 typedef SingleThreadRTPSessionIPV6<SymmetricRTPChannelIPV6,
                    SymmetricRTPChannelIPV6> SymmetricRTPSessionIPV6;


#endif

/** @}*/ // sessions

END_NAMESPACE

#endif  //CCXX_RTP_RTP_H_

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