/* ------------------------------------------------------------------
 * Copyright (C) 1998-2009 PacketVideo
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
 * express or implied.
 * See the License for the specific language governing permissions
 * and limitations under the License.
 * -------------------------------------------------------------------
 */
#ifndef PVRTSP_CLIENT_ENGINE_NODE_H
#define PVRTSP_CLIENT_ENGINE_NODE_H


#ifndef OSCL_BASE_H_INCLUDED
#include "oscl_base.h"
#endif

#ifndef OSCL_UTF8CONV_H
#include "oscl_utf8conv.h"
#endif

#ifndef OSCL_ERROR_CODES_H_INCLUDED
#include "oscl_error_codes.h"
#endif

#ifndef OSCL_SCHEDULER_AO_H_INCLUDED
#include "oscl_scheduler_ao.h"
#endif

#ifndef OSCL_SOCKET_TYPES_H_INCLUDED
#include "oscl_socket_types.h"
#endif

#ifndef OSCL_SOCKET_H_INCLUDED
#include "oscl_socket.h"
#endif

#ifndef OSCL_DNS_H_INCLUDED
#include "oscl_dns.h"
#endif

#ifndef OSCL_STRING_CONTAINERS_H_INCLUDED
#include "oscl_string_containers.h"
#endif

#ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
#include "pvmf_media_clock.h"
#endif

#ifndef OSCL_TIMER_H_INCLUDED
#include "oscl_timer.h"
#endif

#ifndef PVMF_FORMAT_TYPE_H_INCLUDED
#include "pvmf_format_type.h"
#endif

#ifndef PVMF_NODE_INTERFACE_H_INCLUDED
#include "pvmf_node_interface.h"
#endif

#ifndef PVMF_NODE_UTILS_H_INCLUDED
#include "pvmf_node_utils.h"
#endif

#ifndef OSCL_PRIQUEUE_H_INCLUDED
#include "oscl_priqueue.h"
#endif

#ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED
#include "pvmf_simple_media_buffer.h"
#endif

#ifndef OSCL_MEM_MEMPOOL_H_INCLUDED
#include "oscl_mem_mempool.h"
#endif

#ifndef PVLOGGER_H_INCLUDED
#include "pvlogger.h"
#endif

#ifndef PVRTSP_ENGINE_NODE_EXTENSION_INTERFACE_H_INCLUDED
#include "pvrtspenginenodeextensioninterface.h"
#endif

#ifndef RTSP_PAR_COM_MESSAGE_DS_H_
#include "rtsp_par_com_message.h"
#endif

#ifndef RTSP_PARSER_H_
#include "rtsp_parser.h"
#endif

#ifndef SDP_PARSER_H
#include "sdp_parser.h"
#endif

#ifndef PVMF_RTSP_PORT_H_INCLUDED
#include "pvrtsp_client_engine_port.h"
#endif

#ifndef OSCL_FILEIO_H_INCLUDED
#include "oscl_file_io.h"
#endif

#ifndef PVMF_STREAMING_REAL_INTERFACES_INCLUDED
#include "pvmf_streaming_real_interfaces.h"
#endif

#ifndef PAYLOAD_PARSER_H_INCLUDED
#include "payload_parser.h"
#endif

#ifndef PVMF_SM_CONFIG_H_INCLUDED
#include "pvmf_sm_config.h"
#endif

//Default vector reserve size
#define PVMF_RTSP_ENGINE_NODE_COMMAND_VECTOR_RESERVE 10

//Starting value for command IDs
#define PVMF_RTSP_ENGINE_NODE_COMMAND_ID_START 6000

#define MAX_TOTAL_TRACKS 4 /* maximum number of channels per session */

//The RTSP state enumeration
typedef enum
{
    STATE_INIT,
    STATE_READY,
    STATE_PLAYING,
    //STATE_RECORDING
} SessionState;

typedef struct _DataChannelInfo
{
    uint8 *hexSID;

    bool   ssrc_is_set;
    uint32 ssrc;

    bool   seqbase_is_set;
    uint32 seq;

    bool   rtptime_is_set;
    uint32 rtptime;

    int32  offset;
    uint32 timescale;
    uint32 rtcp_interval;
} DataChannelInfo;

//memory allocator type for this node.
typedef OsclMemAllocator PVRTSPEngineNodeAllocator;

class SessionInfo
{
    public:
        //bool sdpFlag;             //Used to make sure that we read into the mediainfo array after it has been assigned
        //SDP_ERROR_CODE sdpErrorCode;            //Saves the value returned from the sdp parser

        OSCL_HeapString<PVRTSPEngineNodeAllocator> iSessionURL;
        OSCL_HeapString<PVRTSPEngineNodeAllocator> iContentBaseURL;//Per session control URL from content base field

        OSCL_HeapString<PVRTSPEngineNodeAllocator> iServerName; //could be either DNS or ip address

        OSCL_HeapString<PVRTSPEngineNodeAllocator> iProxyName;  //could be either DNS or ip address
        uint32  iProxyPort;

        OsclNetworkAddress iSrvAdd;

        bool bExternalSDP;          //true if got SDP through external(NOT DESCRIBE) methods

        RtspRangeType   iReqPlayRange;
        RtspRangeType   iActPlayRange;

        OsclRefCounterMemFrag   pSDPBuf;

        OsclSharedPtr<SDPInfo>  iSDPinfo;
        //SDP_Parser *iSDPparser;       //Pointer to the SDP_Parser class object
        Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> iSelectedStream;

        //Form the track to channel association table. This table is used while
        //interacting with the media buffer. This table is needed to convert from an index
        //based on the number of tracks in the SDP to an index into the number of tracks
        //actually selected. For eg, the SDP might have 5 media tracks, but the number of tracks
        //that get selected could be 2. If the first track that gets selected corresponds to the third
        //track in the SDP list, then the mapping would be 2 -> 0. Similarly, if the second track that
        //gets selected is the fifth in the SDP list, the mapping would be 4 -> 1.
        //All indices begin from 0.
        /*
        for(int ii = 0; ii < numberOfChannels; ii++)
        {
            int sdp_track_id = pSessionInfo->trackSelectionList->getTrackIndex(ii);
            pSessionInfo->channel_tbl[sdp_track_id] = ii;
        }
        */
        int number_of_channels;                 //Used for interaction with the media buffer class
        int channel_tbl[MAX_TOTAL_TRACKS];      //Index from SDP track IDs to tracks actually selected

        OSCL_HeapString<PVRTSPEngineNodeAllocator> iSID;    //alphanumeric session ID

        //OsclMemoryFragment pImgBuf;

        bool serverReplyFlag;           //Used for communication between the PVStream modules (network module and the task scheduler)
        bool getStateFlag;              //Used to ensure that the PE's main loop has been called
        bool pvServerIsSetFlag;             //Used to indicate if we are streaming from PVServer or not
        bool tSIDIsSetFlag;             //Used to send session id from second SETUP request
        uint32 iServerVersionNumber;    // Version number of PVSS
        int32 prerollDuration;                  //Saves the jitter buffer size

        int32 fwp_counter;              //Id of the first returned firewall packet
        int32 rtt;                              //Saves the round trip time for firewall exchange
        uint32 roundTripDelay;                   //Saves the round trip delay for a DESCRIBE request
        uint64 clientServerDelay;                //Saves the client server delay during a DESCRIBE request

        bool pipeLineFlag;                      //Used to indicate a pipe lined request

        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iUserAgent;
        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iUserNetwork;
        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iDeviceInfo;

        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iUserID;
        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iAuthentication;
        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iExpiration;
        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iApplicationSpecificString;
        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iVerification;
        OSCL_HeapString<PVRTSPEngineNodeAllocator>  iSignature;

        enum PVRTSPStreamingType iStreamingType;

        bool                                       iSessionCompleted;
        void UpdateSessionCompletionStatus(bool aSessionCompleted)
        {
            iSessionCompleted = aSessionCompleted;
        }

    public:
        SessionInfo():
                iProxyPort(0),
                bExternalSDP(false),
                pvServerIsSetFlag(false),
                iServerVersionNumber(0),
                roundTripDelay(0),
                iSessionCompleted(false)
        {
            iUserAgent += _STRLIT_CHAR("PVPlayer ");
            iReqPlayRange.format = RtspRangeType::INVALID_RANGE;
        };

} ;

class RTSPNodeMemDestructDealloc : public OsclDestructDealloc
{
    public:
        virtual void destruct_and_dealloc(OsclAny *ptr)
        {
            OSCL_FREE(ptr);
        }
};

typedef PVMFGenericNodeCommand<PVRTSPEngineNodeAllocator> PVRTSPEngineCommandBase;

enum TPVMFRtspNodeCommand //TPVMFGenericNodeCommand
{
    PVMF_RTSP_NODE_ERROR_RECOVERY = PVMF_GENERIC_NODE_COMMAND_LAST + 1
    , PVMF_RTSP_NODE_CANCELALLRESET
};
class PVRTSPEngineCommand: public PVRTSPEngineCommandBase
{
    public:

        void Construct(PVMFSessionId s, int32 cmd, int32 arg1, int32 arg2, int32& arg3, \
                       const OsclAny*aContext)
        {
            PVRTSPEngineCommandBase::Construct(s, cmd, aContext);
            iParam1 = (OsclAny*)arg1;
            iParam2 = (OsclAny*)arg2;
            iParam3 = (OsclAny*) & arg3;
        }
        void Parse(int32&arg1, int32&arg2, int32*&arg3)
        {
            arg1 = (int32)iParam1;
            arg2 = (int32)iParam2;
            arg3 = (int32*)iParam3;
        }
        virtual bool hipri()
        {
            if (iCmd == PVMF_RTSP_NODE_ERROR_RECOVERY)
                return true;

            return PVRTSPEngineCommandBase::hipri();
        }

        /*
        PVMFSessionId iCmdSid;
        int32 iCmdId;
        TPVMFGenericNodeCommand iCmdType;
        OsclAny* iContext;
        PVMFPortInterface* iPort;
        OsclAny* iData1;
        OsclAny* iData2;
        OsclAny* iData3;
        */
    private:
        //PVRTSPEngineCommand(const PVRTSPEngineCommand& aCmd);
};

//Command queue type
typedef PVMFNodeCommandQueue<PVRTSPEngineCommand, PVRTSPEngineNodeAllocator> PVRTSPEngineNodeCmdQ;

class PVRTSPGenericMessageCompareLess
{
    public:
        /**
        * The algorithm used in OsclPriorityQueue needs a compare function
        * that returns true when A's priority is less than B's
        * @return true if A's priority is less than B's, else false
            */
        int compare(RTSPGenericMessage* a, RTSPGenericMessage* b) const
        {
            return (PVRTSPGenericMessageCompareLess::GetPriority(*a) > PVRTSPGenericMessageCompareLess::GetPriority(*b));
        }

        /**
        * Returns the priority of each command
        * @return A 0-based priority number. A lower number indicates lower priority.
        */
        static int GetPriority(RTSPGenericMessage &aCmd)
        {//for cseq numbers, the low numbers come first. so higher priority
            return aCmd.cseq;
        }
};

class GetPostCorrelationObject
{
    public:
        // factory method
        static GetPostCorrelationObject *create(OSCL_TCHAR* aFileName = NULL);
        // destructor
        ~GetPostCorrelationObject();

        // get post correlation value
        uint8 get() const
        {
            return iGetPostCorrelation;
        }
        // increase get post correlation value by 1 within [1, 255]
        bool update();

    private:
        // constructor
        GetPostCorrelationObject()
        {
            ;
        }
        bool construct(OSCL_TCHAR* aFileName);
        void closeFile();
        bool writeToFile();

    private:
        uint8 iGetPostCorrelation;
        bool iFileCreated; // check for the file creation

        // File IO stuff
        Oscl_FileServer iFs;
        Oscl_File iGetPostCorrelationFile;
};

class PVRTSPEngineNode
        : public PVInterface,
        public PVMFNodeInterface,
        public OsclTimerObject,
        public OsclSocketObserver,
        public OsclDNSObserver,
        public OsclTimerObserver,
        public OsclMemPoolFixedChunkAllocatorObserver
{
    public:
        OSCL_IMPORT_REF PVRTSPEngineNode(int32 aPriority);
        OSCL_IMPORT_REF virtual ~PVRTSPEngineNode();

        //************ begin PVMFNodeInterface

        OSCL_IMPORT_REF virtual  PVMFStatus ThreadLogon();
        OSCL_IMPORT_REF virtual  PVMFStatus ThreadLogoff();

        /**
        GetCapability can be invoked only when after a node is initialized
        **/
        OSCL_IMPORT_REF virtual  PVMFStatus GetCapability(PVMFNodeCapability& aNodeCapability);

        /**
         * Returns a list of ports currently available in the node that meet the filter criteria
         * We can add fancier iterators and filters as needed.
         * For now we return all the available ports.  If no ports are present, NULL is returned
         **/
        OSCL_IMPORT_REF virtual  PVMFPortIter* GetPorts(const PVMFPortFilter* aFilter = NULL);

        /**
         * This API is to allow for extensibility of the PVMF Node interface.
         * It allows a caller to ask for all UUIDs associated with a particular MIME type.
         * If interfaces of the requested MIME type are found within the system, they are added
         * to the UUIDs array.
         *
         * Also added to the UUIDs array will be all interfaces which have the requested MIME
         * type as a base MIME type.  This functionality can be turned off.
         *
         * @param aMimeType The MIME type of the desired interfaces
         * @param aUuids A vector to hold the discovered UUIDs
         * @param aExactUuidsOnly Turns on/off the retrival of UUIDs with aMimeType as a base type
         * @param aContext Optional opaque data to be passed back to user with the command response
         * @returns A unique command id for asynchronous completion
         */
        OSCL_IMPORT_REF virtual PVMFCommandId QueryUUID(PVMFSessionId aSession
                , const PvmfMimeString& aMimeType
                , Oscl_Vector<PVUuid, PVRTSPEngineNodeAllocator>& aUuids
                , bool aExactUuidsOnly = false
                                         , const OsclAny* aContext = NULL);

        /**
         * This API is to allow for extensibility of the PVMF Node interface.
         * It allows a caller to ask for an instance of a particular interface object to be returned.
         * The mechanism is analogous to the COM IUnknown method.  The interfaces are identified with
         * an interface ID that is a UUID as in DCE and a pointer to the interface object is
         * returned if it is supported.  Otherwise the returned pointer is NULL.
         *
         * @param aUuid The UUID of the desired interface
         * @param aInterfacePtr The output pointer to the desired interface
         * @param aContext Optional opaque data to be passed back to user with the command response
         * @returns A unique command id for asynchronous completion
         */
        OSCL_IMPORT_REF virtual PVMFCommandId QueryInterface(PVMFSessionId aSession
                , const PVUuid& aUuid
                , PVInterface*& aInterfacePtr
                , const OsclAny* aContext = NULL);

        /**
         * Requests the node to return a port meeting certain criteria for format types and buffering
         * capabilities.  The node may return a reference to an already created unused port or it may dynamically
         * create one if it has the capability to do so.  Since there might be some port specific initializations
         * that might need to be done for ports created on demand, it will be most flexible to have this as an
         * asynchronous API.
         * A reference to the port interface is returned with the the command completion.  It is passed as an auto ptr
         * carrying opaque data that needs to be cast to PVMFPortInterface*
         * @exception PVMFErrNotSupported leaves if this is not supported.
         **/
        OSCL_IMPORT_REF virtual PVMFCommandId RequestPort(PVMFSessionId aSession
                , int32 aPortTag
                , const PvmfMimeString* aPortConfig = NULL
                                                      , const OsclAny* aContext = NULL);

        /**
         * Releases a port back to the owning node.
         * @exception PVMFErrArgument leaves if this node is not the owner.
         **/
        OSCL_IMPORT_REF virtual PVMFCommandId ReleasePort(PVMFSessionId aSession
                , PVMFPortInterface& aPort
                , const OsclAny* aContext = NULL);

        //Describe,
        OSCL_IMPORT_REF virtual PVMFCommandId Init(PVMFSessionId aSession
                , const OsclAny* aContext = NULL);

        OSCL_IMPORT_REF virtual PVMFCommandId Prepare(PVMFSessionId aSession,
                const OsclAny* aContext = NULL);

        //Setup, Firewall pkts exchange, Play
        /**
         * Causes the node to start servicing all connected ports.
         **/
        OSCL_IMPORT_REF virtual PVMFCommandId Start(PVMFSessionId aSession
                , const OsclAny* aContext = NULL);

        //Pause
        /**
         * Causes the node to pause servicing all connected ports without
         * discarding un-processed data.
         **/
        OSCL_IMPORT_REF virtual PVMFCommandId Pause(PVMFSessionId aSession
                , const OsclAny* aContext = NULL);

        //Teardown
        OSCL_IMPORT_REF virtual PVMFCommandId Stop(PVMFSessionId aSession
                , const OsclAny* aContext = NULL);

        /**
         * Resets the node.  The node should relinquish all resources that is has acquired as part of the
         * initialization process and should be ready to be deleted when this completes.
         **/
        OSCL_IMPORT_REF virtual PVMFCommandId Reset(PVMFSessionId aSession
                , const OsclAny* aContext = NULL);

        /**
         * Causes the node to stop servicing all connected ports as
         * soon as current data is processed.
         **/
        OSCL_IMPORT_REF virtual PVMFCommandId Flush(PVMFSessionId aSession
                , const OsclAny* aContext = NULL);


        /**
         * Cancel all pending requests. The current request being processed, if any, will also be aborted.
         *
         * @param aContextData Optional opaque data that will be passed back to the user with the command response
         * @returns A unique command id for asynchronous completion
         */
        OSCL_IMPORT_REF virtual PVMFCommandId CancelAllCommands(PVMFSessionId aSession
                , const OsclAny* aContextData = NULL);

        /**
         * Cancels pending command with the specified ID.
         *
         * @param aCmdId Command Id of the command to be cancelled
         * @param aContextData Optional opaque data that will be passed back to the user with the command response
         * @returns A unique command id for asynchronous completion
         */
        OSCL_IMPORT_REF virtual PVMFCommandId CancelCommand(PVMFSessionId aSession
                , PVMFCommandId aCmdId
                , const OsclAny* aContextData = NULL);

        /**
         * Ports call this API to report activity to the node.
         *
         * @param aActivity Information regarding the activity.
         */
        OSCL_IMPORT_REF void HandlePortActivity(const PVMFPortActivity& aActivity);

        //************ end PVMFNodeInterface

        //************ begin PVRTSPEngineNodeExtensionInterface
        OSCL_IMPORT_REF virtual void addRef();
        OSCL_IMPORT_REF virtual void removeRef(void);
        OSCL_IMPORT_REF virtual bool queryInterface(const PVUuid& uuid, PVInterface*& iface);

        OSCL_IMPORT_REF virtual PVMFStatus SetStreamingType(PVRTSPStreamingType aType = PVRTSP_3GPP_UDP);

        OSCL_IMPORT_REF virtual PVMFStatus SetSessionURL(OSCL_wString& aURL);

        OSCL_IMPORT_REF virtual PVMFStatus SetRtspProxy(OSCL_String& aRtspProxyName, uint32 aRtspProxyPort);
        OSCL_IMPORT_REF virtual PVMFStatus GetRtspProxy(OSCL_String& aRtspProxyName, uint32& aRtspProxyPort);

        OSCL_IMPORT_REF virtual PVMFStatus GetSDP(OsclRefCounterMemFrag& aSDPBuf);
        OSCL_IMPORT_REF virtual PVMFStatus SetSDPInfo(OsclSharedPtr<SDPInfo>& aSDPinfo, Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> &aSelectedStream);
        OSCL_IMPORT_REF virtual PVMFStatus GetServerInfo(PVRTSPEngineNodeServerInfo& aServerInfo);
        OSCL_IMPORT_REF virtual PVMFStatus GetStreamInfo(Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> &aSelectedStream);

        OSCL_IMPORT_REF virtual PVMFStatus GetUserAgent(OSCL_wString& aUserAgent);

        OSCL_IMPORT_REF virtual PVMFStatus SetClientParameters(OSCL_wString& aUserAgent,
                OSCL_wString&  aUserNetwork,
                OSCL_wString&  aDeviceInfo);

        OSCL_IMPORT_REF virtual bool IsRdtTransport();
        OSCL_IMPORT_REF virtual void SetPortRdtStreamId(PVMFPortInterface* pPort,
                int iRdtStreamId);

        OSCL_IMPORT_REF virtual void SetRealChallengeCalculator(IRealChallengeGen* pChallengeCalc);
        OSCL_IMPORT_REF virtual void SetRdtParser(IPayloadParser* pRdtParser);

        OSCL_IMPORT_REF virtual PVMFStatus SetAuthenticationParameters(OSCL_wString& aUserID,
                OSCL_wString& aAuthentication,
                OSCL_wString& aExpiration,
                OSCL_wString& aApplicationSpecificString,
                OSCL_wString& aVerification,
                OSCL_wString& aSignature);

        OSCL_IMPORT_REF virtual PVMFStatus SetRequestPlayRange(const RtspRangeType& aRange);
        OSCL_IMPORT_REF virtual PVMFStatus GetActualPlayRange(RtspRangeType& aRange);

        OSCL_IMPORT_REF virtual PVMFStatus SetKeepAliveMethod_timeout(int32 aTimeout = 0);
        OSCL_IMPORT_REF virtual PVMFStatus SetKeepAliveMethod_use_SET_PARAMETER(bool aUseSetParameter = false);
        OSCL_IMPORT_REF virtual PVMFStatus SetKeepAliveMethod_keep_alive_in_play(bool aKeepAliveInPlay = false);

        OSCL_IMPORT_REF virtual PVMFStatus GetKeepAliveMethod(int32 &aTimeout, bool &aUseSetParameter, bool &aKeepAliveInPlay);


        OSCL_IMPORT_REF virtual PVMFStatus GetRTSPTimeOut(int32 &aTimeout);
        OSCL_IMPORT_REF virtual PVMFStatus SetRTSPTimeOut(int32 aTimeout);

        //************ end PVRTSPEngineNodeExtensionInterface

        //************ begin OsclTimerObserver
        OSCL_IMPORT_REF virtual void TimeoutOccurred(int32 timerID, int32 timeoutInfo);

        //************ begin OsclSocketObserver
        OSCL_IMPORT_REF virtual void HandleSocketEvent(int32 aId, TPVSocketFxn aFxn, TPVSocketEvent aEvent, int32 aError);
        //************ end OsclSocketObserver

        //************ begin OsclDNSObserver
        OSCL_IMPORT_REF virtual void HandleDNSEvent(int32 aId, TPVDNSFxn aFxn, TPVDNSEvent aEvent, int32 aError);
        //************ end OsclDNSObserver

        //************ begin OsclMemPoolFixedChunkAllocatorObserver
        void freechunkavailable(OsclAny*);
        //************ end OsclMemPoolFixedChunkAllocatorObserver

        void UpdateSessionCompletionStatus(bool aSessionCompleted)
        {
            iSessionInfo.iSessionCompleted = aSessionCompleted;
        }

        bool IsSessionCompleted() const
        {
            return iSessionInfo.iSessionCompleted;
        }

        typedef struct _SocketEvent
        {
            int32           iSockId;
            TPVSocketFxn    iSockFxn;
            TPVSocketEvent  iSockEvent;
            int32           iSockError;
        } SocketEvent;

        enum PVRTSPEngineState
        {
            //for async request
            PVRTSP_ENGINE_NODE_STATE_IDLE,
            PVRTSP_ENGINE_NODE_STATE_DNS_RESOLVING,

            PVRTSP_ENGINE_NODE_STATE_CONNECT,
            PVRTSP_ENGINE_NODE_STATE_CONNECTING,

            PVRTSP_ENGINE_NODE_STATE_HTTP_CLOAKING_SETUP,

            PVRTSP_ENGINE_NODE_STATE_SEND_OPTIONS,
            PVRTSP_ENGINE_NODE_STATE_SEND_DESCRIBE,
            PVRTSP_ENGINE_NODE_STATE_OPTIONS_WAITING,
            PVRTSP_ENGINE_NODE_STATE_DESCRIBE_WAITING,

            PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE,
            PVRTSP_ENGINE_NODE_STATE_PROCESS_REST_SETUP,

            PVRTSP_ENGINE_NODE_STATE_SETUP_DONE,
            PVRTSP_ENGINE_NODE_STATE_WAIT_PLAY,

            PVRTSP_ENGINE_NODE_STATE_PLAY_DONE,
            PVRTSP_ENGINE_NODE_STATE_WAIT_PAUSE,
            PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE,

            PVRTSP_ENGINE_NODE_STATE_WAIT_STOP,

            PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK,

            PVRTSP_ENGINE_NODE_STATE_INVALID
        } iState;

    private:
        OsclSharedPtr<PVMFMediaDataImpl> AllocateMediaData(int32& errCode);
        Oscl_Vector<SocketEvent, PVRTSPEngineNodeAllocator> iSocketEventQueue;

        PVRTSPEngineNodeAllocator iAlloc;

        PVMFCommandId iCurrentCmdId;

        OsclSocketServ  *iSockServ;

//note: this class is for internal use only, but must be public to avoid ADS v1.2 compile error.
    public:
        //To keep track of current socket op
        class SocketState
        {
            public:
                SocketState()
                        : iPending(false)
                        , iCanceled(false)
                {}
                bool iPending;
                bool iCanceled;
                void Reset()
                {
                    iPending = iCanceled = false;
                }
        };

    private:

        //Container for a TCP socket that can connect, send, & recv.
        class SocketContainer
        {
            public:
                SocketContainer(): iSocket(NULL)
                {}
                OsclTCPSocket* iSocket;
                SocketState iConnectState;
                SocketState iSendState;
                SocketState iRecvState;
                SocketState iShutdownState;
                void Reset(OsclTCPSocket* aSock)
                {
                    iSocket = aSock;
                    iConnectState.Reset();
                    iSendState.Reset();
                    iRecvState.Reset();
                    iShutdownState.Reset();
                }
                bool IsBusy()
                {
                    return iSocket
                           && (iConnectState.iPending
                               || iSendState.iPending
                               || iRecvState.iPending
                               || iShutdownState.iPending);
                }
        };
        class DnsContainer
        {
            public:
                DnsContainer(): iDns(NULL)
                {}
                OsclDNS* iDns;
                SocketState iState;
                bool IsBusy()
                {
                    return (iDns
                            && iState.iPending);
                }
        };
        void SetSendPending(SocketContainer&);
        void SetRecvPending(SocketContainer&);

        SocketContainer iSendSocket, iRecvSocket;
        DnsContainer iDNS;

        //To keep track of socket reset sequence.
        enum TSocketCleanupState
        {
            ESocketCleanup_Idle
            , ESocketCleanup_CancelCurrentOp
            , ESocketCleanup_WaitOnCancel
            , ESocketCleanup_Shutdown
            , ESocketCleanup_WaitOnShutdown
            , ESocketCleanup_Delete
        };
        TSocketCleanupState iSocketCleanupState;

        //only for http cloaking, string to store the text to send until send completes
        OSCL_HeapString<PVRTSPEngineNodeAllocator> iRecvChannelMsg, iSendChannelMsg;

        RTSPParser *iRTSPParser;
        RTSPParser::ParserState iRTSPParserState;
        RTSPIncomingMessage iIncomingMsg;
        uint32 iOutgoingSeq;

        bool bNoRecvPending;//an Recv() is pending on RTSP socket
        bool bNoSendPending;//a Send() is pending on RTSP socket

        PVMFPortInterface* iTheBusyPort;
        //OsclMemoryFragment entityBody;            //Used to register with RTSP parser
        //OsclMemoryFragment embeddedDataMemory;    //Used to save embedded binary data

        SessionInfo iSessionInfo;

        PVLogger* iLogger;

        //uint8 iBufEmbedded[2048];
        //RTSPEntityBody iEmbeddedData;
        PVMFSharedMediaDataPtr  iEmbeddedDataPtr;
        // Reference counter for extension
        uint32 iExtensionRefCount;
        uint32 iNumRedirectTrials;

        //socket server will callback even if Cancel() is called
        //most likely this is the case for OsclDNS as well
        //But this is NOT the case for OsclTimer
        uint32  iNumHostCallback, iNumConnectCallback, iNumSendCallback, iNumRecvCallback;
        int BASE_REQUEST_ID;
        static const int REQ_SEND_SOCKET_ID;
        static const int REQ_RECV_SOCKET_ID;
        int REQ_TIMER_WATCHDOG_ID, REQ_TIMER_KEEPALIVE_ID;
        int REQ_DNS_LOOKUP_ID;


        const int DEFAULT_RTSP_PORT, DEFAULT_HTTP_PORT;

        //these three are in milliseconds
        const int TIMEOUT_CONNECT_AND_DNS_LOOKUP, TIMEOUT_SEND, TIMEOUT_RECV;
        const int TIMEOUT_SHUTDOWN;

        //these two are in seconds
        int TIMEOUT_WATCHDOG;
        const int TIMEOUT_WATCHDOG_TEARDOWN;
        int TIMEOUT_KEEPALIVE;
        const int RECOMMENDED_RTP_BLOCK_SIZE;

        int setupTrackIndex;
        bool bRepositioning;

        class PVRTSPErrorContext
        {
            public:
                SocketEvent     iErrSockEvent;
                PVRTSPEngineState   iErrState;
        };


        //temp string compose buffer for internal use RTSP_MAX_FULL_REQUEST_SIZE
        OsclMemoryFragment  iRTSPEngTmpBuf;
        OsclMemoryFragment  iEntityMemFrag;
        //OsclRefCounterMemFrag iEntityMemFrag;

        // Queue of commands for cancel
        PVRTSPEngineNodeCmdQ iCancelCmdQueue;
        // Queue of commands user requested
        PVRTSPEngineNodeCmdQ iPendingCmdQueue;

        //Queue for cmds which are running.
        //normally this node will not start processing one command
        //until the prior one is finished.  However, a hi priority
        //command such as Cancel must be able to interrupt a command
        //in progress.
        PVRTSPEngineNodeCmdQ iRunningCmdQueue;
        PVMFPortVector<PVMFRTSPPort, PVRTSPEngineNodeAllocator> iPortVector;
        /**
         * Queue holding port activity. Only incoming and outgoing msg activity are
         * put on the queue.  For each port, there should only be at most one activity
         * of each type on the queue.
         */
        Oscl_Vector<PVMFPortActivity, PVRTSPEngineNodeAllocator> iPortActivityQueue;
        PVMFNodeCapability iCapability;

        //OsclPriorityQueue<PVRTSPEngineCommand,PVRTSPEngineNodeAllocator,Oscl_Vector<PVRTSPEngineCommand,PVRTSPEngineNodeAllocator>,PVRTSPEngineCommandCompareLess> iPendingCmdQueue;
//  Oscl_Vector<PVRTSPEngineAsyncEvent, PVRTSPEngineNodeAllocator> iPendingEvents;

//  OsclPriorityQueue<RTSPIncomingMessage,PVRTSPEngineNodeAllocator,Oscl_Vector<RTSPIncomingMessage,PVRTSPEngineNodeAllocator>,PVRTSPGenericMessageCompareLess> iIncomingMsgQueue;
        OsclPriorityQueue<RTSPOutgoingMessage*, PVRTSPEngineNodeAllocator, Oscl_Vector<RTSPOutgoingMessage*, PVRTSPEngineNodeAllocator>, PVRTSPGenericMessageCompareLess> iOutgoingMsgQueue;
        RTSPOutgoingMessage* iSrvResponse;
        bool    bSrvRespPending;

        OsclTimer<PVRTSPEngineNodeAllocator>    *iWatchdogTimer;

        int32 iCurrentErrorCode;
        PVUuid iEventUUID;

        bool    bKeepAliveInPlay;
        RTSPMethod  iKeepAliveMethod;

        bool    bAddXStrHeader;

        OsclMemPoolResizableAllocator *iMediaDataResizableAlloc;
        PVMFSimpleMediaBufferCombinedAlloc *iMediaDataImplAlloc;

        /* Round trip delay calculation */
        PVMFTimebase_Tickcount iRoundTripClockTimeBase;

        int32   iErrorRecoveryAttempt;

        //uint8 iGetPostCorrelation;
        GetPostCorrelationObject *iGetPostCorrelationObject;
    private:
        PVRTSPEngineNode();
        PVRTSPEngineNode&  operator = (const PVRTSPEngineNode&);
        PVRTSPEngineNode(const PVRTSPEngineNode&);

        //OsclActiveObject
        virtual void Run();
        virtual OsclLeaveCode RunError(OsclLeaveCode aError);

        PVMFStatus sendSocketOutgoingMsg(SocketContainer &aSock, RTSPOutgoingMessage &aMsg);
        PVMFStatus sendSocketOutgoingMsg(SocketContainer &aSock, const uint8* aSendBuf, uint32 aSendLen);

        void ChangeExternalState(TPVMFNodeInterfaceState aNewState);

        // Handle command and data events
        PVMFCommandId AddCmdToQueue(PVRTSPEngineCommand& aCmd);

        bool ProcessCommand(PVRTSPEngineCommand& aCmd);
        bool rtspParserLoop(void);

        PVMFStatus DispatchCommand(PVRTSPEngineCommand& aCmd);
        void MoveCmdToCancelQueue(PVRTSPEngineCommand& aCmd);

        PVMFStatus DoInitNode(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoPrepareNode(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoStartNode(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoPauseNode(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoStopNode(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoResetNode(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoQueryUuid(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoQueryInterface(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoCancelCommand(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoCancelAllCommands(PVRTSPEngineCommand &aCmd);
        PVMFStatus DoFlush(PVRTSPEngineCommand &aCmd);

        PVMFStatus DoErrorRecovery(PVRTSPEngineCommand &aCmd);

        PVMFStatus DoRequestPort(PVRTSPEngineCommand &aCmd, PVMFRTSPPort* &aPort);
        PVMFStatus DoAddPort(int32 id, bool isMedia, int32 tag, PVMFRTSPPort* &aPort);
        PVMFStatus DoReleasePort(PVRTSPEngineCommand &aCmd);

        bool FlushPending();
        bool ProcessPortActivity();
        void QueuePortActivity(const PVMFPortActivity &aActivity);
        PVMFStatus ProcessOutgoingMsg(PVMFPortInterface* aPort);

        PVMFStatus SendRtspDescribe(PVRTSPEngineCommand &aCmd);
        PVMFStatus SendRtspSetup(PVRTSPEngineCommand &aCmd);
        PVMFStatus SendRtspPlay(PVRTSPEngineCommand &aCmd);
        PVMFStatus SendRtspPause(PVRTSPEngineCommand &aCmd);
        PVMFStatus SendRtspTeardown(PVRTSPEngineCommand &aCmd);

        void CommandComplete(PVRTSPEngineNodeCmdQ&,
                             PVRTSPEngineCommand&,
                             PVMFStatus, OsclAny* aData = NULL,
                             PVUuid* aEventUUID = NULL,
                             int32* aEventCode = NULL);

        bool parseURL(const OSCL_wString& aURL);
        bool parseURL(const char* aURL);


        void ChangeInternalState(PVRTSPEngineState aNewTask);
        PVMFStatus composeOptionsRequest(RTSPOutgoingMessage&);
        PVMFStatus composeDescribeRequest(RTSPOutgoingMessage&);
        PVMFStatus composeSetupRequest(RTSPOutgoingMessage &iMsg, StreamInfo &aSelected);
        PVMFStatus composePlayRequest(RTSPOutgoingMessage &iMsg);
        PVMFStatus composeStopRequest(RTSPOutgoingMessage &iMsg);
        PVMFStatus composePauseRequest(RTSPOutgoingMessage &iMsg);
        PVMFStatus composeKeepAliveRequest(RTSPOutgoingMessage &aMsg);

        PVMFStatus composeGetRequest(RTSPOutgoingMessage &iMsg);
        PVMFStatus composePostRequest(RTSPOutgoingMessage &iMsg);

        PVMFStatus processIncomingMessage(RTSPIncomingMessage &iIncomingMsg);
        PVMFStatus processServerRequest(RTSPIncomingMessage &aMsg);
        PVMFStatus processEntityBody(RTSPIncomingMessage &aMsg, OsclMemoryFragment &aEntityMemFrag);

        PVMFStatus processCommonResponse(RTSPIncomingMessage &aMsg);

        //should merge togather and move to jitter buffer
        PVMFStatus composeSessionURL(RTSPOutgoingMessage &aMsg);
        PVMFStatus composeMediaURL(int aTrackID, StrPtrLen &aMediaURI);

        //PVMFStatus processSDP(OsclMemoryFragment &aSDPBuf, SDPInfo &aSDPinfo);

        void ReportErrorEvent(PVMFEventType aEventType,
                              OsclAny* aEventData = NULL,
                              PVUuid* aEventUUID = NULL,
                              int32* aEventCode = NULL);
        void ReportInfoEvent(PVMFEventType aEventType,
                             OsclAny* aEventData = NULL,
                             PVUuid* aEventUUID = NULL,
                             int32* aEventCode = NULL);

        void MapRTSPCodeToEventCode(RTSPStatusCode aStatusCode,
                                    int32& aEventCode);
        //allocate aReqBufSize memory for iEmbeddedData
        bool PrepareEmbeddedDataMemory(uint32 aReqBufSize, OsclMemoryFragment &);
        bool DispatchEmbeddedData(uint32 aChannelID);
        // private members added for real support
        bool ibIsRealRDT;

        // realchallenge1 string returned by OPTIONS request
        OSCL_HeapString<OsclMemAllocator> iRealChallenge1;

        // realchallenge2 string to be sent in SETUP request
        OSCL_HeapString<OsclMemAllocator> iRealChallenge2;

        IRealChallengeGen* ipRealChallengeGen;
        IPayloadParser* ipRdtParser;

        // allocator for outgoing media frag groups
        PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>* ipFragGroupAllocator;
        OsclMemPoolFixedChunkAllocator* ipFragGroupMemPool;

        /////


        bool DispatchEmbeddedRdtData();
        bool ibBlockedOnFragGroups;
        //bool simpleHttpParser(const uint8 *aBuf, int32 &aLen, bool &aIsStatus200);

        PVMFStatus resetSocket(bool aImmediate = false);
        void clearOutgoingMsgQueue(void);
        void partialResetSessionInfo(void);

        bool clearEventQueue(void);

        void ResetSessionInfo(void);
        PVRTSPEngineNodeExtensionInterface* iExtensionInterface;
};

#endif //PVRTSP_CLIENT_ENGINE_NODE_H
