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 #ifndef PVMF_PROTOCOLENGINE_COMMON_H_INCLUDED
     19 #define PVMF_PROTOCOLENGINE_COMMON_H_INCLUDED
     20 
     21 #include "pvmf_protocol_engine_internal.h"
     22 
     23 #define DATAPATHLOGGER_TAG "protocolenginenode.protocolengine"
     24 #define DATAPATHERRLOGGER_TAG "datapath.sourcenode.protocolenginenode"
     25 
     26 class UserCommands
     27 {
     28     public:
     29         virtual ~UserCommands() {}
     30 
     31         // aSeekPosition can be time-based (in MS HTTP streaming) or byte-based (in progressive streaming
     32         virtual void seek(const uint32 aSeekPosition) = 0;
     33         virtual void stop(const bool isAfterEOS = false) = 0;
     34         virtual void pause(const bool isFirstCallInPause = true) = 0;
     35         virtual void resume() = 0;
     36         virtual void sendRequest() = 0;
     37         virtual void gotoNextState() = 0;
     38         virtual void bitstreamSwitch() = 0;
     39 };
     40 
     41 // Any http-based protocol(progressive download, fasttrack, ms http streaming and real http cloaking)
     42 // can be viewed as a http request-response sequence, which can be addressed by GoF state pattern, i.e. ProtocolState class
     43 // And protocol variances can be abstracted and hidden by using a common interface class, HttpBasedProtocol
     44 // HttpBasedProtocol serves as the context of state class, and also provides the APIs for protocol user.
     45 
     46 enum ProtocolEngineOutputDataType
     47 {
     48     ProtocolEngineOutputDataType_HttpHeader = 0,
     49     ProtocolEngineOutputDataType_FirstDataPacket,
     50     ProtocolEngineOutputDataType_NormalData
     51 };
     52 
     53 struct ProtocolEngineOutputDataSideInfo
     54 {
     55     ProtocolEngineOutputDataType iDataType;
     56     // for OutputDataType_FirstDataPacket,  iData = iFirstPacketNumber
     57     // for OutputDataType_NormalData,       iData = iCurrentDataStreamOffset (for fasttrack) / iCurrPacketNum (for http streaming)
     58     OsclAny *iData;
     59 
     60     // constructors
     61     ProtocolEngineOutputDataSideInfo() : iDataType(ProtocolEngineOutputDataType_HttpHeader), iData(0)
     62     {
     63         ;
     64     }
     65     ProtocolEngineOutputDataSideInfo(const ProtocolEngineOutputDataType aType, OsclAny *aData) :
     66             iDataType(aType), iData(aData)
     67     {
     68         ;
     69     }
     70 
     71     void set(const ProtocolEngineOutputDataType aDataType, const OsclAny *aData = 0)
     72     {
     73         iDataType = (ProtocolEngineOutputDataType)aDataType;
     74         iData = (OsclAny *)aData;
     75     }
     76 };
     77 
     78 struct ProtocolEngineOutputDataSideInfoForFasttrack
     79 {
     80     uint32 iCurrDataStreamOffset;
     81     uint32 iCurrPlaybackTime;
     82 
     83     ProtocolEngineOutputDataSideInfoForFasttrack() :
     84             iCurrDataStreamOffset(0), iCurrPlaybackTime(0) {}
     85 };
     86 
     87 
     88 enum ProtocolRequestType
     89 {
     90     ProtocolRequestType_Normaldata = 0,
     91     ProtocolRequestType_Logging
     92 };
     93 
     94 struct ProtocolStateCompleteInfo
     95 {
     96     bool isDownloadStreamingDone;  // true => current state complete means download or streaming is done/complete
     97     bool isWholeSessionDone;         // true => current state is the last state of the state transition table
     98     bool isEOSAchieved;              // true => EOS packet is received in streaming, or download reaches EOS (content-length, server discconnect or maximum file size)
     99     // for protocol engine side, isDownloadStreamingDone=true <=> isEOSAchieved=true, but node will use this structure for other
    100     // purposes, e.g. this flag can be used to differentiate stop case and true EOS case
    101     // constructors
    102     ProtocolStateCompleteInfo()
    103     {
    104         clear();
    105     }
    106     ProtocolStateCompleteInfo(const ProtocolStateCompleteInfo &x)
    107     {
    108         isDownloadStreamingDone = x.isDownloadStreamingDone;
    109         isWholeSessionDone      = x.isWholeSessionDone;
    110         isEOSAchieved           = x.isEOSAchieved;
    111     }
    112     ProtocolStateCompleteInfo(const bool aDownloadStreamingDone, const bool aSessionDone, const bool aEOSAchieved) :
    113             isDownloadStreamingDone(aDownloadStreamingDone),
    114             isWholeSessionDone(aSessionDone),
    115             isEOSAchieved(aEOSAchieved)
    116     {
    117         ;
    118     }
    119 
    120     // assignment operator
    121     ProtocolStateCompleteInfo& operator=(const ProtocolStateCompleteInfo& x)
    122     {
    123         isDownloadStreamingDone = x.isDownloadStreamingDone;
    124         isWholeSessionDone      = x.isWholeSessionDone;
    125         isEOSAchieved           = x.isEOSAchieved;
    126         return *this;
    127     }
    128 
    129     // clear
    130     void clear()
    131     {
    132         isDownloadStreamingDone = false;
    133         isWholeSessionDone      = false;
    134         isEOSAchieved           = false;
    135     }
    136 };
    137 
    138 
    139 // This observer class is designed to notify state user (specifically, protocol) when one protocol state is completely finished, i.e.
    140 // one http request-response is completely done or parsing response is completely done. Then user may change to next protocol state
    141 class ProtocolStateObserver
    142 {
    143     public:
    144         virtual ~ProtocolStateObserver() {}
    145 
    146         virtual void ProtocolStateComplete(const ProtocolStateCompleteInfo &aInfo) = 0;
    147         virtual void OutputDataAvailable(OUTPUT_DATA_QUEUE &aOutputQueue, ProtocolEngineOutputDataSideInfo& aSideInfo) = 0;
    148         virtual void ProtocolStateError(int32 aErrorCode) = 0; // server response error or other internal fatal error
    149         virtual bool GetBufferForRequest(PVMFSharedMediaDataPtr &aMediaData) = 0; // to contruct HTTP request
    150         virtual void ProtocolRequestAvailable(uint32 aRequestType = ProtocolRequestType_Normaldata) = 0; // need to send to port
    151 };
    152 
    153 // This class is based on state pattern, to encapsulate all state specific behavior.
    154 class ProtocolState : public HttpParsingBasicObjectObserver,
    155         public UserCommands
    156 {
    157     public:
    158         // has base implementation, basically create a templete
    159         OSCL_IMPORT_REF virtual int32 processMicroState(INPUT_DATA_QUEUE &aDataQueue);
    160 
    161         // protocol objects own these objects, observer, composer and parser
    162         // need to pass these objects down to state objects
    163         void setObserver(ProtocolStateObserver *aObserver)
    164         {
    165             iObserver = aObserver;
    166         }
    167         void setComposer(HTTPComposer *aComposer)
    168         {
    169             iComposer = aComposer;
    170         }
    171         void setParser(HttpParsingBasicObject *aParser)
    172         {
    173             iParser = aParser;
    174         }
    175 
    176         // set functions, will be delegated to ProtocolState to handle
    177         // set config info for composing request
    178         void setURI(const INetURI &aUri)
    179         {
    180             iURI = aUri;
    181         }
    182         virtual void setLoggingURI(const INetURI &aUri)
    183         {
    184             OSCL_UNUSED_ARG(aUri);
    185         }
    186         virtual void setConfigInfo(OsclAny* aConfigInfo) = 0;
    187 
    188         // get functions to expose the information that node needs
    189         // The header could be http header, sdp or asf header
    190         OSCL_IMPORT_REF virtual bool getHeader(Oscl_Vector<OsclRefCounterMemFrag, OsclMemAllocator> &aHeader) = 0;
    191         virtual uint32 getContentLength()
    192         {
    193             return (iParser == NULL ? 0 : iParser->getContentLength());
    194         }
    195         virtual uint32 getDownloadSize()
    196         {
    197             return (iParser == NULL ? 0 : iParser->getDownloadSize());
    198         }
    199         virtual uint32 getRemainingSize()
    200         {
    201             if (iParser == NULL || iParser->getContentLength() == 0) return 0;
    202             return iParser->getContentLength() - iParser->getDownloadSize();
    203         }
    204         OSCL_IMPORT_REF virtual uint32 getDownloadRate();
    205         OSCL_IMPORT_REF uint32 getDownloadTimeForEstimation();
    206         uint32 getResponseStatusCode()
    207         {
    208             return (iParser == NULL ? 0 : iParser->getStatusCode());
    209         }
    210         bool getRedirectURI(OSCL_String &aRedirectUri)
    211         {
    212             return iParser->getRedirectURI(aRedirectUri);
    213         }
    214         bool getContentType(OSCL_String &aContentType)
    215         {
    216             return iParser->getContentType(aContentType);
    217         }
    218         bool getAuthenInfo(OSCL_String &aRealm)
    219         {
    220             return iParser->getAuthenInfo(aRealm);
    221         }
    222         bool isServerSupportBasicAuthentication()
    223         {
    224             return iParser->isServerSupportBasicAuthentication();
    225         }
    226         bool isServerSendAuthenticationHeader()
    227         {
    228             return iParser->isServerSendAuthenticationHeader();
    229         }
    230         void getBasicPtr(const StrPtrLen aAuthenValue, uint32 &length)
    231         {
    232             iParser->getBasicPtr(aAuthenValue, length);
    233         }
    234         void getRealmPtr(const char *&ptrRealm, uint32 &len, uint32 &length)
    235         {
    236             iParser->getRealmPtr(ptrRealm, len, length);
    237         }
    238         virtual uint32 getCurrentPlaybackTime()
    239         {
    240             return 0;    // only used in fast track
    241         }
    242         virtual uint32 getTimeoutInMs()
    243         {
    244             return 0;    // ms http streaming only
    245         }
    246         virtual uint32 getServerVersionNumber()
    247         {
    248             return (iParser == NULL ? 0 : iParser->getServerVersionNumber());
    249         }
    250         virtual void prepare()
    251         {
    252             ;    // prepare for the new state, especially store data from the previous state, for the current state
    253         }
    254         bool isSendingNewRequest()
    255         {
    256             return (iProcessingState == EHttpProcessingMicroState_SendRequest);
    257         }
    258         virtual bool isCurrentStateOptional()
    259         {
    260             return false;    // optional state can be by-passed regardless of any error happened
    261         }
    262         virtual void setLastState()
    263         {
    264             ;
    265         }
    266         virtual uint32 getMediaDataLength()
    267         {
    268             return 0;
    269         }
    270         virtual uint32 getContenBitrate()
    271         {
    272             return 0;
    273         }
    274 
    275         // user commands
    276         virtual void seek(const uint32 aSeekPosition)
    277         {
    278             OSCL_UNUSED_ARG(aSeekPosition);    // only used in ms http streaming for now
    279         }
    280         virtual void stop(const bool isAfterEOS = false)
    281         {
    282             OSCL_UNUSED_ARG(isAfterEOS);    // only used in ms http streaming for now
    283         }
    284         virtual void pause(const bool isFirstCallInPause = true)
    285         {
    286             OSCL_UNUSED_ARG(isFirstCallInPause);    // only used in ms http streaming for now
    287         }
    288         virtual void resume()
    289         {
    290             ;    // only used in ms http streaming for now
    291         }
    292         virtual void sendRequest()
    293         {
    294             iProcessingState = EHttpProcessingMicroState_SendRequest;
    295         }
    296         virtual void bitstreamSwitch()
    297         {
    298             ;
    299         }
    300         void gotoNextState()
    301         {
    302             ;
    303         }
    304 
    305         // constructor
    306         ProtocolState() : iComposer(NULL),
    307                 iParser(NULL),
    308                 iProcessingState(EHttpProcessingMicroState_SendRequest),
    309                 iObserver(NULL),
    310                 iNeedGetResponsePreCheck(true)
    311         {
    312             iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode.protocolenginenode");
    313         }
    314 
    315         virtual ~ProtocolState()
    316         {
    317             iComposer = NULL;
    318             iParser   = NULL;
    319             iObserver = NULL;
    320             iDataPathLogger = NULL;
    321         };
    322 
    323         virtual void reset()
    324         {
    325             if (iComposer) iComposer->reset();
    326             if (iParser) iParser->reset();
    327             iNeedGetResponsePreCheck = true;
    328         }
    329 
    330     protected:
    331         // From HttpParsingBasicObjectObserver
    332         virtual int32 OutputDataAvailable(OUTPUT_DATA_QUEUE *aOutputQueue, const bool isHttpHeader)
    333         {
    334             OSCL_UNUSED_ARG(aOutputQueue);
    335             OSCL_UNUSED_ARG(isHttpHeader);
    336             return PROCESS_SUCCESS;
    337         }
    338 
    339         /////////////////////////////////////////////////////////////////////////////
    340         /////// Following APIs are related composing and sending http request ///////
    341         /////////////////////////////////////////////////////////////////////////////
    342         // check all the info is ready for composing and sending a request
    343         OSCL_IMPORT_REF virtual int32 processMicroStateSendRequestPreCheck();
    344         OSCL_IMPORT_REF virtual int32 processMicroStateSendRequest();
    345         int32 composeRequest(OsclMemoryFragment &aFrag);
    346         // By default HTTP GET method, derived class may need to override this one
    347         virtual void setRequestBasics() = 0;
    348         // Each derived class needs to implement this one
    349         virtual bool setHeaderFields() = 0;
    350         // do final compose, fixed for all derived classes
    351         OSCL_IMPORT_REF virtual int32 doCompose(OsclMemoryFragment &aFrag);
    352         OSCL_IMPORT_REF bool setExtensionFields(Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> &aExtensionHeaderKeys,
    353                                                 Oscl_Vector<OSCL_HeapString<OsclMemAllocator>, OsclMemAllocator> &aExtensionHeaderValues,
    354                                                 Oscl_Vector<uint32, OsclMemAllocator> &aMaskBitForHTTPMethod,
    355                                                 Oscl_Vector<bool, OsclMemAllocator> &aExtensionHeadersPurgeOnRedirect,
    356                                                 const HTTPMethod aMethod = HTTP_METHOD_GET);
    357         virtual bool getProtocolRequestType()
    358         {
    359             return (uint32)ProtocolRequestType_Normaldata;
    360         }
    361 
    362         // HTTP basic/digest authentication (RFC 2617)
    363         OSCL_IMPORT_REF bool constructAuthenHeader(OSCL_String &aUserID, OSCL_String &aPasswd);
    364 
    365         /////////////////////////////////////////////////////////////////////////////
    366         /////// Following APIs are related parsing http response ////////////////////
    367         /////////////////////////////////////////////////////////////////////////////
    368         // check all the info is ready for parsing a new response
    369         OSCL_IMPORT_REF virtual int32 processMicroStateGetResponsePreCheck();
    370         OSCL_IMPORT_REF virtual int32 processMicroStateGetResponse(INPUT_DATA_QUEUE &aDataQueue);
    371         // shared routine for all the download protocols
    372         OSCL_IMPORT_REF virtual int32 checkParsingStatus(int32 parsingStatus);
    373 
    374         virtual bool isDownloadStreamingDoneState()
    375         {
    376             return false;
    377         }
    378         virtual bool isLastState()
    379         {
    380             return false;
    381         }
    382 
    383     private:
    384 
    385         // factor processMicroState() into the following methods to prevent processMicroState() getting bloated
    386         int32 doProcessMicroStateSendRequestPreCheck();
    387         int32 doProcessMicroStateSendRequest();
    388         int32 doProcessMicroStateGetResponsePreCheck();
    389         int32 doProcessMicroStateGetResponse(INPUT_DATA_QUEUE &aDataQueue);
    390 
    391         // support setExtensionFields()
    392         uint32 getBitMaskForHttpMethod(Oscl_Vector<uint32, OsclMemAllocator> &aMaskBitForHTTPMethod,
    393                                        const HTTPMethod aMethod);
    394         // called by checkParsingStatus()
    395         int32 handleParsingSyntaxError();
    396 
    397         // called by constructAuthenHeader()
    398         int32 base64enc(char *data, char *out);
    399 
    400     protected:
    401         // http composer and parser should be life-time long, shouldn't be affected by state transition.
    402         // So protocol object owns these two objects.
    403         HTTPComposer *iComposer;
    404         HttpParsingBasicObject *iParser; // wrap http parser to do parsing for each input media data
    405         pvHttpProcessingMicroState iProcessingState;
    406 
    407         ProtocolStateObserver *iObserver;
    408         INetURI iURI; // wrapper for url parsing
    409         TimeValue iStartTime;
    410         bool iNeedGetResponsePreCheck;
    411         ProtocolEngineOutputDataSideInfo iDataSideInfo;
    412         PVLogger *iDataPathLogger;
    413 };
    414 
    415 // This observer class is designed to notify protocol user (specifically, node) when one protocol state is completely finished, i.e.
    416 // one http request-response or parsing response is completely done. Then user may change to next protocol state
    417 class ProtocolObserver
    418 {
    419     public:
    420         virtual ~ProtocolObserver() {}
    421 
    422         virtual void ProtocolStateComplete(const ProtocolStateCompleteInfo &aInfo) = 0;
    423         virtual void OutputDataAvailable(OUTPUT_DATA_QUEUE &aOutputQueue, ProtocolEngineOutputDataSideInfo &aSideInfo) = 0;
    424         virtual void ProtocolStateError(int32 aErrorCode) = 0; // server response error or other internal fatal error
    425         virtual bool GetBufferForRequest(PVMFSharedMediaDataPtr &aMediaData) = 0; // to contruct HTTP request
    426         virtual void ProtocolRequestAvailable(uint32 aRequestType = ProtocolRequestType_Normaldata) = 0; // need to send to port
    427 };
    428 
    429 // Any http-based protocol(progressive download, fasttrack, ms http streaming and real http cloaking)
    430 // can be viewed as a http request-response sequence, which can be addressed by GoF state pattern
    431 class HttpBasedProtocol : public ProtocolStateObserver,
    432         public UserCommands
    433 {
    434     public:
    435         // each http based protocol must implment this interface
    436         virtual int32 runStateMachine(INPUT_DATA_QUEUE &aDataQueue)
    437         {
    438             return iCurrState->processMicroState(aDataQueue);
    439         }
    440 
    441         // From ProtocolStateObserver
    442         virtual void ProtocolStateComplete(const ProtocolStateCompleteInfo &aInfo)
    443         {
    444             // change to the next protocol state and notify the user that data processing at the current state is completely done
    445             if (iObserver) iObserver->ProtocolStateComplete(aInfo);
    446             //if(isSuccess) iCurrState = getNextState();
    447         }
    448         virtual void OutputDataAvailable(OUTPUT_DATA_QUEUE &aOutputQueue, ProtocolEngineOutputDataSideInfo &aSideInfo)
    449         {
    450             if (iObserver) iObserver->OutputDataAvailable(aOutputQueue, aSideInfo);
    451         }
    452         virtual void ProtocolStateError(int32 aErrorCode)
    453         {
    454             if (iObserver) iObserver->ProtocolStateError(aErrorCode);
    455         }
    456 
    457         virtual bool GetBufferForRequest(PVMFSharedMediaDataPtr &aMediaData)
    458         {
    459             return iObserver->GetBufferForRequest(aMediaData);
    460         }
    461 
    462         virtual void ProtocolRequestAvailable(uint32 aRequestType = ProtocolRequestType_Normaldata)
    463         {
    464             if (iObserver) iObserver->ProtocolRequestAvailable(aRequestType);
    465         }
    466 
    467         // initialize means passing protocol owned objects down to state objects
    468         virtual void initialize() = 0;
    469 
    470         // user commands
    471         void stop(const bool isAfterEOS = false)
    472         {
    473             iCurrState->stop(isAfterEOS);
    474         }
    475         virtual void seek(const uint32 aSeekPosition)
    476         {
    477             iCurrState->seek(aSeekPosition);
    478         }
    479         virtual void pause(const bool isFirstCallInPause = true)
    480         {
    481             iCurrState->pause(isFirstCallInPause);
    482         }
    483         virtual void resume()
    484         {
    485             iCurrState->resume();
    486         }
    487         virtual void bitstreamSwitch()
    488         {
    489             iCurrState->bitstreamSwitch();
    490         }
    491         void sendRequest()
    492         {
    493             iCurrState->sendRequest();
    494         }
    495         void gotoNextState()
    496         {
    497             iCurrState = getNextState();
    498             iCurrState->prepare();
    499             iCurrState->reset();
    500             iCurrState->sendRequest();
    501         }
    502 
    503 
    504         // set protocol observer for protocol user
    505         void setObserver(ProtocolObserver *aObserver)
    506         {
    507             iObserver = aObserver;
    508         }
    509 
    510         // set functions, will be delegated to ProtocolState to handle
    511         void setURI(const INetURI &aUri)
    512         {
    513             iCurrState->setURI(aUri);
    514             ProtocolState *state = NULL;
    515             while ((state = getNextState()) != iCurrState) state->setURI(aUri); // set uri for all states
    516         }
    517         void setLoggingURI(const INetURI &aUri)
    518         {
    519             iCurrState->setLoggingURI(aUri);
    520             ProtocolState *state = NULL;
    521             while ((state = getNextState()) != iCurrState) state->setLoggingURI(aUri); // set uri for all states
    522         }
    523         virtual void setConfigInfo(OsclAny* aConfigInfo)
    524         {
    525             iCurrState->setConfigInfo(aConfigInfo);
    526             ProtocolState *state = NULL;
    527             while ((state = getNextState()) != iCurrState) state->setConfigInfo(aConfigInfo); // set config info for all states
    528         }
    529 
    530         // get functions to expose the information that node needs
    531         // The header could be http header, sdp or asf header
    532         bool getHeader(Oscl_Vector<OsclRefCounterMemFrag, OsclMemAllocator> &aHeader)
    533         {
    534             return iCurrState->getHeader(aHeader);
    535         }
    536         uint32 getContentLength()
    537         {
    538             return iCurrState->getContentLength();
    539         }
    540         uint32 getDownloadSize()
    541         {
    542             return iCurrState->getDownloadSize();
    543         }
    544         uint32 getRemainingSize()
    545         {
    546             return iCurrState->getRemainingSize();
    547         }
    548         uint32 getDownloadRate()
    549         {
    550             return iCurrState->getDownloadRate();
    551         }
    552         uint32 getDownloadTimeForEstimation()
    553         {
    554             return iCurrState->getDownloadTimeForEstimation();
    555         }
    556         uint32 getResponseStatusCode()
    557         {
    558             return iCurrState->getResponseStatusCode();
    559         }
    560         bool getRedirectURI(OSCL_String &aRedirectUri)
    561         {
    562             return iCurrState->getRedirectURI(aRedirectUri);
    563         }
    564         bool getContentType(OSCL_String &aContentType)
    565         {
    566             return iCurrState->getContentType(aContentType);
    567         }
    568         bool getAuthenInfo(OSCL_String &aRealm)
    569         {
    570             return iCurrState->getAuthenInfo(aRealm);
    571         }
    572         bool isServerSupportBasicAuthentication()
    573         {
    574             return iParser->isServerSupportBasicAuthentication();
    575         }
    576         bool isServerSendAuthenticationHeader()
    577         {
    578             return iParser->isServerSendAuthenticationHeader();
    579         }
    580         void getBasicPtr(const StrPtrLen aAuthenValue, uint32 &length)
    581         {
    582             iParser->getBasicPtr(aAuthenValue, length);
    583         }
    584         void getRealmPtr(const char *&ptrRealm, uint32 &len, uint32 &length)
    585         {
    586             iParser->getRealmPtr(ptrRealm, len, length);
    587         }
    588         uint32 getCurrentPlaybackTime()
    589         {
    590             return iCurrState->getCurrentPlaybackTime();    // only used in fast track
    591         }
    592         uint32 getTimeoutInMs()
    593         {
    594             return iCurrState->getTimeoutInMs();    // only used in ms http streaming
    595         }
    596         uint32 getServerVersionNum()
    597         {
    598             return iCurrState->getServerVersionNumber();
    599         }
    600         bool isSendingNewRequest()
    601         {
    602             return iCurrState->isSendingNewRequest();
    603         }
    604         bool isCurrentStateOptional()
    605         {
    606             return iCurrState->isCurrentStateOptional();    // optional state can be by-passed regardless of any error happened
    607         }
    608         uint32 getMediaDataLength()
    609         {
    610             return iCurrState->getMediaDataLength();    // only used in Shoutcast streaming
    611         }
    612         uint32 getContenBitrate()
    613         {
    614             return iCurrState->getContenBitrate();    // only used in Shoutcast streaming
    615         }
    616 
    617         void resetTotalHttpStreamingSize()
    618         {
    619             if (iParser) iParser->resetTotalHttpStreamingSize();
    620         }
    621 
    622         virtual void reset()
    623         {
    624             if (iParser) iParser->resetForBadConnectionDetection();
    625             iCurrState->reset();
    626         }
    627 
    628         // constructor
    629         HttpBasedProtocol() : iCurrState(NULL),
    630                 iObserver(NULL),
    631                 iComposer(NULL),
    632                 iParser(NULL)
    633         {
    634             ;
    635         }
    636 
    637         virtual ~HttpBasedProtocol()
    638         {
    639             ;
    640         }
    641 
    642     protected:
    643         virtual ProtocolState* getNextState() = 0;
    644 
    645     protected:
    646         ProtocolState *iCurrState;
    647         ProtocolObserver *iObserver;
    648         HTTPComposer *iComposer;
    649         HttpParsingBasicObject *iParser; // wrap http parser to do parsing for each input media data
    650 };
    651 
    652 #endif // PVMF_PROTOCOLENGINE_H_INCLUDED
    653 
    654