Home | History | Annotate | Download | only in src
      1 /* ------------------------------------------------------------------
      2  * Copyright (C) 1998-2009 PacketVideo
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
     13  * express or implied.
     14  * See the License for the specific language governing permissions
     15  * and limitations under the License.
     16  * -------------------------------------------------------------------
     17  */
     18 
     19 #ifndef PVMF_PROTOCOLENGINE_NODE_COMMON_H_INCLUDED
     20 #define PVMF_PROTOCOLENGINE_NODE_COMMON_H_INCLUDED
     21 
     22 #ifndef OSCL_MEM_MEMPOOL_H_INCLUDED
     23 #include "oscl_mem_mempool.h"
     24 #endif
     25 #ifndef PVMF_MEDIA_DATA_H_INCLUDED
     26 #include "pvmf_media_data.h"
     27 #endif
     28 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED
     29 #include "pvmf_simple_media_buffer.h"
     30 #endif
     31 #ifndef PVMF_META_DATA_TYPES_H_INCLUDED
     32 #include "pvmf_meta_data_types.h"
     33 #endif
     34 #ifndef PVMF_MEDIA_MSG_FORMAT_IDS_H_INCLUDED
     35 #include "pvmf_media_msg_format_ids.h"
     36 #endif
     37 #ifndef PVMI_DATASTREAMUSER_INTERFACE_H_INCLUDED
     38 #include "pvmi_datastreamuser_interface.h"
     39 #endif
     40 #ifndef PVLOGGER_H_INCLUDED
     41 #include "pvlogger.h"
     42 #endif
     43 #ifndef PVLOGGER_FILE_APPENDER_H_INCLUDED
     44 #include "pvlogger_file_appender.h"
     45 #endif
     46 #ifndef PVMF_DOWNLOAD_DATA_SOURCE_H_INCLUDED
     47 #include "pvmf_download_data_source.h"
     48 #endif
     49 #ifndef PVMF_SOURCE_CONTEXT_DATA_H_INCLUDED
     50 #include "pvmf_source_context_data.h"
     51 #endif
     52 #ifndef OSCL_TIMER_H_INCLUDED
     53 #include "oscl_timer.h"
     54 #endif
     55 #ifndef PVMF_PROTOCOL_ENGINE_COMMON_H_INCLUDED
     56 #include "pvmf_protocol_engine_common.h"
     57 #endif
     58 #ifndef PVMF_NODE_UTILS_H_INCLUDED
     59 #include "pvmf_node_utils.h"
     60 #endif
     61 #ifndef PVMF_PROTOCOL_ENGINE_NODE_EVENTS_H_INCLUDED
     62 #include "pvmf_protocol_engine_node_events.h"
     63 #endif
     64 #ifndef PVMI_DATA_STREAM_INTERFACE_H_INCLUDED
     65 #include "pvmi_data_stream_interface.h"
     66 #endif
     67 #ifndef PVMF_EVENT_HANDLING_H_INCLUDED
     68 #include "pvmf_event_handling.h"
     69 #endif
     70 #ifndef PVMF_MEDIA_PRESENTATION_INFO_H_INCLUDED
     71 #include "pvmf_media_presentation_info.h"
     72 #endif
     73 #ifndef PVMF_MEMPOOL_H_INCLUDED
     74 #include "pvmf_mempool.h"
     75 #endif
     76 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED
     77 #include "pvmf_media_clock.h"
     78 #endif
     79 #ifndef PVMI_KVP_H_INCLUDED
     80 #include "pvmi_kvp.h"
     81 #endif
     82 
     83 
     84 //#define PVMF_PROTOCOL_ENGINE_LOG_MS_STREAMING_OUTPUT
     85 
     86 
     87 
     88 //memory allocator type for this node.
     89 typedef OsclMemAllocator PVMFProtocolEngineNodeAllocator;
     90 
     91 // Structure to hold the key string info for
     92 // AAC decnode's capability-and-config
     93 struct PVProtocolEngineNodeKeyStringData
     94 {
     95     char iString[64];
     96     PvmiKvpType iType;
     97     PvmiKvpValueType iValueType;
     98 };
     99 
    100 // The number of characters to allocate for the key string
    101 #define PVPROTOCOLENGINENODECONFIG_KEYSTRING_SIZE 128
    102 
    103 ///////////////////////////////////////////////////////
    104 // For Command implementation
    105 ///////////////////////////////////////////////////////
    106 
    107 //Default vector reserve size
    108 #define PVMF_PROTOCOLENGINE_NODE_COMMAND_VECTOR_RESERVE 16
    109 
    110 //Starting value for command IDs
    111 #define PVMF_PROTOCOLENGINE_NODE_COMMAND_ID_START 6000
    112 
    113 enum PVMFProtocolEngineNodeCmdType
    114 {
    115     PVPROTOCOLENGINE_NODE_CMD_SEEK = PVMF_GENERIC_NODE_COMMAND_LAST,
    116     PVPROTOCOLENGINE_NODE_CMD_BITSTREAM_SWITCH,
    117     PVPROTOCOLENGINE_NODE_CMD_DATASTREAM_REQUEST_REPOSITION
    118 };
    119 
    120 enum PVMFProtocolEngineNodeState
    121 {
    122     // this is special node internal state for processing start command
    123     // we set node state as this state before doing the actual work for start
    124     // this is to differentiate the node state between pause and start without completing start command
    125     // this differentiation aims to ignore logging/keep-alive response when start command gets called,
    126     // but hasn't got completed.
    127     // This internal state should be gone when start command gets completed, then node state will change
    128     // to EPVMFNodeStarted
    129     PVMFProtocolEngineNodeState_BeingStarted = EPVMFNodeLastState,
    130 };
    131 
    132 
    133 //Node command type.
    134 #define PVMFProtocolEngineNodeCommandBase PVMFGenericNodeCommand<PVMFProtocolEngineNodeAllocator> // to remove warning on symbian build
    135 class PVMFProtocolEngineNodeCommand: public PVMFProtocolEngineNodeCommandBase
    136 {
    137     public:
    138         //constructor for Custom2 command
    139         void Construct(PVMFSessionId s, int32 cmd, int32 arg1, int32 arg2, int32& arg3, const OsclAny*aContext)
    140         {
    141             PVMFProtocolEngineNodeCommandBase::Construct(s, cmd, aContext);
    142             iParam1 = (OsclAny*)arg1;
    143             iParam2 = (OsclAny*)arg2;
    144             iParam3 = (OsclAny*) & arg3;
    145         }
    146         void Parse(int32&arg1, int32&arg2, int32*&arg3)
    147         {
    148             arg1 = (int32)iParam1;
    149             arg2 = (int32)iParam2;
    150             arg3 = (int32*)iParam3;
    151         }
    152 
    153         // Constructor and parser for seek and bitstreamSwitch
    154         void Construct(PVMFSessionId s, int32 cmd,
    155                        uint64 aNPTInMS,
    156                        uint32& aFirstSeqNumAfterChange,
    157                        OsclAny* aContext)
    158         {
    159             PVMFProtocolEngineNodeCommandBase::Construct(s, cmd, aContext);
    160             iNPTInMS = aNPTInMS;
    161             iParam2 = (OsclAny*) & aFirstSeqNumAfterChange;
    162         }
    163 
    164         void Parse(uint64& aNPTInMS, uint32*& aFirstSeqNumAfterChange)
    165         {
    166             aNPTInMS = iNPTInMS;
    167             aFirstSeqNumAfterChange = (uint32*)iParam2;
    168         }
    169 
    170         // constructor and parser for data stream request, especially reposition request
    171         void Construct(PVMFSessionId s, int32 cmd,
    172                        PvmiDataStreamSession aSessionID,
    173                        PvmiDataStreamRequest aRequestID,
    174                        OsclAny* aRequestData,
    175                        PvmiDataStreamCommandId aDataStreamCmdId,
    176                        OsclAny* aContext)
    177         {
    178             PVMFProtocolEngineNodeCommandBase::Construct(s, cmd, aContext);
    179             iParam1 = (OsclAny*)aSessionID;
    180             iParam2 = (OsclAny*)((uint32)aRequestID);
    181             iParam3 = aRequestData;
    182             iParam4 = (OsclAny*)aDataStreamCmdId;
    183         }
    184 
    185         void Parse(PvmiDataStreamSession& aSessionID, PvmiDataStreamRequest& aRequestID,
    186                    OsclAny*& aRequestData, PvmiDataStreamCommandId &aDataStreamCmdId)
    187         {
    188             aSessionID   = (PvmiDataStreamSession)iParam1;
    189             aRequestData = iParam3;
    190             aDataStreamCmdId = (PvmiDataStreamCommandId)iParam4;
    191             uint32 requestIDNum = (uint32)iParam2;
    192             aRequestID   = (PvmiDataStreamRequest)requestIDNum;
    193         }
    194 
    195         void Parse(OsclAny*& aRequestData)
    196         {
    197             aRequestData = iParam3;
    198         }
    199 
    200         void Parse(OsclAny*& aRequestData, PvmiDataStreamCommandId &aDataStreamCmdId)
    201         {
    202             aRequestData = iParam3;
    203             aDataStreamCmdId = (PvmiDataStreamCommandId)iParam4;
    204         }
    205 
    206     private:
    207         uint64 iNPTInMS;
    208 };
    209 
    210 
    211 //Command queue type
    212 typedef PVMFNodeCommandQueue<PVMFProtocolEngineNodeCommand, PVMFProtocolEngineNodeAllocator> PVMFProtocolEngineNodeCmdQ;
    213 
    214 typedef Oscl_Vector<PVMFSharedMediaMsgPtr, PVMFProtocolEngineNodeAllocator> INPUT_DATA_QUEUE;
    215 typedef Oscl_Vector<OsclRefCounterMemFrag, PVMFProtocolEngineNodeAllocator> OUTPUT_DATA_QUEUE;
    216 typedef Oscl_Vector<OsclRefCounterMemFrag*, PVMFProtocolEngineNodeAllocator> PENDING_OUTPUT_DATA_QUEUE;
    217 
    218 // two macros used in the array member and function parameter below
    219 #define PVHTTPDOWNLOADOUTPUT_CONTENTDATA_CHUNKSIZE 8000
    220 #define EVENT_HANDLER_TOTAL 10
    221 
    222 enum NetworkTimerType
    223 {
    224     SERVER_RESPONSE_TIMER_ID = 0,
    225     SERVER_INACTIVITY_TIMER_ID,
    226     SERVER_KEEPALIVE_TIMER_ID,
    227     SERVER_RESPONSE_TIMER_ID_FOR_STOPEOS_LOGGING,
    228     // handle data processing in case of no data input (PE node will become idle) for download/progressive streaming,
    229     // so there should be a way to activate PE node to continue data processing if needed
    230     WALL_CLOCK_TIMER_ID,
    231     // a timer to report buffer status periodically, say at every up to 2sec, at least buffer status has to be reported
    232     // which tells our system is running
    233     BUFFER_STATUS_TIMER_ID
    234 };
    235 
    236 enum PVHttpProtocol
    237 {
    238     PVHTTPPROTOCOL_PROGRESSIVE_DOWNLOAD = 0,
    239     PVHTTPPROTOCOL_PROGRESSIVE_STREAMING,
    240     PVHTTPPROTOCOL_SHOUTCAST,
    241     PVHTTPPROTOCOL_FASTTRACK_DOWNLOAD,
    242     PVHTTPPROTOCOL_MS_HTTP_STREAMING,
    243     PVHTTPPROTOCOL_UNKNOWN
    244 };
    245 
    246 // Forward declarations
    247 class PVMFProtocolEngineNode;
    248 class PVMFProtocolEnginePort;
    249 class PVMIDataStreamSyncInterface;
    250 class PVLogger;
    251 class PVMFLightMediaFragGroupAlloc;
    252 class PVMFMediaPresentationInfo;
    253 class HttpBasedProtocol;
    254 class PVMFProtocolEngineNodeOutput;
    255 class DownloadControlInterface;
    256 class DownloadProgressInterface;
    257 class EventReporter;
    258 class PVDlCfgFile;
    259 class PVDlCfgFileContainer;
    260 class PVMFDownloadDataSourceContainer;
    261 class PVMFProtocolEngineNodeTimer;
    262 class InterfacingObjectContainer;
    263 class UserAgentField;
    264 struct PVProtocolEngineNodeInternalEvent;
    265 class PVProtocolEngineNodeInternalEventHandler;
    266 class PVMFProtocolEnginePort;
    267 class OsclSharedLibrary;
    268 
    269 
    270 enum NodeObjectType
    271 {
    272     NodeObjectType_InputPortForData = 0,
    273     NodeObjectType_InputPortForLogging,
    274     NodeObjectType_OutPort,
    275     NodeObjectType_InternalEventQueue,
    276 
    277     NodeObjectType_Protocol,
    278     NodeObjectType_Output,
    279     NodeObjectType_DownloadControl,
    280     NodeObjectType_DownloadProgress,
    281     NodeObjectType_EventReport,
    282     NodeObjectType_DlCfgFileContainer,
    283     NodeObjectType_DataSourceContainer,
    284     NodeObjectType_Timer,
    285     NodeObjectType_InterfacingObjectContainer,
    286     NodeObjectType_UseAgentField
    287 };
    288 
    289 class ProtocolContainerObserver
    290 {
    291     public:
    292         virtual uint32 GetObserverState() = 0;
    293         virtual void SetObserverState(const uint32 aState) = 0;
    294         virtual bool DispatchEvent(PVProtocolEngineNodeInternalEvent *aEvent) = 0;
    295         virtual bool SendMediaCommand(PVMFProtocolEnginePort *aPort, PVUid32 aCmdId, const bool isForLogging = false) = 0;
    296         virtual void ClearRest(const bool aNeedDelete = false) = 0;
    297         virtual void RecheduleDataFlow() = 0;
    298         virtual void SendManualResumeNotificationEvent() = 0;
    299         virtual bool IsRepositionCmdPending() = 0;
    300         virtual PVMFProtocolEngineNodeCommand* FindPendingCmd(int32 aCmdId) = 0;
    301         virtual void CompletePendingCmd(int32 status) = 0;
    302         virtual void CompleteInputCmd(PVMFProtocolEngineNodeCommand& aCmd, int32 status) = 0;
    303         virtual void ErasePendingCmd(PVMFProtocolEngineNodeCommand *aCmd) = 0;
    304         virtual void ReportEvent(PVMFEventType aEventType, OsclAny* aEventData = NULL, const int32 aEventCode = 0, OsclAny* aEventLocalBuffer = NULL, const uint32 aEventLocalBufferSize = 0) = 0;
    305 };
    306 
    307 
    308 
    309 // This class handles protocol initialization for multiple http based protocols,
    310 // and it serves as a friend class of PVMFProtocolEngineNode, and thus helps do
    311 // protocol initialization.
    312 class ProtocolContainer
    313 {
    314     public:
    315         // constructor
    316         OSCL_IMPORT_REF ProtocolContainer(PVMFProtocolEngineNode *aNode = NULL);
    317         virtual ~ProtocolContainer()
    318         {
    319             iDataPathLogger = NULL;
    320             clear();
    321         }
    322 
    323         void setObserver(ProtocolContainerObserver *aObserver)
    324         {
    325             iObserver = aObserver;
    326         }
    327         OSCL_IMPORT_REF virtual bool createProtocolObjects();
    328         OSCL_IMPORT_REF virtual void deleteProtocolObjects();
    329         OSCL_IMPORT_REF virtual bool isObjectsReady(); // centralize the info-checking
    330         OSCL_IMPORT_REF virtual void setSupportObject(OsclAny* aSupportObject, const uint32 aType);
    331         virtual PVMFStatus doInit()
    332         {
    333             return PVMFSuccess;    // used in PVMFProtocolEngineNode::doInit
    334         }
    335         OSCL_IMPORT_REF virtual PVMFStatus doPrepare();                         // used in PVMFProtocolEngineNode::doPrepare, the default implementation is for both 3gpp and fasttrack download
    336         virtual bool doProPrepare()
    337         {
    338             return true;    // used only for fasttrack, invoke the call to generate SDP info.
    339         }
    340         virtual int32 doPreStart()
    341         {
    342             return PROCESS_SUCCESS;
    343         }
    344         virtual bool doPause()
    345         {
    346             return true;
    347         }
    348         OSCL_IMPORT_REF virtual PVMFStatus doStop();
    349         OSCL_IMPORT_REF virtual bool doEOS(const bool isTrueEOS = true);
    350         virtual bool doInfoUpdate(const uint32 downloadStatus)
    351         {
    352             OSCL_UNUSED_ARG(downloadStatus);    // for now, used for download only, report event and update download control
    353             return true;
    354         }
    355         virtual PVMFStatus doSeek(PVMFProtocolEngineNodeCommand& aCmd)
    356         {
    357             OSCL_UNUSED_ARG(aCmd);
    358             return PVMFSuccess;
    359         }
    360         virtual PVMFStatus doBitstreamSwitch(PVMFProtocolEngineNodeCommand& aCmd)
    361         {
    362             OSCL_UNUSED_ARG(aCmd);
    363             return PVMFSuccess;
    364         }
    365         OSCL_IMPORT_REF virtual bool reconnectSocket(const bool aForceSocketReconnect = true);  // used for progressive download and http streaming
    366         virtual bool needSocketReconnect()
    367         {
    368             return true;
    369         }
    370         OSCL_IMPORT_REF virtual void startDataFlowByCommand(const bool needDoSocketReconnect = true);
    371 
    372         OSCL_IMPORT_REF virtual void doClear(const bool aNeedDelete = false);
    373         OSCL_IMPORT_REF virtual void doStopClear();
    374         OSCL_IMPORT_REF virtual void doCancelClear();
    375         virtual bool addSourceData(OsclAny* aSourceData)
    376         {
    377             OSCL_UNUSED_ARG(aSourceData);
    378             return true;
    379         }
    380         virtual bool createCfgFile(OSCL_String& aUri)
    381         {
    382             OSCL_UNUSED_ARG(aUri);
    383             return true;
    384         }
    385         virtual bool getProxy(OSCL_String& aProxyName, uint32 &aProxyPort) = 0;
    386         virtual void setHttpVersion(const uint32 aHttpVersion)
    387         {
    388             OSCL_UNUSED_ARG(aHttpVersion);
    389         }
    390         virtual bool handleContentRangeUnmatch()
    391         {
    392             return true;
    393         }
    394         virtual bool downloadUpdateForHttpHeaderAvailable()
    395         {
    396             return true;
    397         }
    398         virtual void setHttpExtensionHeaderField(OSCL_String &aFieldKey, OSCL_String &aFieldValue, const HttpMethod aMethod = HTTP_GET, const bool aPurgeOnRedirect = false)
    399         {
    400             OSCL_UNUSED_ARG(aFieldKey);
    401             OSCL_UNUSED_ARG(aFieldValue);
    402             OSCL_UNUSED_ARG(aMethod);
    403             OSCL_UNUSED_ARG(aPurgeOnRedirect);
    404         }
    405 
    406         OSCL_IMPORT_REF virtual void handleTimeout(const int32 timerID);
    407         OSCL_IMPORT_REF virtual bool handleProtocolStateComplete(PVProtocolEngineNodeInternalEvent &aEvent, PVProtocolEngineNodeInternalEventHandler *aEventHandler);
    408 
    409         // for fasttrack only
    410         virtual PVMFStatus getMediaPresentationInfo(PVMFMediaPresentationInfo& aInfo)
    411         {
    412             OSCL_UNUSED_ARG(aInfo);
    413             return PVMFSuccess;
    414         }
    415         virtual PVMFStatus selectTracks(PVMFMediaPresentationInfo& aInfo)
    416         {
    417             OSCL_UNUSED_ARG(aInfo);
    418             return PVMFSuccess;
    419         }
    420 
    421         //Http status code 409 means low disk space
    422         virtual bool isHTTP409ForLowDiskSpace(const int32 errorCode)
    423         {
    424             OSCL_UNUSED_ARG(errorCode);
    425             return false;
    426         }
    427 
    428         // for ms http streaming only
    429         virtual void setLoggingStartInPause(const bool aLoggingStartInPause = true)
    430         {
    431             OSCL_UNUSED_ARG(aLoggingStartInPause);
    432         }
    433         virtual bool isLoggingStartInPause()
    434         {
    435             return false;
    436         }
    437         virtual bool needSendEOSDuetoError(const int32 aErrorCode)
    438         {
    439             OSCL_UNUSED_ARG(aErrorCode);
    440             return false;
    441         }
    442 
    443         // for progressive download only
    444         virtual bool needCheckExtraDataComeIn()
    445         {
    446             return false;
    447         }
    448         virtual bool needCheckEOSAfterDisconnectSocket()
    449         {
    450             return false;
    451         }
    452 
    453         // for progressive playback (special case of progressive download) only
    454         virtual bool isStreamingPlayback()
    455         {
    456             return false;
    457         }
    458         virtual bool completeRepositionRequest()
    459         {
    460             return false;
    461         }
    462         virtual void checkSendResumeNotification()
    463         {
    464             ;
    465         }
    466         virtual void enableInfoUpdate(const bool aEnabled = true)
    467         {
    468             OSCL_UNUSED_ARG(aEnabled);
    469         }
    470 
    471         OSCL_IMPORT_REF virtual OsclAny* getObject(const NodeObjectType aObjectType);
    472 
    473         virtual void SetSharedLibraryPtr(OsclSharedLibrary* aPtr)
    474         {
    475             iOsclSharedLibrary = aPtr;
    476         }
    477 
    478         /**
    479          * Retrieves shared library pointer
    480          * @returns Pointer to the shared library.
    481          **/
    482         virtual OsclSharedLibrary* GetSharedLibraryPtr()
    483         {
    484             return iOsclSharedLibrary;
    485         }
    486 
    487     protected:
    488         OSCL_IMPORT_REF virtual PVMFStatus initImpl();
    489         virtual int32 initNodeOutput() = 0;
    490         OSCL_IMPORT_REF bool initProtocol();
    491         virtual bool initProtocol_SetConfigInfo() = 0;
    492         virtual void initDownloadControl()
    493         {
    494             ;
    495         }
    496         OSCL_IMPORT_REF uint32 getBitMaskForHTTPMethod(const HttpMethod aMethod = HTTP_GET);
    497         // called by handleTimeout()
    498         virtual bool handleTimeoutInPause(const int32 timerID)
    499         {
    500             OSCL_UNUSED_ARG(timerID);
    501             return false;
    502         }
    503         virtual bool handleTimeoutInDownloadStreamingDone(const int32 timerID)
    504         {
    505             OSCL_UNUSED_ARG(timerID);
    506             return false;
    507         }
    508         // called by doStop()
    509         OSCL_IMPORT_REF virtual void sendSocketDisconnectCmd();
    510         // called by handleTimeout()
    511         OSCL_IMPORT_REF virtual bool ignoreThisTimeout(const int32 timerID);
    512         OSCL_IMPORT_REF virtual void clear();
    513 
    514     private:
    515         //called by createProtocolObjects()
    516         bool createNetworkTimer();
    517 
    518         // called by handleTimeout()
    519         bool handleTimeoutErr(const int32 timerID);
    520 
    521         // called by startDataFlowByCommand()
    522         void checkEOSMsgFromInputPort();
    523         // called by doClear or doCancelClear()
    524         void clearInternalEventQueue();
    525 
    526     protected:
    527         PVMFProtocolEngineNode *iNode;
    528         ProtocolContainerObserver *iObserver;
    529         PVLogger *iDataPathLogger;
    530 
    531         // hold references for the following node objects
    532         HttpBasedProtocol *iProtocol;
    533         PVMFProtocolEngineNodeOutput *iNodeOutput;
    534         DownloadControlInterface *iDownloadControl;
    535         DownloadProgressInterface *iDownloadProgess;
    536         EventReporter *iEventReport;
    537         PVDlCfgFileContainer *iCfgFileContainer;
    538         PVMFDownloadDataSourceContainer *iDownloadSource;
    539         PVMFProtocolEngineNodeTimer *iNodeTimer;
    540         InterfacingObjectContainer *iInterfacingObjectContainer;
    541         UserAgentField *iUserAgentField;
    542 
    543         // pass-in node objects
    544         PVMFProtocolEnginePort *iPortInForData, *iPortInForLogging, *iPortOut;
    545         Oscl_Vector<PVProtocolEngineNodeInternalEvent, PVMFProtocolEngineNodeAllocator> *iInternalEventQueue;
    546 
    547         OsclSharedLibrary* iOsclSharedLibrary;
    548 };
    549 
    550 ////////////////////////////////////////////////////////////////////////////////////
    551 
    552 // Using state to handle multiple use cases
    553 enum PVProtocolEngineNodePrcoessingState
    554 {
    555     ProcessingState_Idle = 0,
    556     ProcessingState_NormalDataflow,             // normal data flow
    557     // other states are changed to using event
    558 };
    559 
    560 static const TPVMFNodeInterfaceState SetStateByCommand[11] =
    561 {
    562     EPVMFNodeInitialized,   // PVMF_GENERIC_NODE_INIT=4
    563     EPVMFNodePrepared,      // PVMF_GENERIC_NODE_PREPARE=5
    564     EPVMFNodeStarted,       // PVMF_GENERIC_NODE_START=6
    565     EPVMFNodePrepared,      // PVMF_GENERIC_NODE_STOP=7
    566     EPVMFNodeStarted,       // PVMF_GENERIC_NODE_FLUSH=8
    567     EPVMFNodePaused,        // PVMF_GENERIC_NODE_PAUSE=9
    568     EPVMFNodeCreated,       // PVMF_GENERIC_NODE_RESET=10
    569     EPVMFNodeLastState,     // PVMF_GENERIC_NODE_CANCELALLCOMMANDS=11
    570     EPVMFNodeLastState,     // PVMF_GENERIC_NODE_CANCELCOMMAND=12
    571     EPVMFNodeStarted,       // PVPROTOCOLENGINE_NODE_CMD_SEEK=13,
    572     EPVMFNodeStarted        // PVPROTOCOLENGINE_NODE_CMD_BITSTREAM_SWITCH=14
    573 };
    574 
    575 
    576 ////////////////////////////////////////////////////////////////////////////////////
    577 //////  PVProtocolEngineNodeInternalEvent definition
    578 ////////////////////////////////////////////////////////////////////////////////////
    579 
    580 // This structure defines the internal event(constrast to node event) struture, which serves as the basis of
    581 // event-driven handling inside the node
    582 enum PVProtocolEngineNodeInternalEventType
    583 {
    584     // This group of events comes from the callback/feedback from protocol engine
    585     PVProtocolEngineNodeInternalEventType_HttpHeaderAvailable = 0,
    586     PVProtocolEngineNodeInternalEventType_FirstPacketAvailable,
    587     PVProtocolEngineNodeInternalEventType_NormalDataAvailable,
    588     PVProtocolEngineNodeInternalEventType_ProtocolStateComplete,
    589 
    590     // This group of events comes from node itself
    591     PVProtocolEngineNodeInternalEventType_EndOfProcessing,
    592     PVProtocolEngineNodeInternalEventType_ServerResponseError_Bypassing,
    593     PVProtocolEngineNodeInternalEventType_ProtocolStateError,
    594     PVProtocolEngineNodeInternalEventType_CheckResumeNotificationMaually,
    595     PVProtocolEngineNodeInternalEventType_OutgoingMsgQueuedAndSentSuccessfully,
    596 
    597     // data flow event
    598     PVProtocolEngineNodeInternalEventType_IncomingMessageReady = 9,
    599     PVProtocolEngineNodeInternalEventType_HasExtraInputData,
    600     PVProtocolEngineNodeInternalEventType_OutputDataReady,
    601     PVProtocolEngineNodeInternalEventType_StartDataflowByCommand,
    602     PVProtocolEngineNodeInternalEventType_StartDataflowByBufferAvailability,
    603     PVProtocolEngineNodeInternalEventType_StartDataflowBySendRequestAction,
    604     PVProtocolEngineNodeInternalEventType_StartDataflowByPortOutgoingQueueReady
    605 };
    606 
    607 struct PVProtocolEngineNodeInternalEvent
    608 {
    609     PVProtocolEngineNodeInternalEventType iEventId;
    610     OsclAny *iEventInfo; // any other side info except the actual data, such as error code, sequence number(http streaming), seek offset(fasttrack)
    611     OsclAny *iEventData; // actual data for the event
    612 
    613     // default constructor
    614     PVProtocolEngineNodeInternalEvent() : iEventId(PVProtocolEngineNodeInternalEventType_HttpHeaderAvailable), iEventInfo(NULL), iEventData(NULL)
    615     {
    616         ;
    617     }
    618 
    619     // constructor with parameters
    620     PVProtocolEngineNodeInternalEvent(PVProtocolEngineNodeInternalEventType aEventId, OsclAny *aEventInfo, OsclAny *aEventData = NULL)
    621     {
    622         iEventId   = aEventId;
    623         iEventInfo = aEventInfo;
    624         iEventData = aEventData;
    625     }
    626 
    627     PVProtocolEngineNodeInternalEvent(const ProtocolEngineOutputDataSideInfo &aSideInfo, const OsclAny *aData = NULL)
    628     {
    629         ProtocolEngineOutputDataSideInfo sideInfo = (ProtocolEngineOutputDataSideInfo&) aSideInfo;
    630         iEventId   = (PVProtocolEngineNodeInternalEventType)((uint32)sideInfo.iDataType);
    631         iEventInfo = (OsclAny *)sideInfo.iData;
    632         iEventData = (OsclAny *)aData;
    633     }
    634     PVProtocolEngineNodeInternalEvent(PVProtocolEngineNodeInternalEventType aEventId, int32 aInfoCode = 0)
    635     {
    636         iEventId   = aEventId;
    637         iEventInfo = (OsclAny *)aInfoCode;
    638         iEventData = NULL;
    639     }
    640 
    641     // copy constructor
    642     PVProtocolEngineNodeInternalEvent(const PVProtocolEngineNodeInternalEvent &x)
    643     {
    644         iEventId   = x.iEventId;
    645         iEventInfo = x.iEventInfo;
    646         iEventData = x.iEventData;
    647     }
    648 
    649     // operator "="
    650     PVProtocolEngineNodeInternalEvent &operator=(const PVProtocolEngineNodeInternalEvent& x)
    651     {
    652         iEventId   = x.iEventId;
    653         iEventInfo = x.iEventInfo;
    654         iEventData = x.iEventData;
    655         return *this;
    656     }
    657 };
    658 
    659 // this structure defines information needed for EndOfDataProcessingHandler, will be as iEventInfo
    660 struct EndOfDataProcessingInfo
    661 {
    662     bool iSendResumeNotification;
    663     bool iExtraDataComeIn;
    664     bool iSendServerDisconnectEvent;
    665     bool iStreamingDone;
    666     bool iForceStop;
    667 
    668     // constructor
    669     EndOfDataProcessingInfo() : iSendResumeNotification(false),
    670             iExtraDataComeIn(false),
    671             iSendServerDisconnectEvent(false),
    672             iStreamingDone(false),
    673             iForceStop(false) {}
    674 
    675     bool isValid() const
    676     {
    677         return (iSendResumeNotification     ||
    678                 iExtraDataComeIn            ||
    679                 iSendServerDisconnectEvent  ||
    680                 iStreamingDone              ||
    681                 iForceStop);
    682     }
    683 
    684     void clear()
    685     {
    686         iSendResumeNotification = false;
    687         iExtraDataComeIn = false;
    688         iSendServerDisconnectEvent = false;
    689         iStreamingDone = false;
    690         iForceStop = false;
    691     }
    692 };
    693 
    694 // this structure defines information needed for ProtocolStateErrorHandler, will be as iEventInfo
    695 struct ProtocolStateErrorInfo
    696 {
    697     int32 iErrorCode;
    698     // true means using the current iErrorCode, false means using the previous iErrorCode
    699     bool iUseInputErrorCode;
    700 
    701     // constructor
    702     ProtocolStateErrorInfo() : iErrorCode(0), iUseInputErrorCode(true)
    703     {
    704         ;
    705     }
    706     ProtocolStateErrorInfo(const int32 aErrorCode, const bool aUseInputErrorCode = true) :
    707             iErrorCode(aErrorCode),
    708             iUseInputErrorCode(aUseInputErrorCode)
    709     {
    710         ;
    711     }
    712 };
    713 
    714 // this structure defines infomation needed for OutgoingMsgSentSuccessHandler, will be as iEventInfo
    715 struct OutgoingMsgSentSuccessInfo
    716 {
    717     PVMFProtocolEnginePort *iPort;
    718     PVMFSharedMediaMsgPtr iMsg;
    719 
    720     // constructor
    721     OutgoingMsgSentSuccessInfo(): iPort(NULL)
    722     {
    723         ;
    724     }
    725     OutgoingMsgSentSuccessInfo(PVMFProtocolEnginePort *aPort, PVMFSharedMediaMsgPtr &aMsg) :
    726             iPort(aPort), iMsg(aMsg)
    727     {
    728         ;
    729     }
    730 
    731     OutgoingMsgSentSuccessInfo &operator=(const OutgoingMsgSentSuccessInfo& x)
    732     {
    733         iPort = x.iPort;
    734         iMsg  = x.iMsg;
    735         return *this;
    736     }
    737 };
    738 
    739 // use polymophism to handle variant events
    740 class PVProtocolEngineNodeInternalEventHandler
    741 {
    742     public:
    743         virtual ~PVProtocolEngineNodeInternalEventHandler() {}
    744 
    745         virtual bool handle(PVProtocolEngineNodeInternalEvent &aEvent) = 0;
    746         virtual bool completePendingCommand(PVProtocolEngineNodeInternalEvent &aEvent);
    747 
    748         // contructor
    749         PVProtocolEngineNodeInternalEventHandler(PVMFProtocolEngineNode *aNode);
    750 
    751     protected:
    752         bool isBeingStopped(const int32 aStatus = PROCESS_SUCCESS_END_OF_MESSAGE); // common routine
    753 
    754     private:
    755         inline bool isCurrEventMatchCurrPendingCommand(uint32 aCurrEventId);
    756         bool completePendingCommandWithError(PVProtocolEngineNodeInternalEvent &aEvent);
    757         int32 getBasePVMFErrorReturnCode(const int32 errorCode, const bool isForCommandComplete = true);
    758         void handleErrResponse(int32 &aBaseCode, int32 &aErrCode, char* &aEventData, uint32 &aEventDataLen);
    759         void handleAuthenErrResponse(int32 &aErrCode, char* &aEventData, uint32 &aEventDataLen);
    760         void handleRedirectErrResponse(char* &aEventData, uint32 &aEventDataLen);
    761         inline bool isStopCmdPending(); // called by isBeingStopped
    762         inline bool isProtocolStateComplete(const int32 aStatus);
    763 
    764     protected:
    765         PVMFProtocolEngineNode *iNode;
    766         PVLogger* iDataPathLogger;
    767 
    768     private:
    769         OSCL_HeapString<OsclMemAllocator> iAuthenInfoRealm;
    770 };
    771 
    772 // ProtocolStateErrorHandling becomes a little bit more complicated due to the new requirement:
    773 // PE node needs to send EOS to downstream node once error happens during streaming
    774 // Previously, PE node just error out without doing that much stuff. Now for this new requirement,
    775 // PE node needs two rounds error handling in this case, at the first round, probably does nothing but
    776 // storing error code and preparing sending EOS, and then at the second round, does the real error handling
    777 // But for other cases (PDL or streaming doesn't really start), just do error handling
    778 class ProtocolStateErrorHandler : public PVProtocolEngineNodeInternalEventHandler
    779 {
    780     public:
    781         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    782 
    783         // constructor
    784         ProtocolStateErrorHandler(PVMFProtocolEngineNode *aNode) :
    785                 PVProtocolEngineNodeInternalEventHandler(aNode), iErrorCode(0)
    786         {
    787             ;
    788         }
    789     private:
    790         int32 parseServerResponseCode(const int32 aErrorCode, bool &isInfoEvent);
    791         // return value: 0 means caller needs to return immediately, not 0 means error
    792         int32 checkRedirectHandling(const int32 aErrorCode);
    793         bool handleRedirect();
    794         bool NeedHandleContentRangeUnmatch(const int32 aErrorCode);
    795         bool handleContentRangeUnmatch();
    796         bool needCompletePendingCommandAtThisRound(PVProtocolEngineNodeInternalEvent &aEvent);
    797 
    798     private:
    799         int32 iErrorCode;
    800 };
    801 
    802 class HttpHeaderAvailableHandler : public PVProtocolEngineNodeInternalEventHandler
    803 {
    804     public:
    805         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    806 
    807         // constructor
    808         HttpHeaderAvailableHandler(PVMFProtocolEngineNode *aNode) :
    809                 PVProtocolEngineNodeInternalEventHandler(aNode)
    810         {
    811             ;
    812         }
    813 };
    814 
    815 class FirstPacketAvailableHandler : public PVProtocolEngineNodeInternalEventHandler
    816 {
    817     public:
    818         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    819 
    820         // constructor
    821         FirstPacketAvailableHandler(PVMFProtocolEngineNode *aNode) :
    822                 PVProtocolEngineNodeInternalEventHandler(aNode)
    823         {
    824             ;
    825         }
    826 };
    827 
    828 
    829 class NormalDataAvailableHandler : public PVProtocolEngineNodeInternalEventHandler
    830 {
    831     public:
    832         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    833 
    834         // constructor
    835         NormalDataAvailableHandler(PVMFProtocolEngineNode *aNode) :
    836                 PVProtocolEngineNodeInternalEventHandler(aNode)
    837         {
    838             ;
    839         }
    840 };
    841 
    842 class ProtocolStateCompleteHandler : public PVProtocolEngineNodeInternalEventHandler
    843 {
    844     public:
    845         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    846 
    847         // constructor
    848         ProtocolStateCompleteHandler(PVMFProtocolEngineNode *aNode) :
    849                 PVProtocolEngineNodeInternalEventHandler(aNode)
    850         {
    851             ;
    852         }
    853 };
    854 
    855 class NormalDataFlowHandler : public PVProtocolEngineNodeInternalEventHandler
    856 {
    857     public:
    858         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    859 
    860         // constructor
    861         NormalDataFlowHandler(PVMFProtocolEngineNode *aNode) : PVProtocolEngineNodeInternalEventHandler(aNode), iSendSocketReconnect(false)
    862         {
    863             ;
    864         }
    865 
    866     private:
    867         bool flushDataPostProcessing(const int32 aStatusFlushData);
    868         bool handleEOSLogging();
    869         bool handleEOS(const int32 aStatus);
    870         bool handleEndOfProcessing(const int32 aStatus);
    871         bool dataFlowContinue(const int32 aStatus);
    872         inline bool isReadyGotoNextState(const int32 aStatus); // called by dataFlowContinueOrStop
    873 
    874     private:
    875         bool iSendSocketReconnect;
    876 };
    877 
    878 class EndOfDataProcessingHandler : public PVProtocolEngineNodeInternalEventHandler
    879 {
    880     public:
    881         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    882 
    883         // constructor
    884         EndOfDataProcessingHandler(PVMFProtocolEngineNode *aNode) :
    885                 PVProtocolEngineNodeInternalEventHandler(aNode)
    886         {
    887             ;
    888         }
    889 
    890     private:
    891         void cleanupForStop(PVProtocolEngineNodeInternalEvent &aEvent);
    892 };
    893 
    894 
    895 class ServerResponseErrorBypassingHandler : public PVProtocolEngineNodeInternalEventHandler
    896 {
    897     public:
    898         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    899 
    900         // constructor
    901         ServerResponseErrorBypassingHandler(PVMFProtocolEngineNode *aNode) :
    902                 PVProtocolEngineNodeInternalEventHandler(aNode)
    903         {
    904             ;
    905         }
    906 };
    907 
    908 
    909 // This handler is for PVProtocolEngineNodeInternalEventType_CheckResumeNotificationMaually only. This happens in progressive streaming,
    910 // when MBDS is quickly filled up,and parser node hasn't parsed any data. In this special case, PE node will go idle, but parser node
    911 // may send an internal RequestResumeNotification before parsing any data, then deadlock happens.
    912 class CheckResumeNotificationHandler : public PVProtocolEngineNodeInternalEventHandler
    913 {
    914     public:
    915         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    916 
    917         // constructor
    918         CheckResumeNotificationHandler(PVMFProtocolEngineNode *aNode) :
    919                 PVProtocolEngineNodeInternalEventHandler(aNode)
    920         {
    921             ;
    922         }
    923 };
    924 
    925 class OutgoingMsgSentSuccessHandler : public PVProtocolEngineNodeInternalEventHandler
    926 {
    927     public:
    928         bool handle(PVProtocolEngineNodeInternalEvent &aEvent);
    929 
    930         // constructor
    931         OutgoingMsgSentSuccessHandler(PVMFProtocolEngineNode *aNode) :
    932                 PVProtocolEngineNodeInternalEventHandler(aNode)
    933         {
    934             ;
    935         }
    936 };
    937 
    938 
    939 
    940 
    941 ////////////////////////////////////////////////////////////////////////////////////
    942 //////  PVMFProtocolEngineNodeOutput
    943 ////////////////////////////////////////////////////////////////////////////////////
    944 
    945 // Observer class for pvHttpStreamingOutput to notify the node when the output buffer is available since
    946 // the memory pool is created inside pvHttpStreamingOutput
    947 class PVMFProtocolEngineNodeOutputObserver
    948 {
    949     public:
    950         virtual ~PVMFProtocolEngineNodeOutputObserver() {}
    951 
    952         // notify the node that the output buffer pool is fool, so hold off any data processing
    953         virtual void OutputBufferPoolFull() = 0;
    954         // notify the node that the new output buffer inside the pool is back to available.
    955         virtual void OutputBufferAvailable() = 0;
    956         // notify the node that the new data is already written the file and then download control and status
    957         // should be updated responsively
    958         virtual void ReadyToUpdateDownloadControl() = 0;
    959         // notify the node that a media message has been queued in outgoing message queue successfully
    960         virtual bool QueueOutgoingMsgSentComplete(PVMFProtocolEnginePort *aPort, PVMFSharedMediaMsgPtr &aMsg, const PVMFStatus aStatus) = 0;
    961 };
    962 
    963 enum NodeOutputType
    964 {
    965     NodeOutputType_InputPortForData = 0,
    966     NodeOutputType_InputPortForLogging,
    967     NodeOutputType_OutPort,
    968     NodeOutputType_DataStreamFactory
    969 };
    970 
    971 // This base class encapsulates port objects (port and data stream)
    972 class PVMFProtocolEngineNodeOutput
    973 {
    974     public:
    975         // set output object such as, input port, output port and data stream factory
    976         OSCL_IMPORT_REF virtual void setOutputObject(OsclAny* aOutputObject, const uint32 aObjectType = NodeOutputType_InputPortForData);
    977         virtual void setConfigInfo(OsclAny* aConfig)
    978         {
    979             OSCL_UNUSED_ARG(aConfig);
    980         }
    981         OSCL_IMPORT_REF virtual bool passDownNewOutputData(OUTPUT_DATA_QUEUE &aOutputQueue, OsclAny* aSideInfo = NULL);
    982         OSCL_IMPORT_REF virtual int32 flushData(const uint32 aOutputType = NodeOutputType_InputPortForData) = 0;
    983         virtual int32 initialize(OsclAny* aInitInfo = NULL) = 0;
    984         virtual int32 reCreateMemPool(uint32 aNumPool)
    985         {
    986             OSCL_UNUSED_ARG(aNumPool);
    987             return PROCESS_SUCCESS;
    988         }
    989         virtual uint32 getNumBuffersInMediaDataPool()
    990         {
    991             return 0;
    992         }
    993         OSCL_IMPORT_REF bool getBuffer(PVMFSharedMediaDataPtr &aMediaData, uint32 aRequestSize = PVHTTPDOWNLOADOUTPUT_CONTENTDATA_CHUNKSIZE);
    994         OSCL_IMPORT_REF virtual void discardData(const bool aNeedReopen = false);
    995         OSCL_IMPORT_REF virtual bool isPortBusy();
    996 
    997         // PPB (progressive streaming/playback)
    998         virtual bool releaseMemFrag(OsclRefCounterMemFrag* aFrag)
    999         {
   1000             OSCL_UNUSED_ARG(aFrag);
   1001             return false;
   1002         };
   1003         virtual void setContentLength(uint32 aLength)
   1004         {
   1005             OSCL_UNUSED_ARG(aLength);
   1006         };
   1007         virtual void dataStreamCommandCompleted(const PVMFCmdResp& aResponse)
   1008         {
   1009             OSCL_UNUSED_ARG(aResponse);
   1010         };
   1011         virtual void setDataStreamSourceRequestObserver(PvmiDataStreamRequestObserver* aObserver)
   1012         {
   1013             OSCL_UNUSED_ARG(aObserver);
   1014         };
   1015         virtual void flushDataStream()
   1016         {
   1017             ;
   1018         }
   1019         virtual bool seekDataStream(const uint32 aSeekOffset)
   1020         {
   1021             OSCL_UNUSED_ARG(aSeekOffset);
   1022             return true;
   1023         };
   1024 
   1025         // get info from output object to serve as the basis for status update
   1026         uint32 getCurrentOutputSize()
   1027         {
   1028             return iCurrTotalOutputSize;
   1029         }
   1030         void setCurrentOutputSize(const uint32 aCurrentSize)
   1031         {
   1032             iCurrTotalOutputSize = aCurrentSize;    // used in resume download
   1033         }
   1034         virtual uint32 getCurrentPlaybackTime()
   1035         {
   1036             return 0;
   1037         }
   1038         // in case of progressive streaming, the following two sizes mean available cache size and maximum cache size
   1039         virtual uint32 getAvailableOutputSize()
   1040         {
   1041             return 0xFFFFFFFF;
   1042         }
   1043         virtual uint32 getMaxAvailableOutputSize()
   1044         {
   1045             return 0;
   1046         }
   1047 
   1048         // constructor and destructor
   1049         OSCL_IMPORT_REF PVMFProtocolEngineNodeOutput(PVMFProtocolEngineNodeOutputObserver *aObserver = NULL);
   1050         OSCL_IMPORT_REF virtual ~PVMFProtocolEngineNodeOutput();
   1051 
   1052     protected:
   1053         // for media data
   1054         OSCL_IMPORT_REF PVMFStatus createMemPool();
   1055         OSCL_IMPORT_REF void deleteMemPool();
   1056         // create media data for composing http request
   1057         OSCL_IMPORT_REF bool createMediaData(PVMFSharedMediaDataPtr &aMediaData, uint32 aRequestSize);
   1058         OSCL_IMPORT_REF bool sendToDestPort(PVMFSharedMediaDataPtr &aMediaData, PVMFProtocolEnginePort *aPort);
   1059 
   1060         // send the input media data to the port
   1061         OSCL_IMPORT_REF virtual bool sendToPort(PVMFSharedMediaDataPtr &aMediaData, const uint32 aPortType = NodeOutputType_InputPortForData);
   1062 
   1063         // reset
   1064         OSCL_IMPORT_REF virtual void reset();
   1065 
   1066     protected:
   1067         PVMFProtocolEnginePort *iPortIn;  // input port connecting to socket node, both for download and http streaming
   1068 
   1069         // Output buffer memory pool
   1070         OsclMemPoolFixedChunkAllocator *iContentDataMemPool;
   1071 
   1072         // Allocator for simple media data buffer
   1073         PVMFSimpleMediaBufferCombinedAlloc *iMediaDataAlloc;
   1074 
   1075         // Memory pool for simple media data
   1076         PVMFMemPoolFixedChunkAllocator iMediaDataMemPool;
   1077 
   1078         PVMFSharedMediaDataPtr iMediaData;
   1079         Oscl_Vector<OUTPUT_DATA_QUEUE, PVMFProtocolEngineNodeAllocator> iOutputFramesQueue;
   1080         // Mem frags in this queue are being used by the data stream
   1081         PENDING_OUTPUT_DATA_QUEUE iPendingOutputDataQueue;
   1082 
   1083         // observer to notify the node when output buffer is available
   1084         PVMFProtocolEngineNodeOutputObserver *iObserver;
   1085 
   1086         // current total output size, serves as the basis for status update
   1087         uint32 iCurrTotalOutputSize;
   1088 
   1089         PVLogger* iLogger;
   1090         PVLogger* iDataPathLogger;
   1091         PVLogger* iClockLogger;
   1092 };
   1093 
   1094 
   1095 ////////////////////////////////////////////////////////////////////////////////////
   1096 //////  DownloadControlInterface
   1097 ////////////////////////////////////////////////////////////////////////////////////
   1098 enum DownloadControlSupportObjectType
   1099 {
   1100     DownloadControlSupportObjectType_SupportInterface = 0,
   1101     DownloadControlSupportObjectType_ProgressInterface,
   1102     DownloadControlSupportObjectType_EnginePlaybackClock,
   1103     DownloadControlSupportObjectType_ProtocolEngine,
   1104     DownloadControlSupportObjectType_ConfigFileContainer,
   1105     DownloadControlSupportObjectType_SDPInfoContainer,
   1106     DownloadControlSupportObjectType_DownloadProgress,
   1107     DownloadControlSupportObjectType_OutputObject
   1108 };
   1109 
   1110 // The intent of introducing this download ocntrol interface is to make streaming counterpart as a NULL object,
   1111 // which remove any error-prone check
   1112 class DownloadControlInterface
   1113 {
   1114     public:
   1115         // set download control supporting objects:
   1116         virtual void setSupportObject(OsclAny *aDLSupportObject, DownloadControlSupportObjectType aType) = 0;
   1117         // From PVMFDownloadProgressInterface API pass down
   1118         virtual void requestResumeNotification(const uint32 currentNPTReadPosition, bool& aDownloadComplete, bool& aNeedSendUnderflowEvent) = 0;
   1119         // check whether to make resume notification; if needed, then make resume notification
   1120         virtual void cancelResumeNotification() = 0;
   1121         // cancel request of resume notification.
   1122         virtual int32 checkResumeNotification(const bool aDownloadComplete = true) = 0;
   1123         // return true for the new download progress
   1124         // From PVMFDownloadProgressInterface API
   1125         virtual void getDownloadClock(OsclSharedPtr<PVMFMediaClock> &aClock) = 0;
   1126         // From PVMFDownloadProgressInterface API
   1127         virtual void setClipDuration(const uint32 aClipDurationMsec) = 0;
   1128         // for auto-resume control for resume download
   1129         virtual void setPrevDownloadSize(uint32 aPrevDownloadSize = 0) = 0;
   1130         virtual void clear() = 0;
   1131 
   1132         // for progressive playback repositioning
   1133         virtual void clearPerRequest() = 0;
   1134         virtual bool isDownloadCompletedPerRequest() = 0;
   1135 
   1136         // destructor
   1137         virtual ~DownloadControlInterface()
   1138         {
   1139             ;
   1140         }
   1141 };
   1142 
   1143 ////////////////////////////////////////////////////////////////////////////////////
   1144 //////  DownloadProgressInterface
   1145 ////////////////////////////////////////////////////////////////////////////////////
   1146 
   1147 // This class encapsulates the download progress update based on different download progress modes
   1148 class DownloadProgressInterface
   1149 {
   1150     public:
   1151         virtual void setSupportObject(OsclAny *aDLSupportObject, DownloadControlSupportObjectType aType) = 0;
   1152 
   1153         // updata download clock and download progress
   1154         virtual bool update(const bool aDownloadComplete = false) = 0;
   1155 
   1156         // return true for the new download progress
   1157         virtual bool getNewProgressPercent(uint32 &aProgressPercent) = 0;
   1158 
   1159         // return duration for auto-resume decision
   1160         virtual void setClipDuration(const uint32 aClipDurationMsec) = 0;
   1161 
   1162         virtual void setDownloadProgressMode(DownloadProgressMode aMode = DownloadProgressMode_TimeBased) = 0;
   1163 
   1164         virtual ~DownloadProgressInterface()
   1165         {
   1166             ;
   1167         }
   1168 };
   1169 
   1170 ////////////////////////////////////////////////////////////////////////////////////
   1171 //////  EventReporter
   1172 ////////////////////////////////////////////////////////////////////////////////////
   1173 // This class wraps up sending node info&error event.
   1174 enum EventReporterSupportObjectType
   1175 {
   1176     EventReporterSupportObjectType_DownloadProgress = 0,
   1177     EventReporterSupportObjectType_ProtocolEngine,
   1178     EventReporterSupportObjectType_ConfigFileContainer,
   1179     EventReporterSupportObjectType_NodeInterfacingObject,
   1180     EventReporterSupportObjectType_TimerObject,
   1181     EventReporterSupportObjectType_OutputObject
   1182 };
   1183 
   1184 class EventReporterObserver
   1185 {
   1186     public:
   1187         // TODO: Change the buffer to be const void*.
   1188         // TODO: Why do we have event data AND event buffer?
   1189         virtual void ReportEvent(PVMFEventType aEventType, OsclAny* aEventData = NULL, const int32 aEventCode = 0, OsclAny* aEventLocalBuffer = NULL, const size_t aEventLocalBufferSize = 0) = 0;
   1190         virtual void NotifyContentTooLarge() = 0;
   1191         virtual uint32 GetObserverState() = 0;
   1192 };
   1193 
   1194 class EventReporter
   1195 {
   1196     public:
   1197         virtual ~EventReporter() {}
   1198 
   1199         // constructor
   1200         OSCL_IMPORT_REF EventReporter(EventReporterObserver *aObserver);
   1201 
   1202         virtual void setSupportObject(OsclAny *aSupportObject, EventReporterSupportObjectType aType)
   1203         {
   1204             OSCL_UNUSED_ARG(aSupportObject);
   1205             OSCL_UNUSED_ARG(aType);
   1206         }
   1207 
   1208         // major function to walk throught all the node info & error event whether to be sent out
   1209         virtual bool checkReportEvent(const uint32 downloadStatus)
   1210         {
   1211             OSCL_UNUSED_ARG(downloadStatus);
   1212             return true;
   1213         }
   1214         // the content-length event and content too large event, can't fit into the above checkReportEvent() completely
   1215         virtual bool checkContentInfoEvent(const uint32 downloadStatus)
   1216         {
   1217             OSCL_UNUSED_ARG(downloadStatus);
   1218             return true;
   1219         }
   1220 
   1221         // enable some specific events
   1222         virtual void sendDataReadyEvent()
   1223         {
   1224             ;
   1225         }
   1226         virtual void enableBufferingCompleteEvent()
   1227         {
   1228             ;
   1229         }
   1230         virtual void sendBufferStatusEvent()
   1231         {
   1232             ;
   1233         }
   1234 
   1235         OSCL_IMPORT_REF virtual void clear();
   1236 
   1237         // node is running in start state to kick off the normal downloading and streaming
   1238         OSCL_IMPORT_REF void startRealDataflow();
   1239 
   1240     protected:
   1241         bool iStarted;
   1242         EventReporterObserver *iObserver;
   1243         PVLogger *iDataPathLogger;
   1244 };
   1245 
   1246 
   1247 // This class wraps up user agent setting, differentiated in progessive download, fastrack and ms http streaming.
   1248 // Any this kind of variation should be wrapped up into an object
   1249 class UserAgentField
   1250 {
   1251     public:
   1252         // constructor
   1253         UserAgentField() : iOverwritable(false)
   1254         {
   1255             ;
   1256         }
   1257         OSCL_IMPORT_REF UserAgentField(OSCL_wString &aUserAgent, const bool isOverwritable = false);
   1258         OSCL_IMPORT_REF UserAgentField(OSCL_String &aUserAgent, const bool isOverwritable = false);
   1259         virtual ~UserAgentField()
   1260         {
   1261             ;
   1262         }
   1263 
   1264         // set user agent
   1265         OSCL_IMPORT_REF bool setUserAgent(OSCL_wString &aUserAgent, const bool isOverwritable = false);
   1266         OSCL_IMPORT_REF bool setUserAgent(OSCL_String &aUserAgent, const bool isOverwritable = false);
   1267 
   1268         // get the actual user agent (not wide string version) based on overwrite mode or replace mode (attach the input user agent to the default one)
   1269         OSCL_IMPORT_REF bool getUserAgent(OSCL_String &aUserAgent);
   1270 
   1271     protected:
   1272         virtual void getDefaultUserAgent(OSCL_String &aUserAgent) = 0;
   1273 
   1274     protected:
   1275         OSCL_HeapString<OsclMemAllocator> iInputUserAgent;
   1276         OSCL_HeapString<OsclMemAllocator> iActualUserAgent;
   1277         bool iOverwritable;
   1278 };
   1279 
   1280 typedef Oscl_Vector<OutgoingMsgSentSuccessInfo, PVMFProtocolEngineNodeAllocator> OutgoingMsgSentSuccessInfoVec;
   1281 
   1282 // This class interfaces between the node and node user, which is in fact a data holder and holds the data set by the node public APIs
   1283 // and some output data return to node user
   1284 class InterfacingObjectContainer
   1285 {
   1286     public:
   1287         // set and get download format
   1288         void setDownloadFormat(PVMFFormatType &aDownloadFormat)
   1289         {
   1290             iDownloadFormat = (PVMFFormatType)aDownloadFormat;
   1291         }
   1292         PVMFFormatType getDownloadFormat() const
   1293         {
   1294             return iDownloadFormat;
   1295         }
   1296 
   1297         // set and get url
   1298         void setURI(OSCL_String &aUri, const bool aRedirectUri = false)
   1299         {
   1300             iDownloadURI.setURI(aUri, aRedirectUri);
   1301         }
   1302         void setURI(OSCL_wString &aUri, const bool aRedirectUri = false)
   1303         {
   1304             iDownloadURI.setURI(aUri, aRedirectUri);
   1305         }
   1306         INetURI &getURIObject()
   1307         {
   1308             return iDownloadURI;
   1309         }
   1310 
   1311         void setLoggingURI(OSCL_String &aUri)
   1312         {
   1313             iLoggingURI.setURI(aUri);
   1314         }
   1315         void setLoggingURI(OSCL_wString &aUri)
   1316         {
   1317             iLoggingURI.setURI(aUri);
   1318         }
   1319         INetURI &getLoggingURIObject()
   1320         {
   1321             return iLoggingURI;
   1322         }
   1323 
   1324         // set and get data stream factory
   1325         void setDataStreamFactory(const PVMFDataStreamFactory *aDataStreamFactory)
   1326         {
   1327             iDataStreamFactory = (PVMFDataStreamFactory *)aDataStreamFactory;
   1328         }
   1329         PVMFDataStreamFactory *getDataStreamFactory()
   1330         {
   1331             return iDataStreamFactory;
   1332         }
   1333 
   1334         // set and get stream parameters in http streaming
   1335         void setStreamParams(PVMFProtocolEngineNodeMSHTTPStreamingParams &aStreamParams)
   1336         {
   1337             iStreamParams = aStreamParams;
   1338         }
   1339         PVProtocolEngineMSHttpStreamingParams *getStreamParams()
   1340         {
   1341             return &iStreamParams;
   1342         }
   1343 
   1344         //set fast cache setting
   1345         void SetAccelBitrate(uint32 aAccelBitrate)
   1346         {
   1347             iStreamParams.iAccelBitrate = aAccelBitrate;
   1348         }
   1349         void SetAccelDuration(uint32 aAccelDuration)
   1350         {
   1351             iStreamParams.iAccelDuration = aAccelDuration;
   1352         }
   1353 
   1354         //set max streaming size
   1355         void SetMaxHttpStreamingSize(uint32 aMaxHttpStreamingSize)
   1356         {
   1357             iStreamParams.iMaxHttpStreamingSize = aMaxHttpStreamingSize;
   1358         }
   1359 
   1360         // set and get number of buffers in media message allocator in http streaming
   1361         void setMediaMsgAllocatorNumBuffers(const uint32 aNumBuffersInAllocator)
   1362         {
   1363             iNumBuffersInAllocator = aNumBuffersInAllocator;
   1364         }
   1365         uint32 getMediaMsgAllocatorNumBuffers() const
   1366         {
   1367             return iNumBuffersInAllocator;
   1368         }
   1369 
   1370         // set and get number of redirect trials
   1371         void setNumRedirectTrials(const uint32 aNumRedirectTrials)
   1372         {
   1373             iNumRedirectTrials = aNumRedirectTrials;
   1374         }
   1375         void setCurrNumRedirectTrials(const uint32 aCurrNumRedirectTrials)
   1376         {
   1377             iCurrRedirectTrials = aCurrNumRedirectTrials;
   1378         }
   1379         uint32 getNumRedirectTrials() const
   1380         {
   1381             return iNumRedirectTrials;
   1382         }
   1383         uint32 getCurrNumRedirectTrials() const
   1384         {
   1385             return iCurrRedirectTrials;
   1386         }
   1387 
   1388         // set and get http header
   1389         // return the actual http header length, 0 means no header
   1390         OSCL_IMPORT_REF uint32 setHttpHeader(OUTPUT_DATA_QUEUE &aHttpHeader);
   1391         void getHTTPHeader(uint8*& aHeader, uint32& aHeaderLen)
   1392         {
   1393             aHeader = (uint8*)iHttpHeaderBuffer;
   1394             aHeaderLen = iHttpHeaderLength;
   1395         }
   1396 
   1397         // set and get file size
   1398         void setFileSize(const uint32 aFileSize)
   1399         {
   1400             iFileSize = aFileSize;
   1401         }
   1402         uint32 getFileSize() const
   1403         {
   1404             return iFileSize;
   1405         }
   1406 
   1407         // socket connect flags
   1408         void updateSocketConnectFlags(const bool isEOS)
   1409         {
   1410             if (!iCurrSocketConnection && !isEOS) iSocketReconnectCmdSent = false; // when connnection becomes from down (EOS) to up, clear the flag of sending socket reconnect command
   1411             iPrevSocketConnection = iCurrSocketConnection;
   1412             iCurrSocketConnection = !isEOS;
   1413         }
   1414         bool isSocketConnectionUp() const
   1415         {
   1416             return iCurrSocketConnection;
   1417         }
   1418         bool isPrevSocketConnectionUp() const
   1419         {
   1420             return iPrevSocketConnection;
   1421         }
   1422         bool isSocketReconnectCmdSent() const
   1423         {
   1424             return iSocketReconnectCmdSent;
   1425         }
   1426         void setSocketReconnectCmdSent(const bool aSocketReconnectCmdSent = true)
   1427         {
   1428             iSocketReconnectCmdSent = aSocketReconnectCmdSent;
   1429             iCurrSocketConnection = true;
   1430             iPrevSocketConnection = true;
   1431         }
   1432         bool ignoreCurrentInputData() const
   1433         {
   1434             return isCurrentInputDataUnwanted;
   1435         }
   1436         void setInputDataUnwanted(const bool aInputDataUnwanted = true)
   1437         {
   1438             isCurrentInputDataUnwanted = aInputDataUnwanted;
   1439         }
   1440 
   1441         // KeepAlive timeout
   1442         void setKeepAliveTimeout(const uint32 aTimeout)
   1443         {
   1444             iKeepAliveTimeout = aTimeout;
   1445         }
   1446         uint32 getKeepAliveTimeout() const
   1447         {
   1448             return iKeepAliveTimeout;
   1449         }
   1450 
   1451         // Streaming proxy
   1452         OSCL_IMPORT_REF bool setStreamingProxy(OSCL_wString& aProxyName, const uint32 aProxyPort = DEFAULT_HTTP_PORT_NUMBER);
   1453         void getStreamingProxy(OSCL_String& aProxyName, uint32 &aProxyPort)
   1454         {
   1455             aProxyName = iProxyName;
   1456             aProxyPort = iProxyPort;
   1457         }
   1458 
   1459         // flag of disabling HTTP HEAD request
   1460         void setHttpHeadRequestDisabled(const bool aDisableHeadRequest = true)
   1461         {
   1462             iDisableHeadRequest = aDisableHeadRequest;
   1463         }
   1464         bool getHttpHeadRequestDisabled() const
   1465         {
   1466             return iDisableHeadRequest;
   1467         }
   1468 
   1469         // maximum ASF header size
   1470         void setMaxASFHeaderSize(const uint32 aMaxASFHeaderSize)
   1471         {
   1472             iMaxASFHeaderSize = aMaxASFHeaderSize;
   1473         }
   1474         uint32 getMaxASFHeaderSize() const
   1475         {
   1476             return iMaxASFHeaderSize;
   1477         }
   1478 
   1479         // latest packet number just sent to downstream node successfully
   1480         void setLatestPacketNumSent(const uint32 aPacketNum)
   1481         {
   1482             iLatestDataPacketNumSent = aPacketNum;
   1483         }
   1484         uint32 getLatestPacketNumSent() const
   1485         {
   1486             return iLatestDataPacketNumSent;
   1487         }
   1488 
   1489         // user-id and password for HTTP authentication
   1490         void setUserAuthInfo(OSCL_String &aUserID, OSCL_String &aPasswd)
   1491         {
   1492             if (aUserID.get_size() > 0)
   1493             {
   1494                 iStreamParams.iUserID = OSCL_HeapString<OsclMemAllocator> (aUserID.get_cstr(), aUserID.get_size());
   1495             }
   1496             if (aPasswd.get_size() > 0)
   1497             {
   1498                 iStreamParams.iUserPasswd = OSCL_HeapString<OsclMemAllocator> (aPasswd.get_cstr(), aPasswd.get_size());
   1499             }
   1500         }
   1501 
   1502         OSCL_IMPORT_REF void setNumBuffersInMediaDataPoolSMCalc(uint32 aVal);
   1503         uint32 getNumBuffersInMediaDataPoolSMCalc() const
   1504         {
   1505             return iNumBuffersInMediaDataPoolSMCalc;
   1506         }
   1507         // iOutputPortConnected
   1508         void setOutputPortConnect(const bool aConnected = true)
   1509         {
   1510             iOutputPortConnected = aConnected;
   1511         }
   1512         bool getOutputPortConnect() const
   1513         {
   1514             return iOutputPortConnected;
   1515         }
   1516 
   1517         // iCancelCmdHappened
   1518         void setCancelCmdHappened(const bool aCancelCmdHappened = true)
   1519         {
   1520             iCancelCmdHappened = aCancelCmdHappened;
   1521         }
   1522         bool getCancelCmdHappened() const
   1523         {
   1524             return iCancelCmdHappened;
   1525         }
   1526 
   1527         // iEOPInfo
   1528         EndOfDataProcessingInfo *getEOPInfo()
   1529         {
   1530             return &iEOPInfo;
   1531         }
   1532 
   1533         // protocol state complete info
   1534         void setProtocolStateCompleteInfo(const ProtocolStateCompleteInfo &aInfo, const bool aForceSet = false)
   1535         {
   1536             if (!aForceSet)
   1537             {
   1538                 if (aInfo.isDownloadStreamingDone) iProtocolStateCompleteInfo.isDownloadStreamingDone = true;
   1539                 if (aInfo.isWholeSessionDone)     iProtocolStateCompleteInfo.isWholeSessionDone = true;
   1540                 if (aInfo.isEOSAchieved)              iProtocolStateCompleteInfo.isEOSAchieved = true;
   1541             }
   1542             else
   1543             {
   1544                 iProtocolStateCompleteInfo.isDownloadStreamingDone = aInfo.isDownloadStreamingDone;
   1545                 iProtocolStateCompleteInfo.isWholeSessionDone      = aInfo.isWholeSessionDone;
   1546                 iProtocolStateCompleteInfo.isEOSAchieved           = aInfo.isEOSAchieved;
   1547             }
   1548         }
   1549         ProtocolStateCompleteInfo *getProtocolStateCompleteInfo()
   1550         {
   1551             return &iProtocolStateCompleteInfo;
   1552         }
   1553 
   1554         OutgoingMsgSentSuccessInfoVec *getOutgoingMsgSentSuccessInfoVec()
   1555         {
   1556             return &iOutgoingMsgSentSuccessInfoVec;
   1557         }
   1558 
   1559         bool isDownloadStreamingDone()
   1560         {
   1561             return iProtocolStateCompleteInfo.isDownloadStreamingDone;
   1562         }
   1563         bool isWholeSessionDone()
   1564         {
   1565             return iProtocolStateCompleteInfo.isWholeSessionDone;
   1566         }
   1567         bool isEOSAchieved()
   1568         {
   1569             return iProtocolStateCompleteInfo.isEOSAchieved;
   1570         }
   1571 
   1572         void setTruncatedForLimitSize(const bool aTruncatedForLimitSize = false)
   1573         {
   1574             iTruncatedForLimitSize = aTruncatedForLimitSize;
   1575         }
   1576         bool getTruncatedForLimitSize() const
   1577         {
   1578             return iTruncatedForLimitSize;
   1579         }
   1580 
   1581         // constructor
   1582         InterfacingObjectContainer();
   1583         ~InterfacingObjectContainer()
   1584         {
   1585             clear();
   1586             iOutgoingMsgSentSuccessInfoVec.clear();
   1587         }
   1588 
   1589         // clear
   1590         void clear()
   1591         {
   1592             iHttpHeaderLength           = 0;
   1593             iFileSize                   = 0;
   1594             iSocketReconnectCmdSent     = false;
   1595             iCurrRedirectTrials         = 0;
   1596             isCurrentInputDataUnwanted  = true; // when clear(), treat all the input data unwanted (that needs to be ignored), let command and event to enable it
   1597             iProcessingDone             = false;
   1598             iKeepAliveTimeout           = 0;
   1599             iDisableHeadRequest         = true; // changed on the request of Japan
   1600             iMaxASFHeaderSize           = 0;
   1601             iCancelCmdHappened          = false;
   1602             iTruncatedForLimitSize      = false;
   1603             iProtocolStateCompleteInfo.clear();
   1604         }
   1605 
   1606     private:
   1607         PVMFFormatType  iDownloadFormat;
   1608         // set by SetSourceInitializationData()
   1609         INetURI iDownloadURI;
   1610         // set by SetLoggingURL
   1611         INetURI iLoggingURI;
   1612         // set by PassDatastreamFactory()
   1613         PVMFDataStreamFactory *iDataStreamFactory;
   1614         // set by SetStreamParams()
   1615         PVProtocolEngineMSHttpStreamingParams iStreamParams;
   1616         // set by SetMediaMsgAllocatorNumBuffers()
   1617         uint32 iNumBuffersInAllocator;
   1618         // set by SetNumRedirectTrials
   1619         uint32 iNumRedirectTrials;
   1620         uint32 iCurrRedirectTrials;
   1621 
   1622         uint32 iNumBuffersInMediaDataPoolSMCalc;
   1623         // get from GetHTTPHeader()
   1624         char iHttpHeaderBuffer[PVHTTPDOWNLOADOUTPUT_CONTENTDATA_CHUNKSIZE+1]; // to hold http header
   1625         uint32 iHttpHeaderLength;
   1626         // get from GetFileSize()
   1627         uint32 iFileSize;
   1628 
   1629         // socket connect flags
   1630         bool iCurrSocketConnection; // true means the connection is up and on ; false means the connection is downn
   1631         bool iPrevSocketConnection; // the status of previous socket connection
   1632         bool iSocketReconnectCmdSent; // flag to record whether the socket reconnect command is sent
   1633 
   1634         // this flag is introduced to ignore unwanted incoming messages in certain scenarios,
   1635         // such as stop/reset/cancel, protocol state complete/error, while init/prepare/start command would disable
   1636         // this flag
   1637         bool isCurrentInputDataUnwanted;
   1638 
   1639         bool iProcessingDone; // work as a global variable
   1640 
   1641         uint32 iKeepAliveTimeout;
   1642 
   1643         // streaming proxy and port
   1644         OSCL_HeapString<OsclMemAllocator> iProxyName;
   1645         uint32 iProxyPort;
   1646 
   1647         bool iDisableHeadRequest;
   1648         uint32 iMaxASFHeaderSize;
   1649         uint32 iLatestDataPacketNumSent;
   1650 
   1651         // the connection status between PE node output port and downstream(JB) node input port
   1652         // this flag will help sending EOS or not
   1653         bool iOutputPortConnected;
   1654 
   1655         bool iCancelCmdHappened;
   1656 
   1657         // work as a global variable
   1658         EndOfDataProcessingInfo iEOPInfo;
   1659         ProtocolStateCompleteInfo iProtocolStateCompleteInfo;
   1660         OutgoingMsgSentSuccessInfoVec iOutgoingMsgSentSuccessInfoVec;
   1661 
   1662         // This flag mean data-size reach limitation or not
   1663         // true : data reached limitation
   1664         // false: data don't reach limitation
   1665         bool iTruncatedForLimitSize;
   1666 };
   1667 
   1668 
   1669 ////////////////////////////////////////////////////////////////////////////////////
   1670 //////  PVMFProtocolEngineNodeTimer
   1671 ////////////////////////////////////////////////////////////////////////////////////
   1672 
   1673 // This class wraps OsclTimer<allocator> to hide some details and make call more expressive
   1674 struct TimerUnit
   1675 {
   1676     uint32 iTimerID;
   1677     uint32 iTimeout;
   1678 
   1679     // constructor
   1680     TimerUnit() : iTimerID(0), iTimeout(0)
   1681     {
   1682         ;
   1683     }
   1684     TimerUnit(const uint32 aTimerID, const uint32 aTimeout) : iTimerID(aTimerID), iTimeout(aTimeout)
   1685     {
   1686         ;
   1687     }
   1688 };
   1689 
   1690 class PVMFProtocolEngineNodeTimer
   1691 {
   1692     public:
   1693         // factory and destructor
   1694         OSCL_IMPORT_REF static PVMFProtocolEngineNodeTimer* create(OsclTimerObserver *aObserver);
   1695         OSCL_IMPORT_REF ~PVMFProtocolEngineNodeTimer();
   1696 
   1697         // register and set timer id and timeout value
   1698         // note that if aTimeout=0, that means using the internal default one
   1699         OSCL_IMPORT_REF void set(const uint32 aTimerID, const int32 aTimeout = 0);
   1700 
   1701         // get the timeout value for specific timer id. If not set, return default value
   1702         // if input timer id is not registered, will return 0xffffffff
   1703         OSCL_IMPORT_REF uint32 getTimeout(const uint32 aTimerID);
   1704 
   1705         // start the timer with optional new timeout value, aTimeout=0 means using the existing one
   1706         // if the timer id doesn't exist, it will return failure, which means set() has to be called before start()
   1707         OSCL_IMPORT_REF bool start(const uint32 aTimerID, const int32 aTimeout = 0);
   1708 
   1709         OSCL_IMPORT_REF void cancel(const uint32 aTimerID);
   1710         OSCL_IMPORT_REF void clear();
   1711 
   1712         // clear all the timers except the timer with the given timer ID
   1713         OSCL_IMPORT_REF void clearExcept(const uint32 aTimerID);
   1714 
   1715     private:
   1716         // constructor
   1717         PVMFProtocolEngineNodeTimer() : iWatchdogTimer(NULL)
   1718         {
   1719             ;
   1720         }
   1721         bool construct(OsclTimerObserver *aObserver);
   1722 
   1723         uint32 getDefaultTimeout(const uint32 aTimerID);
   1724         uint32 getTimerVectorIndex(const uint32 aTimerID);
   1725 
   1726     private:
   1727         OsclTimer<PVMFProtocolEngineNodeAllocator>  *iWatchdogTimer;
   1728         Oscl_Vector<TimerUnit, PVMFProtocolEngineNodeAllocator> iTimerVec;
   1729 };
   1730 
   1731 #endif
   1732