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 OSCL_BYTE_ORDER_H_INCLUDED
     19 #include "oscl_byte_order.h"
     20 #endif
     21 
     22 #ifndef OSCL_SOCKET_H_INCLUDED
     23 #include "oscl_socket.h"
     24 #endif
     25 
     26 #ifndef OSCL_SOCKET_TYPES_H_INCLUDED
     27 #include "oscl_socket_types.h"
     28 #endif
     29 
     30 #ifndef OSCL_STRING_UTILS_H_INCLUDED
     31 #include "oscl_string_utils.h"
     32 #endif
     33 
     34 #ifndef OSCL_SNPRINTF_H_INCLUDED
     35 #include "oscl_snprintf.h"
     36 #endif
     37 
     38 #ifndef PVRTSP_CLIENT_ENGINE_NODE_H
     39 #include "pvrtsp_client_engine_node.h"
     40 #endif
     41 
     42 #ifndef PVRTSP_CLIENT_ENGINE_UTILS_H
     43 #include "pvrtsp_client_engine_utils.h"
     44 #endif
     45 
     46 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED
     47 #include "pvmf_simple_media_buffer.h"
     48 #endif
     49 
     50 #ifndef PVMF_BASIC_ERRORINFOMESSAGE_H_INCLUDED
     51 #include "pvmf_basic_errorinfomessage.h"
     52 #endif
     53 
     54 #ifndef PVMF_ERRORINFOMESSAGE_EXTENSION_H_INCLUDED
     55 #include "pvmf_errorinfomessage_extension.h"
     56 #endif
     57 
     58 #ifndef PVMF_SM_NODE_EVENTS_H_INCLUDED
     59 #include "pvmf_sm_node_events.h"
     60 #endif
     61 
     62 #ifndef PVMF_MEDIA_MSG_HEADER_H_INCLUDED
     63 #include "pvmf_media_msg_header.h"
     64 #endif
     65 
     66 #ifndef PVMF_SM_TUNABLES_H_INCLUDED
     67 #include "pvmf_sm_tunables.h"
     68 #endif
     69 
     70 #ifndef BASE64_CODEC_H_INCLUDED
     71 #include "base64_codec.h"
     72 #endif
     73 
     74 #ifndef PV_STRING_URI_H_INCLUDE
     75 #include "pv_string_uri.h"
     76 #endif
     77 
     78 #ifndef PVRTSP_ENGINE_NODE_EXTENSION_INTERFACE_IMPL_H_INCLUDED
     79 #include "pvrtspenginenodeextensioninterface_impl.h"
     80 #endif
     81 
     82 /*
     83 #ifndef PV_PLAYER_SDKINFO_H_INCLUDED    //\engines\player\src\pv_player_sdkinfo.h
     84 #include "pv_player_sdkinfo.h"
     85 #endif
     86 */
     87 ////////////////////////////////////////////////////////////////////////////////
     88 
     89 const int PVRTSPEngineNode::REQ_SEND_SOCKET_ID = 1;
     90 const int PVRTSPEngineNode::REQ_RECV_SOCKET_ID = 2;
     91 
     92 
     93 OSCL_EXPORT_REF PVRTSPEngineNode::PVRTSPEngineNode(int32 aPriority) :
     94         OsclTimerObject(aPriority, "PVRTSPEngineNode"),
     95         iState(PVRTSP_ENGINE_NODE_STATE_IDLE),
     96         iCurrentCmdId(0),
     97         iSockServ(NULL),
     98         iSocketCleanupState(ESocketCleanup_Idle),
     99         iRTSPParser(NULL),
    100         iRTSPParserState(RTSPParser::WAITING_FOR_DATA),
    101         iOutgoingSeq(0),
    102         bNoRecvPending(false),
    103         bNoSendPending(false),
    104         iTheBusyPort(NULL),
    105         iLogger(NULL),
    106         iExtensionRefCount(0),
    107         iNumRedirectTrials(PVRTSPENGINENODE_DEFAULT_NUMBER_OF_REDIRECT_TRIALS),
    108         iNumHostCallback(0),
    109         iNumConnectCallback(0),
    110         iNumSendCallback(0),
    111         iNumRecvCallback(0),
    112         BASE_REQUEST_ID(0),
    113         REQ_TIMER_WATCHDOG_ID(0),
    114         REQ_TIMER_KEEPALIVE_ID(0),
    115         REQ_DNS_LOOKUP_ID(0),
    116         DEFAULT_RTSP_PORT(554),
    117         DEFAULT_HTTP_PORT(80),
    118         TIMEOUT_CONNECT_AND_DNS_LOOKUP(30000),
    119         TIMEOUT_SEND(3000),
    120         TIMEOUT_RECV(-1),
    121         TIMEOUT_SHUTDOWN(30000),
    122         TIMEOUT_WATCHDOG(20),
    123         TIMEOUT_WATCHDOG_TEARDOWN(2),
    124         TIMEOUT_KEEPALIVE(PVRTSPENGINENODE_DEFAULT_KEEP_ALIVE_INTERVAL),
    125         RECOMMENDED_RTP_BLOCK_SIZE(1400),
    126         setupTrackIndex(0),
    127         bRepositioning(false),// \todo reset the reqplayrange to invalid after get the PLAY resp
    128         iSrvResponse(NULL),
    129         bSrvRespPending(false),
    130         iWatchdogTimer(NULL),
    131         iCurrentErrorCode(PVMFRTSPClientEngineNodeErrorEventStart),
    132         iEventUUID(PVMFRTSPClientEngineNodeEventTypeUUID),
    133         bKeepAliveInPlay(false),
    134         iKeepAliveMethod(METHOD_OPTIONS),
    135         bAddXStrHeader(false),
    136         iErrorRecoveryAttempt(0),
    137         iGetPostCorrelationObject(NULL),
    138         ibIsRealRDT(false),
    139         ipRealChallengeGen(NULL),
    140         ipRdtParser(NULL),
    141         ipFragGroupAllocator(NULL),
    142         ipFragGroupMemPool(NULL),
    143         ibBlockedOnFragGroups(false),
    144         iExtensionInterface(NULL)
    145 {
    146     int32 err;
    147     OSCL_TRY(err,
    148              //Create the input command queue.  Use a reserve to avoid lots of
    149              //dynamic memory allocation.
    150              iPendingCmdQueue.Construct(PVMF_RTSP_ENGINE_NODE_COMMAND_ID_START, PVMF_RTSP_ENGINE_NODE_COMMAND_VECTOR_RESERVE);
    151 
    152              //Create the "current command" queue.  It will only contain one
    153              //command at a time, so use a reserve of 1.
    154              iRunningCmdQueue.Construct(0, 1);
    155 
    156              //Create the port vector.
    157              iPortVector.Construct(PVMF_RTSP_NODE_PORT_VECTOR_RESERVE);
    158              iPortActivityQueue.reserve(PVMF_RTSP_ENGINE_NODE_COMMAND_VECTOR_RESERVE);
    159 
    160              //Set the node capability data.
    161              //This node can support one duplex port.
    162              iCapability.iCanSupportMultipleInputPorts = false;
    163              iCapability.iCanSupportMultipleOutputPorts = false;
    164              iCapability.iHasMaxNumberOfPorts = true;
    165              iCapability.iMaxNumberOfPorts = 1;
    166 
    167              iEntityMemFrag.len = 0;
    168              iEntityMemFrag.ptr = NULL;
    169 
    170              iRTSPEngTmpBuf.len = 0;
    171              iRTSPEngTmpBuf.ptr = OSCL_MALLOC(RTSP_MAX_FULL_REQUEST_SIZE);
    172              OsclError::LeaveIfNull(iRTSPEngTmpBuf.ptr);
    173              iRTSPEngTmpBuf.len = RTSP_MAX_FULL_REQUEST_SIZE;
    174 
    175              iWatchdogTimer = OSCL_NEW(OsclTimer<PVRTSPEngineNodeAllocator>, ("PVRTSPEngineNodeWatchDog"));
    176              OsclError::LeaveIfNull(iWatchdogTimer);
    177 
    178              //TBD
    179              //iMediaDataResizableAlloc =OSCL_NEW(OsclMemPoolResizableAllocator, (RECOMMENDED_RTP_BLOCK_SIZE, 0, 0, &iAlloc));;
    180              iMediaDataResizableAlloc = OSCL_NEW(OsclMemPoolResizableAllocator, (RECOMMENDED_RTP_BLOCK_SIZE));
    181              OsclError::LeaveIfNull(iMediaDataResizableAlloc);
    182 
    183 
    184              iMediaDataImplAlloc = OSCL_NEW(PVMFSimpleMediaBufferCombinedAlloc, (iMediaDataResizableAlloc));;
    185              OsclError::LeaveIfNull(iMediaDataImplAlloc);
    186 
    187             );
    188 
    189     if (err != OsclErrNone)
    190     {
    191         //if a leave happened, cleanup and re-throw the error
    192         iPendingCmdQueue.clear();
    193         iRunningCmdQueue.clear();
    194         iPortVector.clear();
    195         iCapability.iInputFormatCapability.clear();
    196         iCapability.iOutputFormatCapability.clear();
    197         OSCL_CLEANUP_BASE_CLASS(PVMFNodeInterface);
    198         OSCL_CLEANUP_BASE_CLASS(OsclTimerObject);
    199         OSCL_LEAVE(err);
    200     }
    201     iWatchdogTimer->SetObserver(this);
    202     iWatchdogTimer->SetFrequency(1);
    203     iInterfaceState = EPVMFNodeCreated;
    204 }
    205 
    206 OSCL_EXPORT_REF PVRTSPEngineNode::~PVRTSPEngineNode()
    207 {
    208     Cancel();
    209 
    210     if (iExtensionInterface)
    211     {
    212         iExtensionInterface->removeRef();
    213     }
    214 
    215     if (iWatchdogTimer)
    216     {
    217         OSCL_DELETE(iWatchdogTimer);
    218         iWatchdogTimer = NULL;
    219     }
    220 
    221     if (iRTSPEngTmpBuf.len > 0)
    222     {
    223         OSCL_FREE(iRTSPEngTmpBuf.ptr);
    224         iRTSPEngTmpBuf.len = 0;
    225         iRTSPEngTmpBuf.ptr = NULL;
    226     }
    227 
    228     if (iEntityMemFrag.len > 0)
    229     {
    230         OSCL_FREE(iEntityMemFrag.ptr);
    231         iEntityMemFrag.len = 0;
    232         iEntityMemFrag.ptr = NULL;
    233     }
    234 
    235     if (iSrvResponse)
    236     {
    237         OSCL_DELETE(iSrvResponse);
    238         iSrvResponse = NULL;
    239     }
    240 
    241     if (iRTSPParser)
    242     {
    243         OSCL_DELETE(iRTSPParser);
    244         iRTSPParser = NULL;
    245     }
    246 
    247     if (iMediaDataImplAlloc != NULL)
    248     {
    249         OSCL_DELETE(iMediaDataImplAlloc);
    250     }
    251 
    252     if (iMediaDataResizableAlloc != NULL)
    253     {
    254         iMediaDataResizableAlloc->removeRef();
    255     }
    256 
    257     clearOutgoingMsgQueue();
    258 
    259     resetSocket(true);
    260 
    261     if (iDNS.iDns)
    262     {
    263         iDNS.iDns->~OsclDNS();
    264         iAlloc.deallocate(iDNS.iDns);
    265         iDNS.iDns = NULL;
    266     }
    267 
    268     if (iSockServ)
    269     {
    270         iSockServ->Close();
    271         iSockServ->~OsclSocketServ();
    272         iAlloc.deallocate(iSockServ);
    273         iSockServ = NULL;
    274     }
    275 
    276     if (ipFragGroupAllocator != NULL)
    277         OSCL_DELETE(ipFragGroupAllocator);
    278     if (ipFragGroupMemPool != NULL)
    279         OSCL_DELETE(ipFragGroupMemPool);
    280 
    281     if (iGetPostCorrelationObject != NULL)
    282     {
    283         OSCL_DELETE(iGetPostCorrelationObject);
    284         iGetPostCorrelationObject = NULL;
    285     }
    286 
    287 }
    288 
    289 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::ThreadLogon()
    290 {
    291     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::ThreadLogon() called"));
    292     switch (iInterfaceState)
    293     {
    294         case EPVMFNodeCreated:
    295             if (!IsAdded())
    296                 AddToScheduler();
    297             iLogger = PVLogger::GetLoggerObject("PVRTSPEngineNode");
    298             SetState(EPVMFNodeIdle);
    299             return PVMFSuccess;
    300             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    301         default:
    302             return PVMFErrInvalidState;
    303             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    304     }
    305 }
    306 
    307 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::ThreadLogoff()
    308 {
    309     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::ThreadLogoff() called"));
    310     switch (iInterfaceState)
    311     {
    312         case EPVMFNodeIdle:
    313             if (IsAdded())
    314                 RemoveFromScheduler();
    315             iLogger = NULL;
    316             SetState(EPVMFNodeCreated);
    317             return PVMFSuccess;
    318             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    319 
    320         default:
    321             return PVMFErrInvalidState;
    322             // break;   This break statement was removed to avoid compiler warning for Unreachable Code
    323     }
    324 }
    325 
    326 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetCapability(PVMFNodeCapability& aNodeCapability)
    327 {
    328     OSCL_UNUSED_ARG(aNodeCapability);
    329     return PVMFFailure;
    330 }
    331 
    332 OSCL_EXPORT_REF PVMFPortIter* PVRTSPEngineNode::GetPorts(const PVMFPortFilter* aFilter)
    333 {
    334     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::GetPorts() called"));
    335 
    336     OSCL_UNUSED_ARG(aFilter);
    337     // TODO: Return the currently available ports
    338     return NULL;
    339 }
    340 
    341 OSCL_EXPORT_REF PVMFCommandId PVRTSPEngineNode::QueryUUID(PVMFSessionId aSession
    342         , const PvmfMimeString& aMimeType
    343         , Oscl_Vector<PVUuid, PVRTSPEngineNodeAllocator>& aUuids
    344         , bool aExactUuidsOnly
    345         , const OsclAny* aContext)
    346 {
    347     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::QueryUUID() called"));
    348 
    349     PVRTSPEngineCommand cmd;
    350     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_QUERYUUID, aMimeType, \
    351                                            aUuids, aExactUuidsOnly, aContext);
    352 
    353     return AddCmdToQueue(cmd);
    354 }
    355 
    356 OSCL_EXPORT_REF void PVRTSPEngineNode::addRef()
    357 {
    358 
    359 }
    360 
    361 OSCL_EXPORT_REF void PVRTSPEngineNode::removeRef()
    362 {
    363 
    364 }
    365 
    366 OSCL_EXPORT_REF bool PVRTSPEngineNode::queryInterface(const PVUuid& uuid, PVInterface*& iface)
    367 {
    368     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::QueryInterface() In iExtensionInterface %x", iExtensionInterface));
    369     iface = NULL;
    370     if (uuid == KPVRTSPEngineNodeExtensionUuid)
    371     {
    372         if (!iExtensionInterface)
    373         {
    374             iExtensionInterface = OSCL_NEW(PVRTSPEngineNodeExtensionInterfaceImpl, (this));
    375             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::QueryInterface() iExtensionInterface %x", iExtensionInterface));
    376         }
    377         if (iExtensionInterface)
    378         {
    379             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::QueryInterface() Interface existing iExtensionInterface %x", iExtensionInterface));
    380             return (iExtensionInterface->queryInterface(uuid, iface));
    381         }
    382         else
    383         {
    384             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::queryInterface()- ERROR No memory"));
    385             OSCL_LEAVE(OsclErrNoMemory);
    386             return false;
    387         }
    388     }
    389     else
    390     {
    391         return false;
    392     }
    393 }
    394 
    395 OSCL_EXPORT_REF PVMFCommandId PVRTSPEngineNode::QueryInterface(PVMFSessionId aSession
    396         , const PVUuid& aUuid
    397         , PVInterface*& aInterfacePtr
    398         , const OsclAny* aContext)
    399 {
    400     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::QueryInterface() called"));
    401 
    402     PVRTSPEngineCommand cmd;
    403     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_QUERYINTERFACE, aUuid, aInterfacePtr, aContext);
    404     return AddCmdToQueue(cmd);
    405 }
    406 
    407 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::RequestPort(PVMFSessionId aSession
    408         , int32 aPortTag
    409         , const PvmfMimeString* aPortConfig
    410         , const OsclAny* aContext)
    411 {
    412     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::RequestPort() called"));
    413 
    414     PVRTSPEngineCommand cmd;
    415     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_REQUESTPORT, aPortTag, aPortConfig, aContext);
    416     return AddCmdToQueue(cmd);
    417 }
    418 
    419 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::ReleasePort(PVMFSessionId aSession
    420         , PVMFPortInterface& aPort
    421         , const OsclAny* aContext)
    422 {
    423     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::ReleasePort() called"));
    424 
    425     PVRTSPEngineCommand cmd;
    426     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_RELEASEPORT, aPort, aContext);
    427     return AddCmdToQueue(cmd);
    428 }
    429 
    430 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::Init(PVMFSessionId aSession
    431         , const OsclAny* aContext)
    432 {
    433     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Init() called"));
    434 
    435     PVRTSPEngineCommand cmd;
    436     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_INIT, aContext);
    437     return AddCmdToQueue(cmd);
    438 }
    439 
    440 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::Prepare(PVMFSessionId aSession
    441         , const OsclAny* aContext)
    442 {
    443     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Init() called"));
    444 
    445     PVRTSPEngineCommand cmd;
    446     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_PREPARE, aContext);
    447     return AddCmdToQueue(cmd);
    448 }
    449 
    450 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::Start(PVMFSessionId aSession
    451         , const OsclAny* aContext)
    452 {
    453     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Start() called"));
    454 
    455     PVRTSPEngineCommand cmd;
    456     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_START, aContext);
    457     return AddCmdToQueue(cmd);
    458 }
    459 
    460 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::Pause(PVMFSessionId aSession
    461         , const OsclAny* aContext)
    462 {
    463     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Pause() called"));
    464 
    465     PVRTSPEngineCommand cmd;
    466     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_PAUSE, aContext);
    467     return AddCmdToQueue(cmd);
    468 }
    469 
    470 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::Stop(PVMFSessionId aSession
    471         , const OsclAny* aContext)
    472 {
    473     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Stop() called"));
    474 
    475     PVRTSPEngineCommand cmd;
    476     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_STOP, aContext);
    477     return AddCmdToQueue(cmd);
    478 }
    479 
    480 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::Reset(PVMFSessionId aSession
    481         , const OsclAny* aContext)
    482 {
    483     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Reset() called"));
    484 
    485     PVRTSPEngineCommand cmd;
    486     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_RESET, aContext);
    487     return AddCmdToQueue(cmd);
    488 }
    489 
    490 OSCL_EXPORT_REF PVMFCommandId PVRTSPEngineNode::Flush(PVMFSessionId aSession, const OsclAny* aContext)
    491 {
    492     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Flush() called"));
    493 
    494     PVRTSPEngineCommand cmd;
    495     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_FLUSH, aContext);
    496     return AddCmdToQueue(cmd);
    497 }
    498 
    499 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::CancelCommand(PVMFSessionId aSession
    500         , PVMFCommandId aCmdId
    501         , const OsclAny* aContextData)
    502 {
    503     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::CancelCommand() called"));
    504     //OSCL_LEAVE(OsclErrNotSupported);
    505     PVRTSPEngineCommand cmd;
    506     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_CANCELCOMMAND, aCmdId, aContextData);
    507     return AddCmdToQueue(cmd);
    508 }
    509 
    510 OSCL_EXPORT_REF   PVMFCommandId PVRTSPEngineNode::CancelAllCommands(PVMFSessionId aSession
    511         , const OsclAny* aContextData)
    512 {
    513     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::CancelAllCommands() called"));
    514 
    515     //OSCL_LEAVE(OsclErrNotSupported);
    516     PVRTSPEngineCommand cmd;
    517     cmd.PVRTSPEngineCommandBase::Construct(aSession, PVMF_GENERIC_NODE_CANCELALLCOMMANDS, aContextData);
    518     return AddCmdToQueue(cmd);
    519 }
    520 //************ end PVMFNodeInterface
    521 
    522 //************ begin PVRTSPEngineNodeExtensionInterface
    523 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetStreamingType(PVRTSPStreamingType aType)
    524 {
    525     iSessionInfo.iStreamingType = aType;
    526     return PVMFSuccess;
    527 }
    528 
    529 OSCL_EXPORT_REF  PVMFStatus PVRTSPEngineNode::SetSessionURL(OSCL_wString& aURL)
    530 {
    531     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetSessionURL() called"));
    532     if (iInterfaceState == EPVMFNodeIdle)
    533     {
    534         if (parseURL(aURL))
    535         {
    536             iSessionInfo.bExternalSDP = false;
    537             return PVMFSuccess;
    538         }
    539     }
    540     iSessionInfo.iSessionURL = "";
    541     return PVMFFailure;
    542 }
    543 
    544 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetRtspProxy(OSCL_String& aRtspProxyName, uint32 aRtspProxyPort)
    545 {
    546     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetRtspProxy() aRtspProxy %s %d", aRtspProxyName.get_cstr(), aRtspProxyPort));
    547 
    548     //If proxy is in use, both the name and the port have to be set.
    549     if ((0 == aRtspProxyName.get_size())
    550             || (0 == aRtspProxyPort)
    551             || (iInterfaceState != EPVMFNodeIdle))
    552     {
    553         return PVMFFailure;
    554     }
    555 
    556     {
    557         iSessionInfo.iProxyName = aRtspProxyName;
    558         iSessionInfo.iProxyPort = aRtspProxyPort;
    559 
    560         return PVMFSuccess;
    561     }
    562 }
    563 OSCL_EXPORT_REF  PVMFStatus PVRTSPEngineNode::GetRtspProxy(OSCL_String& aRtspProxyName, uint32& aRtspProxyPort)
    564 {
    565     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::GetRtspProxy() RtspProxy %s %d", iSessionInfo.iProxyName.get_cstr(), iSessionInfo.iProxyPort));
    566     aRtspProxyName = iSessionInfo.iProxyName;
    567     aRtspProxyPort = iSessionInfo.iProxyPort;
    568     return PVMFSuccess;
    569 }
    570 
    571 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetSDPInfo(OsclSharedPtr<SDPInfo>& aSDPinfo, Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> &aSelectedStream)
    572 {
    573     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetSDPInfo() called"));
    574 
    575     if ((iInterfaceState == EPVMFNodePrepared) ||
    576             (iInterfaceState == EPVMFNodeInitialized) ||
    577             (iInterfaceState == EPVMFNodeIdle))
    578     {
    579         if (iState == PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE)
    580         {
    581             iSessionInfo.bExternalSDP = false;
    582         }
    583         else if (iState == PVRTSP_ENGINE_NODE_STATE_IDLE)
    584         {
    585             iSessionInfo.bExternalSDP = true;
    586         }
    587         else
    588         {
    589             return PVMFErrInvalidState;
    590         }
    591 
    592         iSessionInfo.iSDPinfo = aSDPinfo;
    593         iSessionInfo.iSelectedStream = aSelectedStream;
    594 
    595         if (iSessionInfo.bExternalSDP)
    596         {
    597             //set the server address
    598             const char *servURL = (aSDPinfo->getSessionInfo())->getControlURL();
    599             uint32 servURLLen = oscl_strlen(servURL);
    600             if (servURLLen >= iRTSPEngTmpBuf.len)
    601             {
    602                 //we do not support URLs larger than RTSP_MAX_FULL_REQUEST_SIZE
    603                 //iRTSPEngTmpBuf.len is initialized to RTSP_MAX_FULL_REQUEST_SIZE
    604                 return PVMFFailure;
    605             }
    606             oscl_memset(iRTSPEngTmpBuf.ptr, 0, iRTSPEngTmpBuf.len);
    607             oscl_strncpy((mbchar*)iRTSPEngTmpBuf.ptr, servURL, servURLLen);
    608             if (!parseURL((mbchar*)iRTSPEngTmpBuf.ptr))
    609             {
    610                 return PVMFFailure;
    611             }
    612         }
    613         return PVMFSuccess;
    614     }
    615     return PVMFErrInvalidState;
    616 }
    617 
    618 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetSDP(OsclRefCounterMemFrag& aSDPMemFrag)
    619 {
    620     aSDPMemFrag = iSessionInfo.pSDPBuf;
    621     return PVMFSuccess;
    622 }
    623 
    624 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetServerInfo(PVRTSPEngineNodeServerInfo& aServerInfo)
    625 {
    626     aServerInfo.iServerName = iSessionInfo.iServerName;
    627     aServerInfo.iIsPVServer = iSessionInfo.pvServerIsSetFlag;
    628     aServerInfo.iRoundTripDelayInMS = iSessionInfo.roundTripDelay;
    629     aServerInfo.iServerVersionNumber = iSessionInfo.iServerVersionNumber;
    630     return PVMFSuccess;
    631 }
    632 
    633 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetStreamInfo(Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> &aSelectedStream)
    634 {
    635     aSelectedStream = iSessionInfo.iSelectedStream;
    636     return PVMFSuccess;
    637 }
    638 
    639 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetUserAgent(OSCL_wString& aUserAgent)
    640 {
    641     uint32 tmpSize = iSessionInfo.iUserAgent.get_size();
    642     tmpSize += 8;
    643     int32 err;
    644     oscl_wchar *tmpBuf = NULL;
    645     OSCL_TRY(err, tmpBuf = OSCL_ARRAY_NEW(oscl_wchar, (tmpSize)););
    646     if ((err != OsclErrNone) || (tmpBuf == NULL))
    647     {
    648         return PVMFFailure;
    649     }
    650 
    651     if (0 == oscl_UTF8ToUnicode(iSessionInfo.iUserAgent.get_cstr(), iSessionInfo.iUserAgent.get_size(), (oscl_wchar*)tmpBuf, (tmpSize*sizeof(oscl_wchar))))
    652     {
    653         OSCL_ARRAY_DELETE(tmpBuf);
    654         return PVMFFailure;
    655     }
    656 
    657     aUserAgent = tmpBuf;
    658 
    659     OSCL_ARRAY_DELETE(tmpBuf);
    660     return PVMFSuccess;
    661 }
    662 
    663 OSCL_EXPORT_REF  PVMFStatus PVRTSPEngineNode::SetClientParameters(OSCL_wString& aUserAgent,
    664         OSCL_wString&  aUserNetwork,
    665         OSCL_wString&  aDeviceInfo)
    666 {
    667     uint32 tmpSize = aUserAgent.get_size();
    668     if (tmpSize < aUserNetwork.get_size())
    669     {
    670         tmpSize = aUserNetwork.get_size();
    671     }
    672     if (tmpSize < aDeviceInfo.get_size())
    673     {
    674         tmpSize = aDeviceInfo.get_size();
    675     }
    676     tmpSize += 8;
    677 
    678     int32 err;
    679     uint8 *tmpBuf = NULL;
    680     OSCL_TRY(err, tmpBuf = OSCL_ARRAY_NEW(uint8, (tmpSize)););
    681     if ((err != OsclErrNone) || (tmpBuf == NULL))
    682     {
    683         return PVMFFailure;
    684     }
    685 
    686     if (aUserAgent.get_size() > 0)
    687     {
    688         if (0 == oscl_UnicodeToUTF8(aUserAgent.get_cstr(), aUserAgent.get_size(), (char*)tmpBuf, tmpSize))
    689         {
    690             OSCL_ARRAY_DELETE(tmpBuf);
    691             return PVMFFailure;
    692         }
    693         //\engines\player\src\pv_player_sdkinfo.h
    694         //#define PVPLAYER_ENGINE_SDKINFO_LABEL "PVPLAYER 04.07.00.01"
    695         //iSessionInfo.iUserAgent = PVPLAYER_ENGINE_SDKINFO_LABEL;
    696         iSessionInfo.iUserAgent += (char*)tmpBuf;
    697         //iSessionInfo.iUserAgent = (char*)tmpBuf;
    698     }
    699 
    700     if (aUserNetwork.get_size() > 0)
    701     {
    702         if (0 == oscl_UnicodeToUTF8(aUserNetwork.get_cstr(), aUserNetwork.get_size(), (char*)tmpBuf, tmpSize))
    703         {
    704             OSCL_ARRAY_DELETE(tmpBuf);
    705             return PVMFFailure;
    706         }
    707         iSessionInfo.iUserNetwork = (char*)tmpBuf;
    708     }
    709 
    710     if (aDeviceInfo.get_size() > 0)
    711     {
    712         if (0 == oscl_UnicodeToUTF8(aDeviceInfo.get_cstr(), aDeviceInfo.get_size(), (char*)tmpBuf, tmpSize))
    713         {
    714             OSCL_ARRAY_DELETE(tmpBuf);
    715             return PVMFFailure;
    716         }
    717         iSessionInfo.iDeviceInfo = (char*)tmpBuf;
    718     }
    719 
    720     OSCL_ARRAY_DELETE(tmpBuf);
    721     return PVMFSuccess;
    722 }
    723 
    724 OSCL_EXPORT_REF bool PVRTSPEngineNode::IsRdtTransport()
    725 {
    726     return ibIsRealRDT;
    727 }
    728 
    729 
    730 OSCL_EXPORT_REF void PVRTSPEngineNode::SetPortRdtStreamId(PVMFPortInterface* pPort,
    731         int iRdtStreamId)
    732 {
    733     ((PVMFRTSPPort*)pPort)->iRdtStreamId = iRdtStreamId;
    734 }
    735 
    736 OSCL_EXPORT_REF void PVRTSPEngineNode::SetRealChallengeCalculator(IRealChallengeGen* pChallengeCalc)
    737 {
    738     ipRealChallengeGen = pChallengeCalc;
    739 }
    740 
    741 OSCL_EXPORT_REF void PVRTSPEngineNode::SetRdtParser(IPayloadParser* pRdtParser)
    742 {
    743     ipRdtParser = pRdtParser;
    744 }
    745 
    746 OSCL_EXPORT_REF  PVMFStatus PVRTSPEngineNode::SetAuthenticationParameters(OSCL_wString& aUserID,
    747         OSCL_wString& aAuthentication,
    748         OSCL_wString& aExpiration,
    749         OSCL_wString& aApplicationSpecificString,
    750         OSCL_wString& aVerification,
    751         OSCL_wString& aSignature)
    752 {
    753     uint32 tmpSize = aUserID.get_size();
    754     if (tmpSize < aAuthentication.get_size())
    755     {
    756         tmpSize = aAuthentication.get_size();
    757     }
    758     if (tmpSize < aExpiration.get_size())
    759     {
    760         tmpSize = aExpiration.get_size();
    761     }
    762     if (tmpSize < aApplicationSpecificString.get_size())
    763     {
    764         tmpSize = aApplicationSpecificString.get_size();
    765     }
    766     if (tmpSize < aVerification.get_size())
    767     {
    768         tmpSize = aVerification.get_size();
    769     }
    770     if (tmpSize < aSignature.get_size())
    771     {
    772         tmpSize = aSignature.get_size();
    773     }
    774     tmpSize += 8;
    775 
    776     int32 err;
    777     uint8 *tmpBuf = NULL;
    778     OSCL_TRY(err, tmpBuf = OSCL_ARRAY_NEW(uint8, (tmpSize)););
    779     if ((err != OsclErrNone) || (tmpBuf == NULL))
    780     {
    781         return PVMFFailure;
    782     }
    783 
    784     if (0 == oscl_UnicodeToUTF8(aUserID.get_cstr(), aUserID.get_size(), (char*)tmpBuf, tmpSize))
    785     {
    786         OSCL_ARRAY_DELETE(tmpBuf);
    787         return PVMFFailure;
    788     }
    789     iSessionInfo.iUserID = (char*)tmpBuf;
    790 
    791     if (0 == oscl_UnicodeToUTF8(aAuthentication.get_cstr(), aAuthentication.get_size(), (char*)tmpBuf, tmpSize))
    792     {
    793         OSCL_ARRAY_DELETE(tmpBuf);
    794         return PVMFFailure;
    795     }
    796     iSessionInfo.iAuthentication = (char*)tmpBuf;
    797 
    798     if (0 == oscl_UnicodeToUTF8(aExpiration.get_cstr(), aExpiration.get_size(), (char*)tmpBuf, tmpSize))
    799     {
    800         OSCL_ARRAY_DELETE(tmpBuf);
    801         return PVMFFailure;
    802     }
    803     iSessionInfo.iExpiration = (char*)tmpBuf;
    804 
    805     if (0 == oscl_UnicodeToUTF8(aApplicationSpecificString.get_cstr(), aApplicationSpecificString.get_size(), (char*)tmpBuf, tmpSize))
    806     {
    807         OSCL_ARRAY_DELETE(tmpBuf);
    808         return PVMFFailure;
    809     }
    810     iSessionInfo.iApplicationSpecificString = (char*)tmpBuf;
    811 
    812     if (0 == oscl_UnicodeToUTF8(aVerification.get_cstr(), aVerification.get_size(), (char*)tmpBuf, tmpSize))
    813     {
    814         OSCL_ARRAY_DELETE(tmpBuf);
    815         return PVMFFailure;
    816     }
    817     iSessionInfo.iVerification = (char*)tmpBuf;
    818 
    819     if (0 == oscl_UnicodeToUTF8(aSignature.get_cstr(), aSignature.get_size(), (char*)tmpBuf, tmpSize))
    820     {
    821         OSCL_ARRAY_DELETE(tmpBuf);
    822         return PVMFFailure;
    823     }
    824     iSessionInfo.iSignature = (char*)tmpBuf;
    825 
    826     OSCL_ARRAY_DELETE(tmpBuf);
    827 
    828     return PVMFSuccess;
    829 }
    830 
    831 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetRequestPlayRange(const RtspRangeType& aRange)
    832 {
    833     if (aRange.format == RtspRangeType::NPT_RANGE)
    834     {//only accept npt for now.
    835         iSessionInfo.iReqPlayRange = aRange;
    836         iSessionInfo.iActPlayRange.format = RtspRangeType::INVALID_RANGE;
    837         if (PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE == iState)
    838         {
    839             bRepositioning =  true;
    840         }
    841         return PVMFSuccess;
    842     }
    843     return PVMFFailure;
    844 }
    845 
    846 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetActualPlayRange(RtspRangeType& aRange)
    847 {
    848     aRange = iSessionInfo.iActPlayRange;
    849     if (iSessionInfo.iActPlayRange.format == RtspRangeType::INVALID_RANGE)
    850     {
    851         return PVMFFailure;
    852     }
    853     return PVMFSuccess;
    854 }
    855 
    856 //************ end PVRTSPEngineNodeExtensionInterface
    857 
    858 //************ begin OsclSocketObserver
    859 OSCL_EXPORT_REF  void PVRTSPEngineNode::HandleSocketEvent(int32 aId, TPVSocketFxn aFxn, TPVSocketEvent aEvent, int32 aError)
    860 {
    861     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::HandleSocketEvent() In aId=%d, aFxn=%d, aEvent=%d, aError=%d", aId, aFxn, aEvent, aError));
    862 
    863     //update socket container state.
    864     //note we only update iRecvSocket container when it's a unique socket.
    865     SocketContainer* container;
    866     switch (aId)
    867     {
    868         case REQ_RECV_SOCKET_ID:
    869             container = &iRecvSocket;
    870             break;
    871         case REQ_SEND_SOCKET_ID:
    872             container = &iSendSocket;
    873             break;
    874         default:
    875             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::HandleSocketEvent() ERROR invalid aId=%d", aId));
    876             return;
    877     }
    878     //clear the appropriate cmd pending & canceled flags.
    879     switch (aFxn)
    880     {
    881         case EPVSocketConnect:
    882             container->iConnectState.Reset();
    883             OSCL_ASSERT(iNumConnectCallback > 0);
    884             iNumConnectCallback--;
    885             break;
    886         case EPVSocketRecv:
    887             container->iRecvState.Reset();
    888             OSCL_ASSERT(iNumRecvCallback > 0);
    889             iNumRecvCallback--;
    890             break;
    891         case EPVSocketSend:
    892             container->iSendState.Reset();
    893             OSCL_ASSERT(iNumSendCallback > 0);
    894             iNumSendCallback--;
    895             break;
    896         case EPVSocketShutdown:
    897             container->iShutdownState.Reset();
    898             break;
    899         default:
    900             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::HandleSocketEvent() ERROR invalid aFxn=%d", aFxn));
    901             return;
    902     }
    903 
    904     if (!IsAdded())
    905     {//prevent the leave 49. should never get here
    906         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::HandleSocketEvent() ERROR line %d", __LINE__));
    907         return;
    908     }
    909 
    910     //For socket cleanup sequence including Stop & Reset command
    911     if (iSocketCleanupState != ESocketCleanup_Idle)
    912     {
    913         RunIfNotReady();
    914         return;
    915     }
    916 
    917     //save info
    918     SocketEvent tmpSockEvent;
    919     tmpSockEvent.iSockId    = aId;
    920     tmpSockEvent.iSockFxn = aFxn;
    921     tmpSockEvent.iSockEvent = aEvent;
    922     tmpSockEvent.iSockError = aError;
    923 
    924     if (aFxn == EPVSocketRecv)
    925     {
    926         bNoRecvPending = true;
    927         if (EPVSocketSuccess == aEvent)
    928         {
    929             int32 incomingMessageLen;
    930             uint8* recvData = iRecvSocket.iSocket->GetRecvData(&incomingMessageLen);
    931             OSCL_UNUSED_ARG(recvData);
    932 
    933 #ifdef MY_RTSP_DEBUG
    934             {
    935                 const uint32 dbgBufSize = 256;
    936                 uint8* dbgBuf = OSCL_ARRAY_NEW(uint8, dbgBufSize);
    937                 if (dbgBuf) oscl_memcpy(dbgBuf, recvData, dbgBufSize - 1);
    938                 dbgBuf[dbgBufSize-1] = '\0';
    939                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "C <--- S\n%s", dbgBuf));
    940                 OSCL_ARRAY_DELETE(dbgBuf);
    941             }
    942 #endif
    943 
    944             if (incomingMessageLen > 0)
    945             {
    946                 if (!iRTSPParser->registerDataBufferWritten(incomingMessageLen))
    947                 {//parser some kind of error on Engine's part, or Parser's internal inconsistency
    948                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::HandleSocketEvent() registerDataBufferWritten() error"));
    949                     iRTSPParser->flush();
    950                 }
    951                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::HandleSocketEvent() In incomingMessageLen=%d", incomingMessageLen));
    952             }
    953             RunIfNotReady();
    954             return; // for recv success, process is done
    955         }
    956     }
    957     else if (aFxn == EPVSocketSend)
    958     {
    959         if (aId == REQ_RECV_SOCKET_ID)
    960         {//clear POST msg
    961             iRecvChannelMsg = "";
    962         }
    963 
    964         //TBD using send Q
    965         if ((bSrvRespPending) && (EPVSocketSuccess == aEvent))
    966         {//there is one resp waiting on queue because there was a send() pending
    967             bSrvRespPending = false;
    968 
    969             if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *iSrvResponse))
    970             {
    971                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::HandleSocketEvent() sendSocketOutgoingMsg() error"));
    972             }
    973         }
    974         else
    975         {
    976             bNoSendPending = true;
    977             if (iSrvResponse)
    978             {
    979                 OSCL_DELETE(iSrvResponse);
    980                 iSrvResponse = NULL;
    981             }
    982             if (iState == PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE)
    983             {//wait first SETUP response before sending the remaining SETUPs
    984                 bNoSendPending = false;
    985                 return;//handling of this socketevent is done.
    986             }
    987         }
    988     }
    989 
    990     iSocketEventQueue.push_back(tmpSockEvent);
    991     RunIfNotReady();
    992 }
    993 //************ end OsclSocketObserver
    994 
    995 //************ begin OsclDNSObserver
    996 OSCL_EXPORT_REF void PVRTSPEngineNode::HandleDNSEvent(int32 aId, TPVDNSFxn aFxn, TPVDNSEvent aEvent, int32 aError)
    997 {
    998     OSCL_UNUSED_ARG(aEvent);
    999 
   1000     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::HandleDNSEvent() In aId=%d, aFxn=%d, aEvent=%d, aError=%d", aId, aFxn, aEvent, aError));
   1001 
   1002     //clear the cmd Pending and Canceled flags
   1003     iDNS.iState.Reset();
   1004 
   1005     if (aFxn == EPVDNSGetHostByName)
   1006     {
   1007         OSCL_ASSERT(iNumHostCallback > 0);
   1008         iNumHostCallback--;
   1009     }
   1010     if (!IsAdded())
   1011     {//prevent the leave 49. should never get here
   1012         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::HandleDNSEvent() ERROR line %d", __LINE__));
   1013         return;
   1014     }
   1015 
   1016     //For socket cleanup sequence including Stop & Reset command
   1017     if (iSocketCleanupState != ESocketCleanup_Idle)
   1018     {
   1019         RunIfNotReady();
   1020         return;
   1021     }
   1022 
   1023     if ((aId == REQ_DNS_LOOKUP_ID) && (aFxn == EPVDNSGetHostByName))
   1024     {
   1025         {//wrap the DNS event as an socket event
   1026             SocketEvent tmpSockEvent;
   1027             {//TBD type mismatch
   1028                 tmpSockEvent.iSockId    = aId;
   1029                 tmpSockEvent.iSockFxn = EPVSocketRecv; //aFxn;
   1030 
   1031                 tmpSockEvent.iSockEvent = EPVSocketSuccess; //aEvent;
   1032                 if (oscl_strlen((const char*)iSessionInfo.iSrvAdd.ipAddr.Str()) == 0)
   1033                 {
   1034                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorDNSLookUpError;
   1035                     tmpSockEvent.iSockEvent = EPVSocketFailure; //aEvent;
   1036                 }
   1037                 tmpSockEvent.iSockError = aError;
   1038             }
   1039 
   1040             iSocketEventQueue.push_back(tmpSockEvent);
   1041         }
   1042 
   1043         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
   1044         RunIfNotReady();
   1045         return;
   1046     }
   1047     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::HandleDNSEvent() unsolicited event"));
   1048 }
   1049 //************ end OsclDNSObserver
   1050 
   1051 void PVRTSPEngineNode::Run()
   1052 {
   1053     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Run() In"));
   1054 
   1055     //Drive the reset sequence
   1056     if (iSocketCleanupState != ESocketCleanup_Idle)
   1057     {
   1058         if (resetSocket() == PVMFPending)
   1059             return;//keep waiting on callbacks.
   1060     }
   1061 
   1062     //Process commands.
   1063     if (iPendingCmdQueue.size() > 0)
   1064     {
   1065         if (ProcessCommand(iPendingCmdQueue.front()))
   1066         {
   1067             if (IsAdded())
   1068                 RunIfNotReady();
   1069             return;
   1070         }
   1071     }
   1072 
   1073     if (iRunningCmdQueue.size() > 0)
   1074     {
   1075         DispatchCommand(iRunningCmdQueue.front());
   1076         if ((iPendingCmdQueue.size() > 0) && IsAdded())
   1077         {
   1078             RunIfNotReady();
   1079         }
   1080     }
   1081     else
   1082     {
   1083         if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
   1084         {
   1085             PVMFStatus iRet = processIncomingMessage(iIncomingMsg);
   1086             if ((iRet != PVMFPending) && (iRet != PVMFSuccess))
   1087             {//TBD error handling.
   1088                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::Run() ERROR processIncomingMessage(). Ln %d", __LINE__));
   1089                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_INVALID);
   1090             }
   1091         }
   1092         else if (RTSPParser::ENTITY_BODY_IS_READY == iRTSPParserState)
   1093         {//Incoming message also has an entity body
   1094             PVMFStatus iRet = processEntityBody(iIncomingMsg, iEntityMemFrag);
   1095             if ((iRet != PVMFPending) && (iRet != PVMFSuccess))
   1096             {//TBD error handling.
   1097                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::Run() ERROR processIncomingMessage(). Ln %d", __LINE__));
   1098                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_INVALID);
   1099             }
   1100         }
   1101         else if (!clearEventQueue())
   1102         {
   1103             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::Run() ERROR Ln %d", __LINE__));
   1104 
   1105             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPSocketConnectError;
   1106             //TBD PVMFFailure;
   1107             if (iErrorRecoveryAttempt-- <= 0)
   1108             {
   1109                 ChangeExternalState(EPVMFNodeError);
   1110                 ReportInfoEvent(PVMFInfoStateChanged);
   1111             }
   1112             else
   1113             {
   1114                 int32 err;
   1115                 PVRTSPErrorContext* errorContext = NULL;
   1116                 OSCL_TRY(err, errorContext = OSCL_NEW(PVRTSPErrorContext, ()));
   1117                 if (err || (errorContext ==  NULL))
   1118                 {
   1119                     ChangeExternalState(EPVMFNodeError);
   1120                 }
   1121                 else
   1122                 {//send error info
   1123                     errorContext->iErrState = iState;
   1124 
   1125                     ReportInfoEvent(PVMFInfoErrorHandlingStart);
   1126                     partialResetSessionInfo();
   1127                     clearOutgoingMsgQueue();
   1128                     PVMFStatus status = resetSocket();
   1129 
   1130                     PVRTSPEngineCommand cmd;
   1131                     //const OsclAny* aContext = OSCL_STATIC_CAST(OsclAny*, errorContext);
   1132                     //cmd.PVRTSPEngineCommandBase::Construct(aCmd.iSession,PVMF_RTSP_NODE_ERROR_RECOVERY,aContext);
   1133                     cmd.PVRTSPEngineCommandBase::Construct(0, PVMF_RTSP_NODE_ERROR_RECOVERY, NULL);
   1134                     cmd.iParam1 = OSCL_STATIC_CAST(OsclAny*, errorContext);
   1135 
   1136                     iRunningCmdQueue.AddL(cmd);
   1137                     if (status != PVMFPending)
   1138                         RunIfNotReady();
   1139                 }
   1140             }
   1141         }
   1142     }
   1143 
   1144     if (iInterfaceState == EPVMFNodeStarted || FlushPending())
   1145     {
   1146         while (!iPortActivityQueue.empty())
   1147         {
   1148             if (!ProcessPortActivity())
   1149             {//error
   1150                 break;
   1151             }
   1152         }
   1153     }
   1154     if (FlushPending() && iPortActivityQueue.empty())
   1155     {
   1156         //If we get here we did not process any ports or commands.
   1157         //Check for completion of a flush command...
   1158         SetState(EPVMFNodePrepared);
   1159         //resume port input so the ports can be re-started.
   1160         for (uint32 i = 0; i < iPortVector.size(); i++)
   1161             iPortVector[i]->ResumeInput();
   1162         CommandComplete(iRunningCmdQueue, iRunningCmdQueue.front(), PVMFSuccess);
   1163         RunIfNotReady();
   1164     }
   1165 
   1166     if (rtspParserLoop())
   1167     {
   1168         RunIfNotReady();
   1169     }
   1170 
   1171     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::Run() Out"));
   1172 }
   1173 
   1174 
   1175 /**
   1176 //A routine to tell if a flush operation is in progress.
   1177 */
   1178 bool PVRTSPEngineNode::FlushPending()
   1179 {
   1180     return (iRunningCmdQueue.size() > 0
   1181             && iRunningCmdQueue.front().iCmd == PVMF_GENERIC_NODE_FLUSH);
   1182 }
   1183 
   1184 bool PVRTSPEngineNode::ProcessPortActivity()
   1185 {//called by the AO to process a port activity message
   1186     //Pop the queue...
   1187     PVMFPortActivity activity(iPortActivityQueue.front());
   1188     iPortActivityQueue.erase(&iPortActivityQueue.front());
   1189 
   1190     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1191                     (0, "0x%x PVRTSPEngineNode::ProcessPortActivity: port=0x%x, type=%d",
   1192                      this, activity.iPort, activity.iType));
   1193 
   1194     PVMFStatus status = PVMFSuccess;
   1195     switch (activity.iType)
   1196     {
   1197         case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
   1198             if (NULL == iTheBusyPort)
   1199             {
   1200                 if (activity.iPort->OutgoingMsgQueueSize() > 0)
   1201                 {
   1202                     status = ProcessOutgoingMsg(activity.iPort);
   1203                     //if there is still data, queue another port activity event.
   1204                     if (status == PVMFSuccess
   1205                             && activity.iPort->OutgoingMsgQueueSize() > 0)
   1206                     {
   1207                         QueuePortActivity(activity);
   1208                     }
   1209                 }
   1210             }
   1211             break;
   1212         case PVMF_PORT_ACTIVITY_INCOMING_MSG:
   1213             break;
   1214 
   1215         default:
   1216             break;
   1217     }
   1218 
   1219     //report a failure in port processing...
   1220     if (status != PVMFErrBusy && status != PVMFSuccess)
   1221     {
   1222         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   1223                         (0, "0x%x PVRTSPEngineNode::ProcessPortActivity() Error - ProcessPortActivity failed. port=0x%x, type=%d",
   1224                          this, activity.iPort, activity.iType));
   1225         ReportErrorEvent(PVMFErrPortProcessing);
   1226         return false;
   1227     }
   1228     //return true if we processed an activity...
   1229     //return (status!=PVMFErrBusy);
   1230     return true;
   1231 }
   1232 
   1233 /////////////////////////////////////////////////////
   1234 PVMFStatus PVRTSPEngineNode::ProcessOutgoingMsg(PVMFPortInterface* aPort)
   1235 {
   1236     //Called by the AO to process one message off the outgoing
   1237     //message queue for the given port.  This routine will
   1238     //try to send the data to the connected port.
   1239 
   1240     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   1241                     (0, "0x%x PVRTSPEngineNode::ProcessOutgoingMsg: aPort=0x%x", this, aPort));
   1242 
   1243     PVMFStatus status = aPort->Send();
   1244     if (status == PVMFErrBusy)
   1245     {
   1246         //iTheBusyPort = true;
   1247         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "0x%x PVRTSPEngineNode::ProcessOutgoingMsg: Connected port busy", this));
   1248     }
   1249 
   1250     return status;
   1251 }
   1252 
   1253 /**
   1254 //Called by the command handler AO to process a command from
   1255 //the input queue.
   1256 //Return true if a command was processed, false if the command
   1257 //processor is busy and can't process another command now.
   1258 */
   1259 bool PVRTSPEngineNode::ProcessCommand(PVRTSPEngineCommand& aInCmd)
   1260 {
   1261     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::ProcessCommand() in"));
   1262 
   1263     //don't interrupt a cancel command
   1264     if (!iCancelCmdQueue.empty())
   1265         return false;
   1266     if (!iRunningCmdQueue.empty()
   1267             && iRunningCmdQueue.front().iCmd == PVMF_RTSP_NODE_CANCELALLRESET)
   1268         return false;
   1269 
   1270     //don't interrupt a running command unless this is hi-priority command
   1271     //such as a cancel.
   1272     if (iRunningCmdQueue.size() > 0 && !aInCmd.hipri())
   1273         return false;
   1274 
   1275     {
   1276         //move the command from the pending command queue to the
   1277         //running command queue, where it will remain until it completes.
   1278         int32 err;
   1279         OSCL_TRY(err, iRunningCmdQueue.StoreL(aInCmd););
   1280 
   1281         if (err != OsclErrNone)
   1282         {
   1283             CommandComplete(iPendingCmdQueue, aInCmd, PVMFErrNoMemory);
   1284             return PVMFErrNoMemory;
   1285         }
   1286         iPendingCmdQueue.Erase(&aInCmd);
   1287     }
   1288 
   1289     DispatchCommand(iRunningCmdQueue.front());
   1290     return true;
   1291 }
   1292 
   1293 PVMFStatus PVRTSPEngineNode::DispatchCommand(PVRTSPEngineCommand& aCmd)
   1294 {
   1295     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DispatchCommand() in"));
   1296 
   1297     bool bRevertToPreviousStateImpossible = true;
   1298     bool bErrorRecoveryImpossible = true;
   1299     PVMFStatus iRet = PVMFFailure;
   1300     switch (aCmd.iCmd)
   1301     {
   1302         case PVMF_GENERIC_NODE_QUERYUUID:
   1303             iRet = DoQueryUuid(aCmd);
   1304             break;
   1305 
   1306         case PVMF_GENERIC_NODE_INIT:
   1307             iRet = DoInitNode(aCmd);
   1308             if (iRet == PVMFSuccess)
   1309             {
   1310                 ChangeExternalState(EPVMFNodeInitialized);
   1311             }
   1312             bErrorRecoveryImpossible = false;
   1313             break;
   1314 
   1315         case PVMF_GENERIC_NODE_PREPARE:
   1316             iRet = DoPrepareNode(aCmd);
   1317             if (iRet == PVMFSuccess)
   1318             {
   1319                 ChangeExternalState(EPVMFNodePrepared);
   1320             }
   1321             bErrorRecoveryImpossible = false;
   1322             break;
   1323 
   1324         case PVMF_GENERIC_NODE_START:
   1325             iRet = DoStartNode(aCmd);
   1326             if (iRet == PVMFSuccess)
   1327             {
   1328                 ChangeExternalState(EPVMFNodeStarted);
   1329                 if (bKeepAliveInPlay)
   1330                 {
   1331                     //setup the timer for sending keep-alive
   1332                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::DispatchCommand() start keep-alive timer %d. Ln %d", TIMEOUT_KEEPALIVE, __LINE__));
   1333                     iWatchdogTimer->Request(REQ_TIMER_KEEPALIVE_ID, 0, TIMEOUT_KEEPALIVE);
   1334                 }
   1335             }
   1336             bErrorRecoveryImpossible = false;
   1337             break;
   1338 
   1339         case PVMF_GENERIC_NODE_STOP:
   1340             iRet = DoStopNode(aCmd);
   1341             if (iRet == PVMFSuccess)
   1342             {
   1343                 ChangeExternalState(EPVMFNodePrepared);
   1344             }
   1345             bRevertToPreviousStateImpossible = false;
   1346             bErrorRecoveryImpossible = false;
   1347             break;
   1348 
   1349         case PVMF_GENERIC_NODE_PAUSE:
   1350             iRet = DoPauseNode(aCmd);
   1351             if (iRet == PVMFSuccess)
   1352             {
   1353                 //setup the timer for sending keep-alive
   1354                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::DispatchCommand() start keep-alive timer %d. Ln %d", TIMEOUT_KEEPALIVE, __LINE__));
   1355                 iWatchdogTimer->Request(REQ_TIMER_KEEPALIVE_ID, 0, TIMEOUT_KEEPALIVE);
   1356 
   1357                 ChangeExternalState(EPVMFNodePaused);
   1358             }
   1359             bRevertToPreviousStateImpossible = false;
   1360             bErrorRecoveryImpossible = false;
   1361             break;
   1362 
   1363         case PVMF_GENERIC_NODE_RESET:
   1364         case PVMF_RTSP_NODE_CANCELALLRESET:
   1365             iRet = DoResetNode(aCmd);
   1366             if (iRet != PVMFPending)
   1367             {
   1368                 OSCL_DELETE(iRTSPParser);
   1369                 iRTSPParser = NULL;
   1370 
   1371                 partialResetSessionInfo();
   1372                 ResetSessionInfo();
   1373                 clearOutgoingMsgQueue();
   1374                 iRet = resetSocket();
   1375             }
   1376             break;
   1377 
   1378         case PVMF_GENERIC_NODE_QUERYINTERFACE:
   1379             iRet = DoQueryInterface(aCmd);
   1380             break;
   1381 
   1382         case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
   1383             iRet = DoCancelAllCommands(aCmd);
   1384             break;
   1385 
   1386 
   1387         case PVMF_GENERIC_NODE_FLUSH:
   1388             iRet = DoFlush(aCmd);
   1389             break;
   1390 
   1391         case PVMF_GENERIC_NODE_REQUESTPORT:
   1392         {
   1393             PVMFRTSPPort* aPort = NULL;
   1394             iRet = DoRequestPort(aCmd, aPort);
   1395             if (iRet == PVMFSuccess)
   1396             {
   1397                 //Return the port pointer to the caller.
   1398                 CommandComplete(iRunningCmdQueue, aCmd, iRet, (OsclAny*)aPort);
   1399                 return iRet;
   1400             }
   1401         }
   1402         break;
   1403 
   1404         case PVMF_GENERIC_NODE_RELEASEPORT:
   1405             iRet = DoReleasePort(aCmd);
   1406             break;
   1407 
   1408         case PVMF_RTSP_NODE_ERROR_RECOVERY:
   1409             iRet = DoErrorRecovery(aCmd);
   1410             if (iRet != PVMFPending)
   1411             {
   1412                 if ((iRet != PVMFSuccess) && (iErrorRecoveryAttempt-- > 0))
   1413                 {//retry
   1414                     partialResetSessionInfo();
   1415                     clearOutgoingMsgQueue();
   1416                     iRet = resetSocket();
   1417                     if (iRet != PVMFPending)
   1418                         RunIfNotReady();
   1419                     return PVMFPending;
   1420                 }
   1421 
   1422                 if ((iRet == PVMFSuccess) && (iState == PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE))
   1423                 {
   1424                     //setup the timer for sending keep-alive
   1425                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::DispatchCommand() start keep-alive timer %d. Ln %d", TIMEOUT_KEEPALIVE, __LINE__));
   1426                     iWatchdogTimer->Request(REQ_TIMER_KEEPALIVE_ID, 0, TIMEOUT_KEEPALIVE);
   1427 
   1428                     ChangeExternalState(EPVMFNodePaused);
   1429                     ReportInfoEvent(PVMFInfoStateChanged);
   1430                 }
   1431 
   1432                 PVRTSPErrorContext* errorContext = OSCL_STATIC_CAST(PVRTSPErrorContext*, aCmd.iParam1);
   1433                 if (errorContext)
   1434                 {
   1435                     OSCL_DELETE(errorContext);
   1436                 }
   1437                 //Erase the cmd from iRunningCmdQueue
   1438                 iRunningCmdQueue.Erase(&aCmd);
   1439 
   1440 
   1441                 if (iRunningCmdQueue.size() > 0)
   1442                 {//error happened while servicing an reqeust, resume service
   1443                     //RunIfNotReady();
   1444                     aCmd = iRunningCmdQueue.front();
   1445                     if (iRet == PVMFSuccess)
   1446                     {
   1447                         iRet = PVMFPending;
   1448                         //TBD
   1449                         //this RunIfNotReady() is only needed when no event pending
   1450                         // like Prepare() fails in PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE state
   1451                         RunIfNotReady();
   1452                     }
   1453                 }
   1454                 else
   1455                 {//do report event
   1456                     if (iRet != PVMFSuccess)
   1457                     {
   1458                         ChangeExternalState(EPVMFNodeError);
   1459                         ReportInfoEvent(PVMFInfoStateChanged);
   1460                     }
   1461                     iRet = PVMFPending; ////internal cmd, no CommandComplete needed
   1462                 }
   1463                 ReportInfoEvent(PVMFInfoErrorHandlingComplete);
   1464             }
   1465             break;
   1466 
   1467         default://unknown command type
   1468             iRet = PVMFFailure;
   1469             break;
   1470     }
   1471 
   1472     if (iRet != PVMFPending)
   1473     {
   1474         if (iRet != PVMFSuccess)
   1475         {
   1476             if (bRevertToPreviousStateImpossible)
   1477             {
   1478                 ///////////////////////////////////////////////////////////////////////////
   1479                 //
   1480                 // Added 5/9/2006 to disable error recovery. Error recovery needs to become
   1481                 // configurable; until then, we'll disable it
   1482                 //
   1483                 //bErrorRecoveryImpossible = true;
   1484                 ///////////////////////////////////////////////////////////////////////////
   1485 
   1486                 if ((bErrorRecoveryImpossible) || (iErrorRecoveryAttempt-- <= 0))
   1487                 {
   1488                     ChangeExternalState(EPVMFNodeError);
   1489                     ReportInfoEvent(PVMFInfoStateChanged);
   1490                 }
   1491                 else
   1492                 {
   1493                     int32 err;
   1494                     PVRTSPErrorContext* errorContext = NULL;
   1495                     OSCL_TRY(err, errorContext = OSCL_NEW(PVRTSPErrorContext, ()));
   1496                     if (err || (errorContext ==  NULL))
   1497                     {
   1498                         iRet = PVMFFailure; // reinitialized since it may be clobbered by OSCL_TRY()
   1499                         ChangeExternalState(EPVMFNodeError);
   1500                     }
   1501                     else
   1502                     {//send error info
   1503                         errorContext->iErrState = iState;
   1504 
   1505                         ReportInfoEvent(PVMFInfoErrorHandlingStart);
   1506                         partialResetSessionInfo();
   1507                         clearOutgoingMsgQueue();
   1508                         PVMFStatus status = resetSocket();
   1509 
   1510                         iState = PVRTSP_ENGINE_NODE_STATE_IDLE;
   1511 
   1512                         PVRTSPEngineCommand cmd;
   1513                         //const OsclAny* aContext = OSCL_STATIC_CAST(OsclAny*, errorContext);
   1514                         //cmd.PVRTSPEngineCommandBase::Construct(aCmd.iSession,PVMF_RTSP_NODE_ERROR_RECOVERY,aContext);
   1515                         cmd.PVRTSPEngineCommandBase::Construct(aCmd.iSession, PVMF_RTSP_NODE_ERROR_RECOVERY, NULL);
   1516                         cmd.iParam1 = OSCL_STATIC_CAST(OsclAny*, errorContext);
   1517 
   1518                         iRunningCmdQueue.AddL(cmd);
   1519 
   1520                         if (status != PVMFPending)
   1521                             RunIfNotReady();
   1522                         return PVMFPending;
   1523                     }
   1524                 }
   1525             }
   1526             if (iCurrentErrorCode != PVMFRTSPClientEngineNodeErrorEventStart)
   1527             {
   1528                 CommandComplete(iRunningCmdQueue, aCmd, iRet, NULL, &iEventUUID, &iCurrentErrorCode);
   1529                 /* Reset error code */
   1530                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorEventStart;
   1531                 return iRet;
   1532             }
   1533         }
   1534         CommandComplete(iRunningCmdQueue, aCmd, iRet);
   1535     }
   1536     return iRet;
   1537 }
   1538 
   1539 
   1540 /**
   1541 //The various command handlers call this when a command is complete.
   1542 */
   1543 void PVRTSPEngineNode::CommandComplete(PVRTSPEngineNodeCmdQ& aCmdQ,
   1544                                        PVRTSPEngineCommand& aCmd,
   1545                                        PVMFStatus aStatus,
   1546                                        OsclAny* aEventData,
   1547                                        PVUuid* aEventUUID,
   1548                                        int32* aEventCode)
   1549 
   1550 {
   1551     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode:CommandComplete Id %d Cmd %d Status %d Context %d Data %d"
   1552                     , aCmd.iId, aCmd.iCmd, aStatus, aCmd.iContext, aEventData));
   1553 
   1554     //Do special handling of some commands.
   1555     switch (aCmd.iCmd)
   1556     {
   1557 
   1558         case PVMF_RTSP_NODE_CANCELALLRESET:
   1559             //restore command ID
   1560             aCmd.iCmd = PVMF_GENERIC_NODE_CANCELALLCOMMANDS;
   1561             break;
   1562 
   1563         case PVMF_GENERIC_NODE_RESET:
   1564             if (aStatus == PVMFSuccess)
   1565                 ChangeExternalState(EPVMFNodeIdle);
   1566             ThreadLogoff();
   1567             break;
   1568 
   1569         case PVMF_GENERIC_NODE_CANCELALLCOMMANDS:
   1570             //Add a reset sequence to the end of "Cancel all" processing, in order to
   1571             //satisfy the expectation of streaming manager node.
   1572         {
   1573             //change the command type to "cancelallreset"
   1574             aCmd.iCmd = PVMF_RTSP_NODE_CANCELALLRESET;
   1575             //move command from cancel command queue to running command queue
   1576             //if necessary.  we do this because this node is only setup to
   1577             //continue processing commands in the running queue.
   1578             if (&aCmdQ == &iCancelCmdQueue)
   1579             {
   1580                 iRunningCmdQueue.StoreL(aCmd);
   1581                 aCmdQ.Erase(&aCmd);
   1582             }
   1583             RunIfNotReady();
   1584             return;
   1585         }
   1586         default:
   1587             break;
   1588     }
   1589 
   1590     PVInterface* extif = NULL;
   1591     PVMFBasicErrorInfoMessage* errormsg = NULL;
   1592     if (aEventUUID && aEventCode)
   1593     {
   1594         errormsg = OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
   1595         extif = OSCL_STATIC_CAST(PVInterface*, errormsg);
   1596     }
   1597 
   1598     //create response
   1599     PVMFCmdResp resp(aCmd.iId, aCmd.iContext, aStatus, extif, aEventData);
   1600     PVMFSessionId session = aCmd.iSession;
   1601 
   1602     //Erase the command from the queue.
   1603     aCmdQ.Erase(&aCmd);
   1604 
   1605     //Report completion to the session observer.
   1606     ReportCmdCompleteEvent(session, resp);
   1607 
   1608     if (errormsg)
   1609     {
   1610         errormsg->removeRef();
   1611     }
   1612 
   1613     //There may be a cancel command that was just waiting on the running command to finish.
   1614     //If so, complete the cancel command now.
   1615     if (&aCmdQ == &iRunningCmdQueue
   1616             && !iCancelCmdQueue.empty())
   1617     {
   1618         CommandComplete(iCancelCmdQueue, iCancelCmdQueue.front(), PVMFSuccess);
   1619     }
   1620 }
   1621 
   1622 // Handle command and data events
   1623 PVMFCommandId PVRTSPEngineNode::AddCmdToQueue(PVRTSPEngineCommand& aCmd)
   1624 {
   1625     PVMFCommandId id;
   1626 
   1627     id = iPendingCmdQueue.AddL(aCmd);
   1628 
   1629     //wakeup the AO
   1630     RunIfNotReady();
   1631 
   1632     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::AddCmdToQueue() Cmd Id %d", id));
   1633     return id;
   1634 }
   1635 
   1636 void PVRTSPEngineNode::ChangeExternalState(TPVMFNodeInterfaceState aNewState)
   1637 {
   1638     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::ChangeExternalState() Old %d New %d", iInterfaceState, aNewState));
   1639     iInterfaceState = aNewState;
   1640 }
   1641 
   1642 void PVRTSPEngineNode::ChangeInternalState(PVRTSPEngineState aNewState)
   1643 {
   1644     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::ChangeInternalState() Old %d New %d", iState, aNewState));
   1645     iState = aNewState;
   1646 }
   1647 
   1648 PVMFStatus PVRTSPEngineNode::DoInitNode(PVRTSPEngineCommand &aCmd)
   1649 {
   1650     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoInitNode() In"));
   1651     OSCL_UNUSED_ARG(aCmd);
   1652 
   1653     if (iInterfaceState != EPVMFNodeIdle)
   1654     {
   1655         return PVMFErrInvalidState;
   1656     }
   1657 
   1658     if (bAddXStrHeader)
   1659     {
   1660         // create iGetPostCorrelationObject
   1661         if (!iGetPostCorrelationObject)
   1662         {
   1663             if ((iGetPostCorrelationObject = GetPostCorrelationObject::create()) == NULL) return PVMFFailure;
   1664         }
   1665     }
   1666 
   1667     return SendRtspDescribe(aCmd);
   1668 }
   1669 
   1670 PVMFStatus PVRTSPEngineNode::SendRtspDescribe(PVRTSPEngineCommand &aCmd)
   1671 {
   1672     OSCL_UNUSED_ARG(aCmd);
   1673 
   1674     PVMFStatus iRet = PVMFPending;
   1675     switch (iState)
   1676     {
   1677         case PVRTSP_ENGINE_NODE_STATE_IDLE:
   1678         {
   1679             if (iSockServ == NULL)
   1680             {
   1681                 int32 err;
   1682                 OSCL_TRY(err, iSockServ = OsclSocketServ::NewL(iAlloc););
   1683                 if (err || (iSockServ ==  NULL))
   1684                 {
   1685                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketServerError;
   1686                     iRet =  PVMFFailure;
   1687                     break;
   1688                 }
   1689                 if (iSockServ->Connect() != OsclErrNone)
   1690                 {
   1691                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketServerError;
   1692                     iRet =  PVMFFailure;
   1693                     break;
   1694                 }
   1695             }
   1696 
   1697             if (!iRTSPParser)
   1698             {
   1699                 iRTSPParser = OSCL_NEW(RTSPParser, ());
   1700                 if (NULL == iRTSPParser)
   1701                 {
   1702                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPParserError;
   1703                     iRet =  PVMFFailure;
   1704                     break;
   1705                 }
   1706             }
   1707             iRTSPParser->flush();
   1708 
   1709             // 1. Do DNS look up if needed.
   1710             OSCL_HeapString<PVRTSPEngineNodeAllocator> endPointName = iSessionInfo.iServerName;
   1711             if (iSessionInfo.iProxyName.get_size())
   1712             {
   1713                 iSessionInfo.iSrvAdd.port = iSessionInfo.iProxyPort;
   1714                 endPointName = iSessionInfo.iProxyName;
   1715             }
   1716 
   1717             if (OsclValidInetAddr(endPointName.get_cstr()))
   1718             {//ip address
   1719                 iSessionInfo.iSrvAdd.ipAddr.Set(endPointName.get_cstr());
   1720                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
   1721                 RunIfNotReady();
   1722             }
   1723             else
   1724             {//dns lookup
   1725                 if (NULL == iDNS.iDns)
   1726                 {
   1727                     REQ_DNS_LOOKUP_ID =  ++BASE_REQUEST_ID;
   1728                     iDNS.iDns = OsclDNS::NewL(iAlloc, *iSockServ, *this, REQ_DNS_LOOKUP_ID);
   1729                 }
   1730                 if (iDNS.iDns == NULL)
   1731                 {
   1732                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorDNSLookUpError;
   1733                     iRet =  PVMFFailure;
   1734                     break;
   1735                 }
   1736                 iDNS.iState.Reset();
   1737 
   1738                 iSessionInfo.iSrvAdd.ipAddr.Set("");
   1739                 if (EPVDNSPending != iDNS.iDns->GetHostByName(endPointName.get_str(), iSessionInfo.iSrvAdd, TIMEOUT_CONNECT_AND_DNS_LOOKUP))
   1740                 {
   1741                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorDNSLookUpError;
   1742                     iRet =  PVMFFailure;
   1743                     break;
   1744                 }
   1745                 iDNS.iState.iPending = true;
   1746                 iNumHostCallback++;
   1747                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_DNS_RESOLVING);
   1748             }
   1749             break;
   1750         }
   1751 
   1752         case PVRTSP_ENGINE_NODE_STATE_DNS_RESOLVING:
   1753         {
   1754             break;
   1755         }
   1756 
   1757         case PVRTSP_ENGINE_NODE_STATE_CONNECT:
   1758         {
   1759             if (!clearEventQueue())
   1760             {
   1761                 //cancell the watchdog
   1762                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   1763 
   1764                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorDNSLookUpError;
   1765                 iRet =  PVMFFailure;
   1766                 break;
   1767             }
   1768             {
   1769                 //Allocate 1 TCP socket and set both iSendSocket and iRecvSocket to that socket.
   1770                 //Note: in this case we only track the status in the "send" container since
   1771                 //it's really only one socket.
   1772                 int32 err;
   1773                 OsclTCPSocket *sock = NULL;
   1774                 OSCL_TRY(err, sock = OsclTCPSocket::NewL(iAlloc, *iSockServ, this, REQ_SEND_SOCKET_ID););
   1775                 if (err || (sock ==  NULL))
   1776                 {
   1777                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPSocketCreateError;
   1778                     iRet =  PVMFFailure;
   1779                     break;
   1780                 }
   1781                 iRecvSocket.Reset(sock);
   1782                 iSendSocket.Reset(sock);
   1783 
   1784                 //proxy support
   1785                 //OSCL_StackString<64> tmpServerName = _STRLIT_CHAR("172.16.2.145");
   1786                 //iSessionInfo.iSrvAdd.ipAddr.Set( tmpServerName.get_cstr() );
   1787 
   1788                 TPVSocketEvent sendConnect = iSendSocket.iSocket->Connect(iSessionInfo.iSrvAdd, TIMEOUT_CONNECT_AND_DNS_LOOKUP);
   1789                 if (sendConnect == EPVSocketPending)
   1790                     iSendSocket.iConnectState.iPending = true;
   1791                 if (sendConnect != EPVSocketPending)
   1792                 {
   1793                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPSocketConnectError;
   1794                     iRet =  PVMFFailure;
   1795                     break;
   1796                 }
   1797                 iNumConnectCallback++;
   1798             }
   1799 
   1800             ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECTING);
   1801             break;
   1802         }
   1803         case PVRTSP_ENGINE_NODE_STATE_CONNECTING:
   1804         {
   1805             uint32 numSockEvents = (PVRTSP_RM_HTTP == iSessionInfo.iStreamingType) ? 2 : 1;
   1806             if (iSocketEventQueue.size() < numSockEvents)
   1807             {
   1808                 break;
   1809             }
   1810 
   1811             do
   1812             {
   1813                 SocketEvent tmpSockEvent(iSocketEventQueue.front());
   1814                 iSocketEventQueue.erase(&iSocketEventQueue.front());
   1815 
   1816                 if (tmpSockEvent.iSockEvent != EPVSocketSuccess)
   1817                 {
   1818                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPSocketConnectError;
   1819                     iRet =  PVMFFailure;
   1820                     break;
   1821                 }
   1822                 if (tmpSockEvent.iSockFxn != EPVSocketConnect)
   1823                 {   //unsolicited socket event
   1824                     //break;
   1825                     continue;
   1826                 }
   1827                 if (tmpSockEvent.iSockId == REQ_RECV_SOCKET_ID)
   1828                 {
   1829                     bNoRecvPending = true;
   1830                 }
   1831                 else if (tmpSockEvent.iSockId == REQ_SEND_SOCKET_ID)
   1832                 {
   1833                     bNoSendPending = true;
   1834                 }
   1835 
   1836                 if (PVRTSP_RM_HTTP != iSessionInfo.iStreamingType)
   1837                 {
   1838                     bNoSendPending = bNoRecvPending = true;
   1839                 }
   1840             }
   1841             while (!iSocketEventQueue.empty());
   1842 
   1843             if (!(bNoSendPending && bNoRecvPending))
   1844             {
   1845                 break;
   1846             }
   1847 
   1848             REQ_TIMER_WATCHDOG_ID =  ++BASE_REQUEST_ID;
   1849             REQ_TIMER_KEEPALIVE_ID =  ++BASE_REQUEST_ID;
   1850             if (iSessionInfo.iSDPinfo.GetRep() != NULL)
   1851             {//if sdp is available
   1852                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE);
   1853                 iRet =  PVMFSuccess;
   1854                 break;
   1855             }
   1856             else
   1857             {//if sdp is not available
   1858                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_SEND_OPTIONS);
   1859             }
   1860             //DO NOT break, continue to send DESCRIBE
   1861             RunIfNotReady();
   1862             break;
   1863         }
   1864         case PVRTSP_ENGINE_NODE_STATE_HTTP_CLOAKING_SETUP:
   1865         {//send the GET and POST requests.
   1866             if (!clearEventQueue())
   1867             {
   1868                 //cancell the watchdog
   1869                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   1870 
   1871                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPSocketConnectError;
   1872                 iRet =  PVMFFailure;
   1873                 break;
   1874             }
   1875 
   1876             if (RTSPParser::REQUEST_IS_READY != iRTSPParserState)
   1877                 break;
   1878 
   1879             {
   1880                 iRet = processIncomingMessage(iIncomingMsg);
   1881                 if (iRet != PVMFPending)
   1882                 {
   1883                     //cancell the watchdog
   1884                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   1885                 }
   1886                 if (iRet == PVMFSuccess)
   1887                 {
   1888                     iRet = PVMFPending;
   1889                 }
   1890                 else
   1891                 {//either pending or error
   1892                     break;
   1893                 }
   1894             }
   1895 
   1896             if (iSessionInfo.iSDPinfo.GetRep() != NULL)
   1897             {//if sdp is available
   1898                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE);
   1899                 iRet =  PVMFSuccess;
   1900                 break;
   1901             }
   1902             else
   1903             {//if sdp is not available
   1904                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_SEND_OPTIONS);
   1905                 //go to next case directly
   1906                 //RunIfNotReady(); break;
   1907             }
   1908         }
   1909 
   1910         case PVRTSP_ENGINE_NODE_STATE_SEND_OPTIONS:
   1911         {
   1912             if (bNoSendPending)
   1913             {
   1914                 // send options
   1915                 RTSPOutgoingMessage *tmpOutgoingMsg = OSCL_NEW(RTSPOutgoingMessage, ());
   1916                 if (tmpOutgoingMsg == NULL)
   1917                 {
   1918                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   1919                     iRet =  PVMFFailure;
   1920                     break;
   1921                 }
   1922 
   1923                 if (PVMFSuccess != composeOptionsRequest(*tmpOutgoingMsg))
   1924                 {
   1925                     iCurrentErrorCode =
   1926                         PVMFRTSPClientEngineNodeErrorRTSPComposeOptionsRequestError;
   1927                     OSCL_DELETE(tmpOutgoingMsg);
   1928                     iRet =  PVMFFailure;
   1929                     break;
   1930                 }
   1931 
   1932                 if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
   1933                 {
   1934                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   1935                     OSCL_DELETE(tmpOutgoingMsg);
   1936                     iRet =  PVMFFailure;
   1937                     break;
   1938                 }
   1939 
   1940                 bNoSendPending = false;
   1941                 iOutgoingMsgQueue.push(tmpOutgoingMsg);
   1942                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_SEND_DESCRIBE);
   1943 
   1944                 //setup the watch dog for server response
   1945                 iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG);
   1946             }
   1947             break;
   1948         }
   1949 
   1950         case PVRTSP_ENGINE_NODE_STATE_SEND_DESCRIBE:
   1951         {
   1952             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
   1953             {
   1954                 iRet = processIncomingMessage(iIncomingMsg);
   1955                 if (iRet == PVMFSuccess)
   1956                 {
   1957                     iRet = PVMFPending;
   1958                 }
   1959                 else
   1960                 {//either pending or error
   1961                     if (iRet != PVMFPending)
   1962                     {
   1963                         //cancell the watchdog
   1964                         iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   1965                     }
   1966                     if ((RTSPResponseMsg != iIncomingMsg.msgType) || (iRet != PVMFPending))
   1967                     {//processIncomingMessage() returns pending if there are unacknowledged
   1968                         //rtsp msgs
   1969                         break;
   1970                     }
   1971                 }
   1972 
   1973                 iRealChallenge1 = "";
   1974                 const StrPtrLen *tmpRealChallenge = iIncomingMsg.queryField("RealChallenge1");
   1975                 if (tmpRealChallenge)
   1976                 {
   1977                     iRealChallenge1 = OSCL_HeapString<OsclMemAllocator>(tmpRealChallenge->c_str());
   1978                 }
   1979 
   1980                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_DESCRIBE_WAITING);
   1981             }
   1982 
   1983             if (bNoSendPending)
   1984             {
   1985                 // send describe
   1986                 RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
   1987                 if (tmpOutgoingMsg == NULL)
   1988                 {
   1989                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   1990                     iRet =  PVMFFailure;
   1991                     break;
   1992                 }
   1993                 if (PVMFSuccess != composeDescribeRequest(*tmpOutgoingMsg))
   1994                 {
   1995                     iCurrentErrorCode =
   1996                         PVMFRTSPClientEngineNodeErrorRTSPComposeDescribeRequestError;
   1997                     OSCL_DELETE(tmpOutgoingMsg);
   1998                     iRet =  PVMFFailure;
   1999 
   2000                     //cancell the watchdog
   2001                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2002                     break;
   2003                 }
   2004 
   2005                 if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
   2006                 {
   2007                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   2008                     OSCL_DELETE(tmpOutgoingMsg);
   2009                     iRet =  PVMFFailure;
   2010                     //cancell the watchdog
   2011                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2012                     break;
   2013                 }
   2014 
   2015                 bNoSendPending = false;
   2016                 iOutgoingMsgQueue.push(tmpOutgoingMsg);
   2017 
   2018                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_OPTIONS_WAITING);
   2019                 //RunIfNotReady();
   2020             }
   2021             break;
   2022         }
   2023         case PVRTSP_ENGINE_NODE_STATE_OPTIONS_WAITING:
   2024         {
   2025             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
   2026             {
   2027                 iRet = processIncomingMessage(iIncomingMsg);
   2028                 if (iRet == PVMFSuccess)
   2029                 {
   2030                     iRet = PVMFPending;
   2031                 }
   2032                 else
   2033                 {//either pending or error
   2034                     if (iRet != PVMFPending)
   2035                     {
   2036                         //cancell the watchdog
   2037                         iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2038                     }
   2039 
   2040                     if ((RTSPResponseMsg != iIncomingMsg.msgType) || (iRet != PVMFPending))
   2041                     {//processIncomingMessage() returns pending if there are unacknowledged
   2042                         //rtsp msgs
   2043                         break;
   2044                     }
   2045                 }
   2046 
   2047                 iRealChallenge1 = "";
   2048                 const StrPtrLen *tmpRealChallenge = iIncomingMsg.queryField("RealChallenge1");
   2049                 if (tmpRealChallenge)
   2050                 {
   2051                     iRealChallenge1 = OSCL_HeapString<OsclMemAllocator>(tmpRealChallenge->c_str());
   2052                 }
   2053 
   2054                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_DESCRIBE_WAITING);
   2055             }
   2056             else if (!clearEventQueue())
   2057             {//sth failed, could be Send, Recv, or server closes
   2058                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketError;
   2059                 iRet =  PVMFFailure;
   2060                 //cancell the watchdog
   2061                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2062             }
   2063             break;
   2064         }
   2065         case PVRTSP_ENGINE_NODE_STATE_DESCRIBE_WAITING:
   2066         {
   2067             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
   2068             {
   2069                 iRet = processIncomingMessage(iIncomingMsg);
   2070                 if (iRet == PVMFSuccess)
   2071                 {//Init is not done until we get SDP
   2072                     iRet = PVMFPending;
   2073                 }
   2074                 else
   2075                 {//either pending or error
   2076                     if (iRet != PVMFPending)
   2077                     {
   2078                         //cancell the watchdog
   2079                         iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2080                     }
   2081                     break;
   2082                 }
   2083             }
   2084             else if (RTSPParser::ENTITY_BODY_IS_READY == iRTSPParserState)
   2085             {//got sdp
   2086                 {
   2087                     OsclRefCounter* my_refcnt = new OsclRefCounterSA< RTSPNodeMemDestructDealloc >(iEntityMemFrag.ptr);
   2088                     if (my_refcnt == NULL)
   2089                     {
   2090                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspDescribe() Unable to Allocate Memory"));
   2091                         return PVMFErrNoMemory;
   2092                     }
   2093 
   2094                     iSessionInfo.pSDPBuf = OsclRefCounterMemFrag(iEntityMemFrag, my_refcnt, iEntityMemFrag.len);
   2095                     {//done with the entity body, change the ownership of the mem
   2096                         iEntityMemFrag.len = 0;
   2097                         iEntityMemFrag.ptr = NULL;
   2098                     }
   2099                 }
   2100 
   2101                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE);
   2102 
   2103                 //cancell the watchdog
   2104                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2105                 //iWatchdogTimer->Clear();
   2106 
   2107                 iRet =  PVMFSuccess;
   2108             }
   2109             else if (!clearEventQueue())
   2110             {
   2111                 //cancell the watchdog
   2112                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2113 
   2114                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketError;
   2115                 iRet =  PVMFFailure;
   2116                 break;
   2117             }
   2118             break;
   2119         }
   2120         default:
   2121         {
   2122             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::SendRtspDescribe() In"));
   2123             iRet = PVMFErrInvalidState;
   2124             break;
   2125         }
   2126     }
   2127 
   2128     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspDescribe() Out"));
   2129     return iRet;
   2130 }
   2131 
   2132 PVMFStatus PVRTSPEngineNode::DoPrepareNode(PVRTSPEngineCommand &aCmd)
   2133 {
   2134     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoPrepareNode() In"));
   2135     OSCL_UNUSED_ARG(aCmd);
   2136 
   2137     if (iInterfaceState != EPVMFNodeInitialized)
   2138     {
   2139         return PVMFErrInvalidState;
   2140     }
   2141 
   2142     return SendRtspSetup(aCmd);
   2143 }
   2144 
   2145 PVMFStatus PVRTSPEngineNode::SendRtspSetup(PVRTSPEngineCommand &aCmd)
   2146 {
   2147     OSCL_UNUSED_ARG(aCmd);
   2148 
   2149     PVMFStatus iRet = PVMFPending;
   2150     switch (iState)
   2151     {
   2152         case PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE:
   2153         case PVRTSP_ENGINE_NODE_STATE_PROCESS_REST_SETUP:
   2154         {
   2155             /*
   2156             before this, the track selection is done.
   2157             Also, the Bind for RTP and RTCP for each channel are done
   2158 
   2159               compose one RTSPOutgoingMessage for each SETUP
   2160               push each RTSPOutgoingMessage in the iOutgoingMsgQueue
   2161               lump all the SETUPs in one Send
   2162                 */
   2163 
   2164             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
   2165             {
   2166                 iRet = processIncomingMessage(iIncomingMsg);
   2167                 if (iRet == PVMFSuccess)
   2168                 {//The Prepare() not done until all the SETUPs are sent
   2169                     iRet = PVMFPending;
   2170                 }
   2171                 else
   2172                 {//either pending or error
   2173                     if (iRet != PVMFPending)
   2174                     {
   2175                         //cancell the watchdog
   2176                         iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2177                     }
   2178                     break;
   2179                 }
   2180 
   2181                 if (iState == PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE)
   2182                 {//ok, got the resp of 1st SETUP, send the reset SETUPs
   2183                     bNoSendPending = true;
   2184                     ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PROCESS_REST_SETUP);
   2185                 }
   2186 
   2187                 //idx = iSessionInfo.trackSelectionList->getNumTracks();
   2188                 //if(all SETUPs resp are back)
   2189                 if ((uint32)setupTrackIndex  == iSessionInfo.iSelectedStream.size())
   2190                 {
   2191                     if (!iOutgoingMsgQueue.empty())
   2192                     {
   2193                         RTSPOutgoingMessage* tmpOutgoingMsg = iOutgoingMsgQueue.top();
   2194                         if (tmpOutgoingMsg->method == METHOD_SETUP)
   2195                         {//still got some SETUPs of which server has not responded
   2196                             break;
   2197                         }
   2198                     }
   2199 
   2200                     //cancell the watchdog
   2201                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2202                     //iWatchdogTimer->Clear();
   2203 
   2204                     if (ibIsRealRDT)
   2205                     {
   2206                         // create frag group allocator
   2207                         ipFragGroupMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (DEFAULT_NUM_MEDIA_MSGS_IN_JITTER_BUFFER));
   2208                         if (ipFragGroupMemPool == NULL)
   2209                         {
   2210                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DoInitNode() Error - Unable to allocate mempool"));
   2211                             return PVMFErrNoMemory;
   2212                         }
   2213                         ipFragGroupAllocator = OSCL_NEW(PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>, (
   2214                                                             DEFAULT_NUM_MEDIA_MSGS_IN_JITTER_BUFFER,
   2215                                                             1, ipFragGroupMemPool));
   2216                         if (ipFragGroupAllocator == NULL)
   2217                         {
   2218                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DoInitNode() Error - Unable to create frag group allocator"));
   2219                             return PVMFErrNoMemory;
   2220                         }
   2221                         ipFragGroupAllocator->create();
   2222                     }
   2223 
   2224                     ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_SETUP_DONE);
   2225                     iRet =  PVMFSuccess;
   2226                     break;
   2227                     //break;    //send PLAY back-to-back
   2228                 }
   2229             }
   2230             else if (RTSPParser::ENTITY_BODY_IS_READY == iRTSPParserState)
   2231             {//got still image
   2232                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_SETUP_DONE);
   2233                 iRet =  PVMFSuccess;
   2234                 break;
   2235             }
   2236             else if (!iSocketEventQueue.empty())
   2237             {//TBD          if(!clearEventQueue())
   2238                 SocketEvent tmpSockEvent(iSocketEventQueue.front());
   2239                 iSocketEventQueue.erase(&iSocketEventQueue.front());
   2240 
   2241                 if (tmpSockEvent.iSockEvent != EPVSocketSuccess)
   2242                 {//sth failed, could be Send, Recv, or server closes
   2243                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketError;
   2244                     iRet =  PVMFFailure;
   2245                     break;
   2246                 }
   2247 
   2248                 if ((iState == PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE)
   2249                         && (tmpSockEvent.iSockFxn == EPVSocketSend))
   2250                 {//pretend there is a send pending so it waits for the first
   2251                     //SETUP resp to come back and then sends the rest SETUPs
   2252                     bNoSendPending = false;
   2253                     break;
   2254                 }
   2255             }
   2256 
   2257             //The trackID is the index to the SDP media info array.
   2258             //Get the first track's index
   2259             //int trackID = iSessionInfo.trackSelectionList->getTrackIndex(setupIndex);
   2260 
   2261             //compose and send SETUP
   2262             //if( (bNoSendPending) && (NOT all the SETUPs are sent out ) )
   2263             if ((bNoSendPending) && ((uint32)setupTrackIndex  < iSessionInfo.iSelectedStream.size()))
   2264             {
   2265                 RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
   2266                 if (tmpOutgoingMsg == NULL)
   2267                 {
   2268                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   2269                     return  PVMFFailure;
   2270                 }
   2271                 //optimize here: use copy/modify instead of build from scratch
   2272                 //idx = iSessionInfo.iSDPinfo.getNumMediaObjects();
   2273                 //idx = iSessionInfo.trackSelectionList->getNumTracks();
   2274                 //if( PVMFSuccess != composeSetupRequest(*tmpOutgoingMsg, idx))
   2275                 if (PVMFSuccess != composeSetupRequest(*tmpOutgoingMsg, iSessionInfo.iSelectedStream[setupTrackIndex ]))
   2276                 {
   2277                     iCurrentErrorCode =
   2278                         PVMFRTSPClientEngineNodeErrorRTSPComposeSetupRequestError;
   2279                     OSCL_DELETE(tmpOutgoingMsg);
   2280                     return  PVMFFailure;
   2281                 }
   2282                 setupTrackIndex ++;
   2283 
   2284                 if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
   2285                 {
   2286                     /* need to pop the msg based on cseq, NOT necessarily the early ones,
   2287                     although YES in this case.
   2288                     //for(int idx=0; idx < iSessionInfo.trackSelectionList->getNumTracks(); idx++ )
   2289                     for(int idx=0; idx < iSessionInfo.iSDPinfo->getNumMediaObjects(); idx++ )
   2290                     {
   2291                     //iOutgoingMsgQueue.pop();
   2292                     }
   2293                         */
   2294                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   2295                     OSCL_DELETE(tmpOutgoingMsg);
   2296                     iRet =  PVMFFailure;
   2297                     break;
   2298                 }
   2299 
   2300                 bNoSendPending = false;
   2301                 iOutgoingMsgQueue.push(tmpOutgoingMsg);
   2302                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_FIRST_SETUP);
   2303 
   2304                 //setup the watch dog for server response
   2305                 if (setupTrackIndex == 1)
   2306                 {//only setup watchdog for the first SETUP, but it monitors all
   2307                     iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG);
   2308                 }
   2309             }
   2310             break;
   2311             //RunIfNotReady();
   2312         }
   2313 
   2314         default:
   2315         {
   2316             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::SendRtspSetup() iState=%d Line %d", iState, __LINE__));
   2317             iRet = PVMFErrInvalidState;
   2318             break;
   2319         }
   2320     }
   2321 
   2322     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspSetup() Out"));
   2323     return iRet;
   2324 }
   2325 
   2326 
   2327 bool PVRTSPEngineNode::parseURL(const OSCL_wString& aURL)
   2328 //(wchar_t *url)
   2329 {
   2330     if (0 == oscl_UnicodeToUTF8(aURL.get_cstr(), aURL.get_size(), ((mbchar*)iRTSPEngTmpBuf.ptr), iRTSPEngTmpBuf.len))
   2331     {
   2332         return false;
   2333     }
   2334 
   2335     return parseURL((mbchar*)iRTSPEngTmpBuf.ptr);
   2336 }
   2337 
   2338 bool PVRTSPEngineNode::parseURL(const char *aUrl)
   2339 {
   2340     /* Input: absolute URI
   2341      * Output: iSessionInfo.iSessionURL, iSessionInfo.iServerName, and iSessionInfo.iSrvAdd.port
   2342      * Connection end point is always iSrvAdd
   2343      * if no proxy is used, iSrvAdd.ipAddr is ip of iServerName and iSrvAdd.port is the server port.
   2344      * Both derived from an absolute url.
   2345      * if proxy is used, iSrvAdd is iProxyName:iProxyPort.
   2346      */
   2347     if (aUrl == NULL)
   2348     {
   2349         return false;
   2350     }
   2351 
   2352     uint32 aURLMaxOutLength;
   2353     PVStringUri::PersentageToEscapedEncoding((mbchar*) aUrl, aURLMaxOutLength);
   2354     PVStringUri::IllegalCharactersToEscapedEncoding((mbchar*) aUrl, aURLMaxOutLength);
   2355 
   2356     iSessionInfo.iSessionURL = ((mbchar*)aUrl);
   2357     OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpURL = ((mbchar*)aUrl);
   2358 
   2359     mbchar *server_ip_ptr = OSCL_CONST_CAST(mbchar*, oscl_strstr(((mbchar*)tmpURL.get_cstr()), "//"));
   2360     if (server_ip_ptr == NULL)
   2361     {
   2362         return false;
   2363     }
   2364 
   2365     server_ip_ptr += 2;
   2366 
   2367     /* Locate the server name. */
   2368     /* URL spec: proto://[user[:pass]@]server[:port][[/path/to]/resource] */
   2369     mbchar *server_port_ptr = OSCL_CONST_CAST(mbchar*, oscl_strstr(server_ip_ptr, ":"));
   2370     mbchar *clip_name = OSCL_CONST_CAST(mbchar*, oscl_strstr(server_ip_ptr, "/"));
   2371     mbchar *at_ptr = OSCL_CONST_CAST(mbchar*, oscl_strstr(server_ip_ptr, "@"));
   2372     if (at_ptr > server_port_ptr &&                 // "@" is found
   2373         (!clip_name ||                              // no "/" is found
   2374          at_ptr < clip_name)) {                     // both "@" and "/" are found
   2375         // We just found :pass, not :port; search for :port after :pass
   2376         server_port_ptr = OSCL_CONST_CAST(mbchar*, oscl_strstr(at_ptr, ":"));
   2377     }
   2378     if (clip_name != NULL)
   2379     {
   2380         *clip_name++ = '\0';
   2381         if (clip_name <= server_port_ptr) {
   2382             server_port_ptr = NULL;  // ":" comes after "/", thus do not specify the port number
   2383         }
   2384     }
   2385 
   2386     /* Locate the port number if provided. */
   2387     iSessionInfo.iSrvAdd.port = (iSessionInfo.iStreamingType == PVRTSP_RM_HTTP) ? DEFAULT_HTTP_PORT : DEFAULT_RTSP_PORT;
   2388     if ((server_port_ptr != NULL)  && (*(server_port_ptr + 1) != '/'))
   2389     {
   2390         *(server_port_ptr++) = '\0';
   2391         uint32 atoi_tmp;
   2392         if (PV_atoi(server_port_ptr, 'd', atoi_tmp))
   2393         {
   2394             iSessionInfo.iSrvAdd.port = atoi_tmp;
   2395         }
   2396     }
   2397 
   2398     OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpServerName(server_ip_ptr, oscl_strlen(server_ip_ptr));
   2399     iSessionInfo.iServerName = tmpServerName;
   2400 
   2401 //iSessionInfo.iSrvAdd.port = 20080;
   2402 //iSessionInfo.iServerName = "172.16.2.42";
   2403 
   2404     return true;
   2405 }
   2406 
   2407 PVMFStatus
   2408 PVRTSPEngineNode::composeOptionsRequest(RTSPOutgoingMessage &iMsg)
   2409 {
   2410     iMsg.reset();
   2411 
   2412     iMsg.numOfTransportEntries = 0;
   2413     iMsg.msgType = RTSPRequestMsg;
   2414     iMsg.method = METHOD_OPTIONS;
   2415     iMsg.originalURI.setPtrLen(iSessionInfo.iSessionURL.get_cstr(), iSessionInfo.iSessionURL.get_size());
   2416     iMsg.cseq = iOutgoingSeq++;
   2417     iMsg.cseqIsSet = true;
   2418     iMsg.acceptIsSet = false;
   2419     iMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
   2420     iMsg.userAgentIsSet = true;
   2421 
   2422     {
   2423         // setup parameters for the options command. this is necessary
   2424         // for real rdt support.
   2425         StrCSumPtrLen ClientChallenge = _STRLIT_CHAR("ClientChallenge");
   2426         OSCL_HeapString<PVRTSPEngineNodeAllocator> ClientChallenge_Val("9e26d33f2984236010ef6253fb1887f7");
   2427         iMsg.addField(&ClientChallenge, ClientChallenge_Val.get_cstr());
   2428 
   2429         StrCSumPtrLen PlayerStarttime = _STRLIT_CHAR("PlayerStarttime");
   2430         OSCL_HeapString<PVRTSPEngineNodeAllocator> PlayerStarttime_Val("[28/03/2003:22:50:23 00:00]");
   2431         iMsg.addField(&PlayerStarttime, PlayerStarttime_Val.get_cstr());
   2432 
   2433         StrCSumPtrLen CompanyID = _STRLIT_CHAR("CompanyID");
   2434         OSCL_HeapString<PVRTSPEngineNodeAllocator> CompanyID_Val("KnKV4M4I/B2FjJ1TToLycw==");
   2435         iMsg.addField(&CompanyID, CompanyID_Val.get_cstr());
   2436 
   2437         StrCSumPtrLen playerGuid = _STRLIT_CHAR("GUID");
   2438         OSCL_StackString<64> playerGuidVal = _STRLIT_CHAR("00000000-0000-0000-0000-000000000000");
   2439         iMsg.addField(&playerGuid, playerGuidVal.get_cstr());
   2440     }
   2441 
   2442     if (iMsg.compose() == false)
   2443     {
   2444         return PVMFFailure;
   2445     }
   2446     else
   2447     {
   2448         return PVMFSuccess;
   2449     }
   2450 }
   2451 
   2452 /*
   2453 * Function : int composeDescribeRequest()
   2454 * Date      : 09/13/2002
   2455 * Purpose  : Composes RTSP DESCRIBE request
   2456 * In/out   :
   2457 * Return   :
   2458 * Modified :
   2459 */
   2460 PVMFStatus
   2461 PVRTSPEngineNode::composeDescribeRequest(RTSPOutgoingMessage &iMsg)
   2462 {
   2463     iMsg.reset();
   2464     iMsg.numOfTransportEntries = 0;
   2465     iMsg.msgType = RTSPRequestMsg;
   2466     iMsg.method = METHOD_DESCRIBE;
   2467     iMsg.originalURI.setPtrLen(iSessionInfo.iSessionURL.get_cstr(), iSessionInfo.iSessionURL.get_size());
   2468     iMsg.cseq = iOutgoingSeq++;
   2469     iMsg.cseqIsSet = true;
   2470     iMsg.accept = "application/sdp";
   2471     iMsg.acceptIsSet = true;
   2472     iMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
   2473     iMsg.userAgentIsSet = true;
   2474 
   2475     if (oscl_strlen(iSessionInfo.iUserNetwork.get_cstr()))
   2476     {
   2477         StrCSumPtrLen UserNetwork = _STRLIT_CHAR("User-Network");
   2478         iMsg.addField(&UserNetwork, iSessionInfo.iUserNetwork.get_cstr());
   2479     }
   2480     if (oscl_strlen(iSessionInfo.iDeviceInfo.get_cstr()))
   2481     {
   2482         StrCSumPtrLen DeviceInfo = _STRLIT_CHAR("DeviceInfo");
   2483         iMsg.addField(&DeviceInfo, iSessionInfo.iDeviceInfo.get_cstr());
   2484     }
   2485     if (oscl_strlen(iSessionInfo.iUserID.get_cstr()) && oscl_strlen(iSessionInfo.iAuthentication.get_cstr()))
   2486     {
   2487         OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("user=");
   2488         myBuf += iSessionInfo.iUserID.get_cstr();
   2489         myBuf += ";authentication=";
   2490         myBuf += iSessionInfo.iAuthentication.get_cstr();
   2491 
   2492         StrCSumPtrLen User_id = _STRLIT_CHAR("ID");
   2493         iMsg.addField(&User_id, myBuf.get_cstr());
   2494     }
   2495     if (oscl_strlen(iSessionInfo.iExpiration.get_cstr()))
   2496     {
   2497         StrCSumPtrLen Expiration = _STRLIT_CHAR("Expiration");
   2498         iMsg.addField(&Expiration, iSessionInfo.iExpiration.get_cstr());
   2499     }
   2500     if (oscl_strlen(iSessionInfo.iApplicationSpecificString.get_cstr()))
   2501     {
   2502         StrCSumPtrLen Application_specific_string = _STRLIT_CHAR("Application-Specific-String");
   2503         iMsg.addField(&Application_specific_string, iSessionInfo.iApplicationSpecificString.get_cstr());
   2504     }
   2505 
   2506     if (iSessionInfo.iVerification.get_size() && iSessionInfo.iSignature.get_size())
   2507     {
   2508         OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("filler=");
   2509         myBuf += iSessionInfo.iVerification.get_cstr();
   2510         myBuf += ";signature=";
   2511         myBuf += iSessionInfo.iSignature.get_cstr();
   2512 
   2513         StrCSumPtrLen Verification = _STRLIT_CHAR("Verification");
   2514         iMsg.addField(&Verification, myBuf.get_cstr());
   2515     }
   2516 
   2517     {//If the Accept-Encoding field-value is empty, then only the "identity"
   2518         // encoding is acceptable.
   2519         StrCSumPtrLen AcceptEncoding = _STRLIT_CHAR("Accept-Encoding");
   2520         iMsg.addField(&AcceptEncoding, "");
   2521     }
   2522 
   2523     if (iMsg.compose() == false)
   2524     {
   2525         return PVMFFailure;
   2526     }
   2527 
   2528     iSessionInfo.clientServerDelay = 0;
   2529     uint32 clock = 0;
   2530     bool overflowFlag = false;
   2531     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
   2532     iSessionInfo.clientServerDelay = clock;
   2533 
   2534     //iSessionInfo.composedMessage = iMsg.retrieveComposedBuffer();
   2535     return PVMFSuccess;
   2536 }
   2537 
   2538 PVMFStatus PVRTSPEngineNode::processServerRequest(RTSPIncomingMessage &aMsg)
   2539 {//input: server request in aMsg;
   2540     //just send the response. bingo.
   2541     //all S->C are optional, including ANNOUNCE, GET_PARAMETER, SET_PARAMETER, OPTIONS
   2542     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::processServerRequest() In"));
   2543 
   2544     if (iSrvResponse == NULL)
   2545     {
   2546         iSrvResponse =  OSCL_NEW(RTSPOutgoingMessage, ());
   2547         if (iSrvResponse == NULL)
   2548         {
   2549             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   2550             return  PVMFFailure;
   2551         }
   2552     }
   2553 
   2554     iSrvResponse->reset();
   2555     iSrvResponse->msgType = RTSPResponseMsg;
   2556     iSrvResponse->numOfTransportEntries = 0;
   2557 
   2558     if (aMsg.method == METHOD_END_OF_STREAM)
   2559     {//
   2560         iSrvResponse->statusCode =  CodeOK;
   2561         iSrvResponse->reasonString = "OK";
   2562         ReportInfoEvent(PVMFInfoEndOfData);
   2563     }
   2564     else if (aMsg.method == METHOD_SET_PARAMETER)
   2565     {//
   2566         iSrvResponse->statusCode =  CodeOK;
   2567         iSrvResponse->reasonString = "OK";
   2568     }
   2569     else
   2570     {
   2571         iSrvResponse->statusCode =  CodeNotImplemented;
   2572         iSrvResponse->reasonString = "Not Implemented";
   2573     }
   2574     //iSrvResponse->statusCode = CodeParameterNotUnderstood;
   2575     //iSrvResponse->reasonString = "Parameter Not Understood";
   2576     iSrvResponse->cseq = aMsg.cseq;
   2577     iSrvResponse->cseqIsSet = true;
   2578 
   2579     if (iSessionInfo.iSID.get_size())
   2580     {
   2581         iSrvResponse->sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
   2582         iSrvResponse->sessionIdIsSet = true;
   2583     }
   2584     if (iSrvResponse->compose() == false)
   2585     {
   2586         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPCompose501ResponseError;
   2587         OSCL_DELETE(iSrvResponse);
   2588         iSrvResponse = NULL;
   2589         return PVMFFailure;
   2590     }
   2591 
   2592     if (bNoSendPending)// bSrvRespPending
   2593     {
   2594         if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *iSrvResponse))
   2595         {
   2596             /* need to pop the msg based on cseq, NOT necessarily the early ones,
   2597             although YES in this case.
   2598             //for(int idx=0; idx < iSessionInfo.trackSelectionList->getNumTracks(); idx++ )
   2599             for(int idx=0; idx < iSessionInfo.iSDPinfo->getNumMediaObjects(); idx++ )
   2600             {
   2601             //iOutgoingMsgQueue.pop();
   2602             }
   2603                 */
   2604             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   2605             OSCL_DELETE(iSrvResponse);
   2606             iSrvResponse = NULL;
   2607             return  PVMFFailure;
   2608         }
   2609 
   2610         bNoSendPending = false;
   2611     }
   2612     else
   2613     {
   2614         bSrvRespPending = true;
   2615     }
   2616 
   2617     return PVMFSuccess;
   2618 }
   2619 
   2620 /**
   2621 * This API processes server requests with entity bodies.
   2622 *
   2623 * @param aMsg The server request.
   2624 * @param aEntityMemFrag The oscl memory fragment which holds the entity body.
   2625 * @returns PVMF status.
   2626 */
   2627 PVMFStatus PVRTSPEngineNode::processEntityBody(RTSPIncomingMessage &aMsg, OsclMemoryFragment &aEntityMemFrag)
   2628 {   //all S->C are optional, including ANNOUNCE, GET_PARAMETER, SET_PARAMETER, OPTIONS
   2629     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::processEntityBody() In"));
   2630 
   2631     if (iEntityMemFrag.ptr == NULL)
   2632     {//the entity body hasn't come yet.
   2633         //return PVMFFailure;
   2634         return PVMFPending;
   2635     }
   2636 
   2637     if (iSrvResponse == NULL)
   2638     {
   2639         iSrvResponse =  OSCL_NEW(RTSPOutgoingMessage, ());
   2640         if (iSrvResponse == NULL)
   2641         {
   2642             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   2643             return  PVMFFailure;
   2644         }
   2645     }
   2646 
   2647     iSrvResponse->reset();
   2648     iSrvResponse->msgType = RTSPResponseMsg;
   2649     iSrvResponse->numOfTransportEntries = 0;
   2650 
   2651     if (aMsg.method == METHOD_SET_PARAMETER)
   2652     {//
   2653         iSrvResponse->statusCode =  CodeOK;
   2654         iSrvResponse->reasonString = "OK";
   2655     }
   2656     else
   2657     {
   2658         iSrvResponse->statusCode =  CodeNotImplemented;
   2659         iSrvResponse->reasonString = "Not Implemented";
   2660     }
   2661     //iSrvResponse->statusCode = CodeParameterNotUnderstood;
   2662     //iSrvResponse->reasonString = "Parameter Not Understood";
   2663     iSrvResponse->cseq = aMsg.cseq;
   2664     iSrvResponse->cseqIsSet = true;
   2665 
   2666     if (iSessionInfo.iSID.get_size())
   2667     {
   2668         iSrvResponse->sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
   2669         iSrvResponse->sessionIdIsSet = true;
   2670     }
   2671     if (iSrvResponse->compose() == false)
   2672     {
   2673         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPCompose501ResponseError;
   2674         OSCL_DELETE(iSrvResponse);
   2675         iSrvResponse = NULL;
   2676         return PVMFFailure;
   2677     }
   2678 
   2679     if (bNoSendPending)// bSrvRespPending
   2680     {
   2681         if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *iSrvResponse))
   2682         {
   2683             /* need to pop the msg based on cseq, NOT necessarily the early ones,
   2684             although YES in this case.
   2685             //for(int idx=0; idx < iSessionInfo.trackSelectionList->getNumTracks(); idx++ )
   2686             for(int idx=0; idx < iSessionInfo.iSDPinfo->getNumMediaObjects(); idx++ )
   2687             {
   2688             //iOutgoingMsgQueue.pop();
   2689             }
   2690                 */
   2691             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   2692             OSCL_DELETE(iSrvResponse);
   2693             iSrvResponse = NULL;
   2694             return  PVMFFailure;
   2695         }
   2696 
   2697         bNoSendPending = false;
   2698     }
   2699     else
   2700     {
   2701         bSrvRespPending = true;
   2702     }
   2703 
   2704     PVMFStatus tmpRet = PVMFSuccess;
   2705     OSCL_UNUSED_ARG(aEntityMemFrag);
   2706     return tmpRet;
   2707 }
   2708 
   2709 
   2710 PVMFStatus PVRTSPEngineNode::DoStartNode(PVRTSPEngineCommand &aCmd)
   2711 {
   2712     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoStartNode() In"));
   2713     OSCL_UNUSED_ARG(aCmd);
   2714 
   2715     //If session is completed, then do not send the play command to the server..
   2716     if (IsSessionCompleted() && !bRepositioning)
   2717     {
   2718         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoStartNode() Skipping sending play 'cos of session expiry"));
   2719         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
   2720         return PVMFSuccess;
   2721     }
   2722 
   2723     if (iInterfaceState != EPVMFNodePrepared &&
   2724             iInterfaceState != EPVMFNodePaused)
   2725     {
   2726         return PVMFErrInvalidState;
   2727     }
   2728 
   2729     return  SendRtspPlay(aCmd);
   2730 }
   2731 
   2732 PVMFStatus PVRTSPEngineNode::SendRtspPlay(PVRTSPEngineCommand &aCmd)
   2733 {
   2734     OSCL_UNUSED_ARG(aCmd);
   2735 
   2736     PVMFStatus iRet = PVMFPending;
   2737     switch (iState)
   2738     {
   2739         case PVRTSP_ENGINE_NODE_STATE_SETUP_DONE:
   2740         case PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE:
   2741         {
   2742             if (!bNoSendPending)
   2743             {
   2744                 break;
   2745             }
   2746             //compose and send PLAY
   2747             //if ASF streaming, the SET_PARAMETER should be pipelined as well
   2748             RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
   2749             if (tmpOutgoingMsg == NULL)
   2750             {
   2751                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   2752                 iRet =  PVMFFailure;
   2753                 break;
   2754             }
   2755             if (PVMFSuccess != composePlayRequest(*tmpOutgoingMsg))
   2756             {
   2757                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposePlayRequestError;
   2758                 OSCL_DELETE(tmpOutgoingMsg);
   2759                 iRet =  PVMFFailure;
   2760                 break;
   2761             }
   2762 
   2763             if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
   2764             {
   2765                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   2766                 OSCL_DELETE(tmpOutgoingMsg);
   2767                 iRet =  PVMFFailure;
   2768                 break;
   2769             }
   2770 
   2771             bNoSendPending = false;
   2772             iOutgoingMsgQueue.push(tmpOutgoingMsg);
   2773 
   2774             ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_PLAY);
   2775             //setup the watch dog for server response
   2776             iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG);
   2777             RunIfNotReady();
   2778             break;
   2779         }
   2780         case PVRTSP_ENGINE_NODE_STATE_WAIT_PLAY:
   2781         {
   2782             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
   2783             {
   2784                 iRet = processIncomingMessage(iIncomingMsg);
   2785                 if (iRet != PVMFPending)
   2786                 {
   2787                     //cancell the watchdog
   2788                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2789                     if (iRet == PVMFSuccess)
   2790                     {
   2791                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
   2792                     }
   2793                 }
   2794             }
   2795             else if (RTSPParser::ENTITY_BODY_IS_READY == iRTSPParserState)
   2796             {//got MS TCP RTP packets
   2797                 //processSDP(REINTERPRET_CAST(mbchar*, pSDPBuf.ptr), pSDPBuf.len-1);
   2798                 //processSDP((mbchar*)pSDPBuf.ptr, pSDPBuf.len-1);
   2799                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_DESCRIBE_DONE);
   2800                 iRet = processIncomingMessage(iIncomingMsg);
   2801                 if (iRet != PVMFPending)
   2802                 {
   2803                     //cancell the watchdog
   2804                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2805                     if (iRet == PVMFSuccess)
   2806                     {
   2807                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
   2808                     }
   2809                 }
   2810             }
   2811             else if (!clearEventQueue())
   2812             {
   2813                 //cancell the watchdog
   2814                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   2815 
   2816                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketError;
   2817                 iRet =  PVMFFailure;
   2818             }
   2819             break;
   2820         }
   2821 
   2822         default:
   2823         {
   2824             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::SendRtspPlay() iState=%d Line %d", iState, __LINE__));
   2825             iRet = PVMFErrInvalidState;
   2826             break;
   2827         }
   2828     }
   2829 
   2830     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspPlay() Out"));
   2831     return iRet;
   2832 }
   2833 
   2834 PVMFStatus PVRTSPEngineNode::composeSetupRequest(RTSPOutgoingMessage &iMsg, StreamInfo &aSelected)
   2835 {
   2836     //Reset the data structure
   2837     iMsg.reset();
   2838 
   2839     if (iSessionInfo.iSDPinfo.GetRep() == NULL) return PVMFFailure;
   2840 
   2841     //Here we decide if the selected track is a still image or not
   2842     mediaInfo *tmpMediaInfo = iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(aSelected.iSDPStreamId);
   2843     if (NULL == tmpMediaInfo)
   2844     {
   2845         return PVMFFailure;
   2846     }
   2847     StrCSumPtrLen still_image = "X-MP4V-IMAGE";
   2848     if (!oscl_strncmp(tmpMediaInfo->getMIMEType(), still_image.c_str(), still_image.length()))
   2849     {
   2850         StrPtrLen contentType = "text/parameters";
   2851         StrCSumPtrLen image = "Image\r\n";
   2852 
   2853         iMsg.contentType = contentType;
   2854         iMsg.contentTypeIsSet = true;
   2855         iMsg.contentLength = image.length();
   2856         iMsg.contentLengthIsSet = true;
   2857         iMsg.accept = "X-MP4V-IMAGE";
   2858         iMsg.acceptIsSet = true;
   2859         iMsg.method = METHOD_GET_PARAMETER;
   2860         iMsg.numOfTransportEntries = 0;
   2861 
   2862         /*
   2863         mbchar mediaURL[RTSP_MAX_FULL_REQUEST_SIZE];
   2864         mediaURL[0] = '\0';
   2865 
   2866           oscl_strncpy( mediaURL,
   2867           ( iSessionInfo.contentBaseFlag )? iSessionInfo.contentBaseURL:requestURL,
   2868           oscl_strlen(( iSessionInfo.contentBaseFlag )? iSessionInfo.contentBaseURL:requestURL) );
   2869           mediaURL[oscl_strlen(( iSessionInfo.contentBaseFlag )? iSessionInfo.contentBaseURL:requestURL)] = '\0';
   2870           iMsg.originalURI = mediaURL;
   2871         */
   2872     }
   2873     else
   2874     {
   2875         //Set standard fields
   2876         iMsg.method = METHOD_SETUP;
   2877         iMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
   2878         iMsg.userAgentIsSet = true;
   2879 
   2880         {
   2881             iMsg.numOfTransportEntries = 1;
   2882             iMsg.transport[0].protocol = RtspTransport::RTP_PROTOCOL;
   2883             iMsg.transport[0].protocolIsSet = true;
   2884             iMsg.transport[0].profile = RtspTransport::AVP_PROFILE;
   2885             iMsg.transport[0].profileIsSet = true;
   2886             iMsg.transport[0].delivery = RtspTransport::UNICAST_DELIVERY;
   2887             iMsg.transport[0].deliveryIsSet = true;
   2888             if ((iSessionInfo.iStreamingType == PVRTSP_3GPP_UDP)
   2889                     || (iSessionInfo.iStreamingType == PVRTSP_MS_UDP))
   2890             {
   2891                 iMsg.transport[0].transportType = RtspTransport::UDP_TRANSPORT;
   2892                 iMsg.transport[0].transportTypeIsSet = true;
   2893 
   2894                 iMsg.transport[0].channelIsSet = false;
   2895 
   2896                 iMsg.transport[0].client_portIsSet = true;
   2897                 iMsg.transport[0].client_port1 = OSCL_STATIC_CAST(uint16, aSelected.iCliRTPPort);   //dataPort;
   2898                 iMsg.transport[0].client_port2 = OSCL_STATIC_CAST(uint16, aSelected.iCliRTCPPort);  //feedbackPort;
   2899 
   2900                 if (iSessionInfo.iStreamingType == PVRTSP_MS_UDP)
   2901                 {//check here!
   2902                     iMsg.transport[0].client_port2 = 0;
   2903                 }
   2904 
   2905                 /* Send recommended block size of RTP packet to the server.  CJ 09/10/2001 */
   2906                 StrCSumPtrLen blockSize = "Blocksize";
   2907                 oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr), iRTSPEngTmpBuf.len, "%d", RECOMMENDED_RTP_BLOCK_SIZE);
   2908                 iMsg.addField(&blockSize, ((mbchar*)iRTSPEngTmpBuf.ptr));
   2909             }
   2910             else
   2911             {
   2912                 iMsg.transport[0].transportType = RtspTransport::TCP_TRANSPORT;
   2913                 iMsg.transport[0].transportTypeIsSet = true;
   2914 
   2915                 iMsg.transport[0].client_portIsSet = false;
   2916 
   2917                 iMsg.transport[0].channelIsSet = false;
   2918                 //iMsg.transport[0].channel1 = 8888;//aSelected.iSerRTPPort;
   2919                 //iMsg.transport[0].channel2 = 9999;//aSelected.iSerRTCPPort;
   2920             }
   2921 
   2922             iMsg.transport[0].appendIsSet = false;
   2923             iMsg.transport[0].layersIsSet = false;
   2924             iMsg.transport[0].modeIsSet = false;
   2925             iMsg.transport[0].portIsSet = false;
   2926             iMsg.transport[0].server_portIsSet = false;
   2927             iMsg.transport[0].ttlIsSet = false;
   2928             iMsg.transport[0].ssrcIsSet = false;
   2929         }
   2930 
   2931         {/*
   2932             StrCSumPtrLen mytransport = "Transport";
   2933             iMsg.addField(&mytransport, "x-real-rdt/udp;client_port=6970");
   2934             iMsg.numOfTransportEntries = 0;
   2935             */
   2936         }
   2937         //Compose etag
   2938         if (oscl_strlen((iSessionInfo.iSDPinfo->getSessionInfo())->getETag()) != 0)
   2939         {
   2940             if (oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr), iRTSPEngTmpBuf.len, "\"%s\"", (iSessionInfo.iSDPinfo->getSessionInfo())->getETag()) != 1)
   2941             {
   2942                 StrCSumPtrLen etag = "If-Match";
   2943                 iMsg.addField(&etag, ((mbchar*)iRTSPEngTmpBuf.ptr));
   2944             }
   2945         }
   2946 
   2947         if (oscl_strlen(iSessionInfo.iUserNetwork.get_cstr()))
   2948         {
   2949             StrCSumPtrLen UserNetwork = _STRLIT_CHAR("User-Network");
   2950             iMsg.addField(&UserNetwork, iSessionInfo.iUserNetwork.get_cstr());
   2951         }
   2952         if (oscl_strlen(iSessionInfo.iDeviceInfo.get_cstr()))
   2953         {
   2954             StrCSumPtrLen DeviceInfo = _STRLIT_CHAR("DeviceInfo");
   2955             iMsg.addField(&DeviceInfo, iSessionInfo.iDeviceInfo.get_cstr());
   2956         }
   2957         if (oscl_strlen(iSessionInfo.iUserID.get_cstr()) && oscl_strlen(iSessionInfo.iAuthentication.get_cstr()))
   2958         {
   2959             OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("user=");
   2960             myBuf += iSessionInfo.iUserID.get_cstr();
   2961             myBuf += ";authentication=";
   2962             myBuf += iSessionInfo.iAuthentication.get_cstr();
   2963 
   2964             StrCSumPtrLen User_id = _STRLIT_CHAR("ID");
   2965             iMsg.addField(&User_id, myBuf.get_cstr());
   2966         }
   2967         if (oscl_strlen(iSessionInfo.iExpiration.get_cstr()))
   2968         {
   2969             StrCSumPtrLen Expiration = _STRLIT_CHAR("Expiration");
   2970             iMsg.addField(&Expiration, iSessionInfo.iExpiration.get_cstr());
   2971         }
   2972         if (oscl_strlen(iSessionInfo.iApplicationSpecificString.get_cstr()))
   2973         {
   2974             StrCSumPtrLen Application_specific_string = _STRLIT_CHAR("Application-Specific-String");
   2975             iMsg.addField(&Application_specific_string, iSessionInfo.iApplicationSpecificString.get_cstr());
   2976         }
   2977         if (iSessionInfo.iVerification.get_size() && iSessionInfo.iSignature.get_size())
   2978         {
   2979             OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("filler=");
   2980             myBuf += iSessionInfo.iVerification.get_cstr();
   2981             myBuf += ";signature=";
   2982             myBuf += iSessionInfo.iSignature.get_cstr();
   2983 
   2984             StrCSumPtrLen Verification = _STRLIT_CHAR("Verification");
   2985             iMsg.addField(&Verification, myBuf.get_cstr());
   2986         }
   2987 
   2988         //Compose the media level URL for use in a RTSP request message.
   2989         if (composeMediaURL(aSelected.iSDPStreamId, iMsg.originalURI) != PVMFSuccess)
   2990         {
   2991             return PVMFFailure;
   2992         }
   2993         aSelected.iMediaURI = iMsg.originalURI.c_str();
   2994 
   2995         if (aSelected.b3gppAdaptationIsSet)
   2996         {// 3GPP release-6 rate adaptation
   2997             mbchar buffer[256];
   2998 
   2999             OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("url=\"");
   3000             myBuf += iMsg.originalURI.c_str();
   3001             myBuf += "\";size=";
   3002             oscl_snprintf(buffer, 256, "%d", aSelected.iBufSize);
   3003             myBuf += buffer;
   3004             myBuf += ";target-time=";
   3005             oscl_snprintf(buffer, 256, "%d", aSelected.iTargetTime);
   3006             myBuf += buffer;
   3007 
   3008             StrCSumPtrLen _3GPPadaptation = "3GPP-Adaptation";
   3009             iMsg.addField(&_3GPPadaptation, myBuf.get_str());
   3010         }
   3011     }
   3012 
   3013     iMsg.msgType = RTSPRequestMsg;
   3014     iMsg.cseq = iOutgoingSeq++;
   3015     iMsg.cseqIsSet = true;
   3016 
   3017     //OSCL_StackString<32> tmpSID = _STRLIT_CHAR("d5ac74e39ac8d75f");
   3018     //iSessionInfo.iSID.set(tmpSID.get_cstr(), tmpSID.get_size());
   3019 
   3020     if (iSessionInfo.iSID.get_size())
   3021     {
   3022         iMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
   3023         iMsg.sessionIdIsSet = true;
   3024     }
   3025 
   3026     if (iMsg.compose() == false)
   3027     {
   3028         return PVMFFailure;
   3029     }
   3030 
   3031     iSessionInfo.clientServerDelay = 0;
   3032     uint32 clock = 0;
   3033     bool overflowFlag = false;
   3034     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
   3035     iSessionInfo.clientServerDelay = clock;
   3036 
   3037     return PVMFSuccess;
   3038 }
   3039 
   3040 PVMFStatus PVRTSPEngineNode::composePlayRequest(RTSPOutgoingMessage &aMsg)
   3041 {
   3042     aMsg.reset();
   3043     aMsg.numOfTransportEntries = 0;
   3044     aMsg.msgType = RTSPRequestMsg;
   3045     aMsg.method = METHOD_PLAY;
   3046     aMsg.cseq = iOutgoingSeq++;
   3047     aMsg.cseqIsSet = true;
   3048 
   3049     if (iSessionInfo.iSID.get_size())
   3050     {
   3051         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
   3052         aMsg.sessionIdIsSet = true;
   3053     }
   3054 
   3055     //Add range field only if it is a PLAY request
   3056     //if( (iState != EResumeSession) && (!upstreamClient) )
   3057     if ((iState != PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE)
   3058             || (bRepositioning)
   3059             || (iInterfaceState == EPVMFNodePrepared))
   3060         //if( iState == PVRTSP_ENGINE_NODE_STATE_SETUP_DONE )
   3061     {
   3062         bRepositioning = false;
   3063         OSCL_StackString<8> npt = _STRLIT_CHAR("npt=");
   3064         oscl_strncpy(((mbchar*)iRTSPEngTmpBuf.ptr), npt.get_cstr(), npt.get_size());
   3065         ((mbchar*)iRTSPEngTmpBuf.ptr)[npt.get_size()] = '\0';
   3066 
   3067         if (iSessionInfo.iReqPlayRange.format == RtspRangeType::NPT_RANGE)
   3068         {
   3069             if (iSessionInfo.iReqPlayRange.start_is_set == true)
   3070             {
   3071                 if (iSessionInfo.iReqPlayRange.npt_start.npt_format == NptTimeFormat::NPT_SEC)
   3072                 {
   3073                     oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr) + oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)), \
   3074                                   (64 - oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr))), "%d.%03d-", \
   3075                                   iSessionInfo.iReqPlayRange.npt_start.npt_sec.sec, iSessionInfo.iReqPlayRange.npt_start.npt_sec.milli_sec);
   3076                 }
   3077                 else if (iSessionInfo.iReqPlayRange.npt_start.npt_format == NptTimeFormat::NOW)
   3078                 {
   3079                     oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr) + oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)), \
   3080                                   (64 - oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr))), "now-");
   3081                 }
   3082                 else
   3083                 {
   3084                     return PVMFFailure;
   3085                 }
   3086             }
   3087 
   3088             if (iSessionInfo.iReqPlayRange.end_is_set == true)
   3089             {
   3090                 if (iSessionInfo.iReqPlayRange.npt_end.npt_format == NptTimeFormat::NPT_SEC)
   3091                 {
   3092                     if ((iSessionInfo.iReqPlayRange.npt_end.npt_sec.sec != 0)
   3093                             || (iSessionInfo.iReqPlayRange.npt_end.npt_sec.milli_sec != 0))
   3094                     {
   3095                         oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr) + oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)), \
   3096                                       (64 - oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr))), "%d.%03d", \
   3097                                       iSessionInfo.iReqPlayRange.npt_end.npt_sec.sec, iSessionInfo.iReqPlayRange.npt_end.npt_sec.milli_sec);
   3098                     }
   3099                 }
   3100                 else
   3101                 {
   3102                     return PVMFFailure;
   3103                 }
   3104             }
   3105 
   3106             StrCSumPtrLen Range = _STRLIT_CHAR("Range");
   3107             aMsg.addField(&Range, ((mbchar*)iRTSPEngTmpBuf.ptr));
   3108         }
   3109     }
   3110 
   3111     {//put user agent in SETUP an PLAY for testing for Real. IOT testing Jun 02, 05
   3112         aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
   3113         aMsg.userAgentIsSet = true;
   3114     }
   3115 
   3116     if (composeSessionURL(aMsg) != PVMFSuccess)
   3117     {
   3118         return PVMFFailure;
   3119     }
   3120 
   3121     if (aMsg.compose() == false)
   3122     {
   3123         return PVMFFailure;
   3124     }
   3125 
   3126     //iSessionInfo.composedMessage = aMsg.retrieveComposedBuffer();
   3127 
   3128     iSessionInfo.clientServerDelay = 0;
   3129     uint32 clock = 0;
   3130     bool overflowFlag = false;
   3131     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
   3132     iSessionInfo.clientServerDelay = clock;
   3133 
   3134     return PVMFSuccess;
   3135 }
   3136 
   3137 PVMFStatus PVRTSPEngineNode::composePauseRequest(RTSPOutgoingMessage &aMsg)
   3138 {
   3139     aMsg.reset();
   3140     aMsg.numOfTransportEntries = 0;
   3141     aMsg.msgType = RTSPRequestMsg;
   3142     aMsg.method = METHOD_PAUSE;
   3143     aMsg.cseq = iOutgoingSeq++;
   3144     aMsg.cseqIsSet = true;
   3145 
   3146     if (iSessionInfo.iSID.get_size())
   3147     {
   3148         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
   3149         aMsg.sessionIdIsSet = true;
   3150     }
   3151 
   3152     {//put user agent in SETUP an PLAY for testing for Real. IOT testing Jun 02, 05
   3153         aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
   3154         aMsg.userAgentIsSet = true;
   3155     }
   3156 
   3157     if (composeSessionURL(aMsg) != PVMFSuccess)
   3158     {
   3159         return PVMFFailure;
   3160     }
   3161 
   3162     if (aMsg.compose() == false)
   3163     {
   3164         return PVMFFailure;
   3165     }
   3166 
   3167     iSessionInfo.clientServerDelay = 0;
   3168     uint32 clock = 0;
   3169     bool overflowFlag = false;
   3170     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
   3171     iSessionInfo.clientServerDelay = clock;
   3172 
   3173     return PVMFSuccess;
   3174 }
   3175 
   3176 
   3177 PVMFStatus PVRTSPEngineNode::composeStopRequest(RTSPOutgoingMessage &aMsg)
   3178 {
   3179     aMsg.reset();
   3180     aMsg.numOfTransportEntries = 0;
   3181     aMsg.msgType = RTSPRequestMsg;
   3182     aMsg.method = METHOD_TEARDOWN;
   3183     aMsg.cseq = iOutgoingSeq++;
   3184     aMsg.cseqIsSet = true;
   3185 
   3186     aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
   3187     aMsg.userAgentIsSet = true;
   3188 
   3189     if (iSessionInfo.iSID.get_size())
   3190     {
   3191         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
   3192         aMsg.sessionIdIsSet = true;
   3193     }
   3194 
   3195     if (composeSessionURL(aMsg) != PVMFSuccess)
   3196     {
   3197         return PVMFFailure;
   3198     }
   3199 
   3200     StrCSumPtrLen connection = "Connection";
   3201     aMsg.addField(&connection, "close");
   3202 
   3203     if (aMsg.compose() == false)
   3204     {
   3205         return PVMFFailure;
   3206     }
   3207 
   3208     iSessionInfo.clientServerDelay = 0;
   3209     uint32 clock = 0;
   3210     bool overflowFlag = false;
   3211     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
   3212     iSessionInfo.clientServerDelay = clock;
   3213 
   3214     return PVMFSuccess;
   3215 }
   3216 
   3217 /*
   3218 * Function : PVMFStatus composeSessionURL()
   3219 * Date     : 10/30/2002
   3220 * Purpose  : Composing a session level URL for use in a RTSP request message.
   3221 * In/out   :
   3222 * Return   : PVMFSuccess upon succeessful composition. PVMFFailure otherwise.
   3223 * Modified :
   3224 */
   3225 PVMFStatus PVRTSPEngineNode::composeSessionURL(RTSPOutgoingMessage &aMsg)
   3226 {
   3227     OSCL_StackString<16> rtsp_str = _STRLIT_CHAR("rtsp");
   3228     const char *sdpSessionURL = (iSessionInfo.iSDPinfo->getSessionInfo())->getControlURL();
   3229     if (sdpSessionURL == NULL)
   3230     {
   3231         return PVMFFailure;
   3232     }
   3233 
   3234     //1. SDP from DESCRIBE response
   3235     if (iSessionInfo.bExternalSDP)
   3236     {
   3237         if (!oscl_strncmp(sdpSessionURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
   3238         {
   3239             aMsg.originalURI = sdpSessionURL;
   3240             return PVMFSuccess;
   3241         }
   3242         return PVMFFailure;
   3243     }
   3244     else
   3245     {
   3246         char *baseURL;
   3247         if (iSessionInfo.iContentBaseURL.get_size())
   3248         {
   3249             baseURL = iSessionInfo.iContentBaseURL.get_str();
   3250         }
   3251         else
   3252         {
   3253             baseURL = iSessionInfo.iSessionURL.get_str();
   3254         }
   3255 
   3256         //Case where control url is *
   3257         ((mbchar*)iRTSPEngTmpBuf.ptr)[0] = '\0';
   3258         uint tmpLen = iRTSPEngTmpBuf.len;
   3259         mbchar asterisk[] = {"*"};
   3260         if (!oscl_strncmp(sdpSessionURL, asterisk, oscl_strlen(asterisk)))
   3261         {
   3262             oscl_strncpy(((mbchar*)iRTSPEngTmpBuf.ptr), baseURL, oscl_strlen(baseURL));
   3263             ((mbchar*)iRTSPEngTmpBuf.ptr)[oscl_strlen(baseURL)] = '\0';
   3264 
   3265             if (((mbchar*)iRTSPEngTmpBuf.ptr)[oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)) - 1] == '/')
   3266             {
   3267                 ((mbchar*)iRTSPEngTmpBuf.ptr)[oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)) - 1] = '\0';
   3268             }
   3269             aMsg.originalURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
   3270         }
   3271         //Case where control url is absolute
   3272         else if (!oscl_strncmp(sdpSessionURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
   3273         {
   3274             aMsg.originalURI = sdpSessionURL;
   3275         }
   3276         //other cases
   3277         else if (composeURL((const char *)baseURL, sdpSessionURL, \
   3278                             ((mbchar*)iRTSPEngTmpBuf.ptr), tmpLen) == true)
   3279         {
   3280             aMsg.originalURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
   3281         }
   3282         else
   3283         {
   3284             return PVMFFailure;
   3285         }
   3286     }
   3287     return PVMFSuccess;
   3288 }
   3289 
   3290 PVMFStatus PVRTSPEngineNode::composeMediaURL(int aTrackID, StrPtrLen &aMediaURI)
   3291 {
   3292     OSCL_StackString<16> rtsp_str = _STRLIT_CHAR("rtsp");
   3293 
   3294     const char *sdpMediaURL = (iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(aTrackID))->getControlURL();
   3295     if (sdpMediaURL == NULL)
   3296     {
   3297         return PVMFFailure;
   3298     }
   3299 
   3300     if (!oscl_strncmp(sdpMediaURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
   3301     {
   3302         {
   3303             aMediaURI = sdpMediaURL;
   3304         }
   3305 
   3306     }
   3307     else
   3308     {
   3309         const char *sdpSessionURL = (iSessionInfo.iSDPinfo->getSessionInfo())->getControlURL();
   3310 
   3311         if (!oscl_strncmp(sdpSessionURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
   3312         {
   3313             ((mbchar*)iRTSPEngTmpBuf.ptr)[0] = '\0';
   3314             uint tmpLen = iRTSPEngTmpBuf.len;
   3315 
   3316             if (composeURL(sdpSessionURL, sdpMediaURL,
   3317                            ((mbchar*)iRTSPEngTmpBuf.ptr), tmpLen) != true)
   3318             {
   3319                 return PVMFFailure;
   3320             }
   3321 
   3322             aMediaURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
   3323         }
   3324         //Compose absolute URL
   3325         else
   3326         {
   3327             char *baseURL;
   3328             if (iSessionInfo.iContentBaseURL.get_size())
   3329             {
   3330                 baseURL = iSessionInfo.iContentBaseURL.get_str();
   3331             }
   3332             else
   3333             {
   3334                 baseURL = iSessionInfo.iSessionURL.get_str();
   3335             }
   3336 
   3337             {
   3338                 uint tmpLen = iRTSPEngTmpBuf.len;
   3339                 if (composeURL((const char *)baseURL,
   3340                                sdpMediaURL,
   3341                                ((mbchar*)iRTSPEngTmpBuf.ptr), tmpLen) != true)
   3342                 {
   3343                     return PVMFFailure;
   3344                 }
   3345             }
   3346             aMediaURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
   3347         }
   3348     }
   3349     return PVMFSuccess;
   3350 }
   3351 
   3352 PVMFStatus PVRTSPEngineNode::processCommonResponse(RTSPIncomingMessage &aMsg)
   3353 {
   3354     /*Parse content base - this is needed to compose URLs for future RTSP requests*/
   3355 
   3356     if (iSessionInfo.iContentBaseURL.get_size() == 0)
   3357     {
   3358         if (aMsg.contentBase.length())
   3359         {
   3360             OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpBaseURL(aMsg.contentBase.c_str(), aMsg.contentBase.length());
   3361             iSessionInfo.iContentBaseURL = tmpBaseURL;
   3362         }
   3363         else
   3364         {
   3365             const StrPtrLen *tmpBaseURLLoc = aMsg.queryField("Content-Location");
   3366             if (tmpBaseURLLoc)
   3367             {
   3368                 OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpBaseURL(tmpBaseURLLoc->c_str(), tmpBaseURLLoc->length());
   3369                 iSessionInfo.iContentBaseURL = tmpBaseURL;
   3370             }
   3371         }
   3372     }
   3373 
   3374     /*Extract session id from the server response. This is done only once per session and the following condition ensures it. */
   3375     //might need to check the SID match
   3376     if ((aMsg.sessionIdIsSet) && (iSessionInfo.iSID.get_size() == 0))
   3377     {
   3378         //because the RTSP parser just gives "d2ecb87b0816b4a;timeout=60"
   3379         char *timeout_location = OSCL_CONST_CAST(char*, oscl_strstr(aMsg.sessionId.c_str(), ";timeout"));
   3380         if (NULL != timeout_location)
   3381         {
   3382             OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpSID(aMsg.sessionId.c_str(), timeout_location - aMsg.sessionId.c_str());
   3383             iSessionInfo.iSID = tmpSID;
   3384 
   3385             //should be timeout-RTT.
   3386             int32 tmpTimeout = (aMsg.timeout - 5);
   3387             if ((TIMEOUT_KEEPALIVE > tmpTimeout) && (tmpTimeout > 0))
   3388             {
   3389                 TIMEOUT_KEEPALIVE = tmpTimeout;
   3390             }
   3391         }
   3392         else
   3393         {
   3394             OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpSID(aMsg.sessionId.c_str(), aMsg.sessionId.length());
   3395             iSessionInfo.iSID = tmpSID;
   3396         }
   3397         iSessionInfo.tSIDIsSetFlag = true;
   3398     }
   3399 
   3400     /*Parse preroll duration from server response (if available)*/
   3401     iSessionInfo.prerollDuration = 0;
   3402 
   3403     const StrPtrLen *tmpBufSize = aMsg.queryField("Buffersize");
   3404 
   3405     if (tmpBufSize != NULL)
   3406     {
   3407         //        pSessionInfo->prerollDuration = atoi( aMsg.queryField(buffer)->getPtr() );
   3408         uint32 atoi_tmp;
   3409         PV_atoi(tmpBufSize->c_str(), 'd', atoi_tmp);
   3410         iSessionInfo.prerollDuration = atoi_tmp;
   3411     }
   3412 
   3413     /*
   3414      * Check for PVServer - needed to perform firewall port remapping
   3415      */
   3416     const StrPtrLen *serverTag = aMsg.queryField("Server");
   3417     OSCL_StackString<8> pvServerTag(_STRLIT_CHAR("PVSS"));
   3418     if (serverTag != NULL)
   3419     {
   3420         uint32 minLen = OSCL_MIN((pvServerTag.get_size()), ((uint32)(serverTag->size())));
   3421         if (!oscl_strncmp(serverTag->c_str(), pvServerTag.get_cstr(), minLen))
   3422         {
   3423             iSessionInfo.pvServerIsSetFlag = true;
   3424         }
   3425         else
   3426         {
   3427             iSessionInfo.pvServerIsSetFlag = false;
   3428         }
   3429     }
   3430     /*
   3431      * Check for PVServer version number
   3432      */
   3433     if (NULL != serverTag)
   3434     {
   3435         if (iSessionInfo.pvServerIsSetFlag)
   3436         {
   3437             OSCL_StackString<8> pvServerVersionNumberLocator(_STRLIT_CHAR("/"));
   3438             const char *versionNumberLocation = oscl_strstr(serverTag->c_str(), pvServerVersionNumberLocator.get_cstr());
   3439             if (NULL != versionNumberLocation)
   3440             {
   3441                 uint32 versionNumber = 0;
   3442                 if (PV_atoi(versionNumberLocation + 1, 'd', 1, versionNumber))
   3443                 {
   3444                     iSessionInfo.iServerVersionNumber = versionNumber;
   3445                 }
   3446             }
   3447         }
   3448     }
   3449 
   3450     return PVMFSuccess;
   3451 }
   3452 
   3453 PVMFStatus PVRTSPEngineNode::processIncomingMessage(RTSPIncomingMessage &iIncomingMsg)
   3454 {
   3455     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::processIncomingMessage() in"));
   3456 
   3457     if (RTSPOk != iIncomingMsg.isMalformed())
   3458     {
   3459         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
   3460         return PVMFFailure;
   3461     }
   3462     if (RTSPRequestMsg == iIncomingMsg.msgType)
   3463     {
   3464         if (METHOD_BINARY_DATA == iIncomingMsg.method)
   3465         {//need to check the rtsp parcom
   3466             /*
   3467             iIncomingMsg.bufferSize;
   3468             iIncomingMsg.contentLength;
   3469             iIncomingMsg.fullRequestBuffer;
   3470             iIncomingMsg.fullRequestBufferSizeUsed;
   3471             */
   3472             //iIncomingMsg.reset();
   3473             return PVMFPending;
   3474         }
   3475         //PVMFStatus tmpRet = ( (iIncomingMsg.contentLengthIsSet) && (iIncomingMsg.contentLength > 0) )
   3476         PVMFStatus tmpRet = ((iIncomingMsg.contentLengthIsSet))
   3477                             ? processEntityBody(iIncomingMsg, iEntityMemFrag)
   3478                             : processServerRequest(iIncomingMsg);
   3479         return (tmpRet == PVMFSuccess) ? PVMFPending : tmpRet;
   3480     }
   3481 
   3482     if (RTSPResponseMsg != iIncomingMsg.msgType)
   3483     {
   3484         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorIncorrectRTSPMessageType;
   3485         return PVMFFailure;
   3486     }
   3487 
   3488     if (iOutgoingMsgQueue.empty())
   3489     {
   3490         //we don't expect a response at this moment.
   3491         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorUnknownRTSPMessage;
   3492         return PVMFFailure;
   3493     }
   3494 
   3495     //pop the outgoing msg queue and see the match
   3496     RTSPOutgoingMessage* tmpOutgoingMsg = iOutgoingMsgQueue.top();
   3497     if (tmpOutgoingMsg->cseqIsSet)
   3498     {
   3499         //we always send seq. But just to be sure
   3500         if (!iIncomingMsg.cseqIsSet)
   3501         {
   3502             //server should reply with seq
   3503             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMissingSeqNumInServerResponse;
   3504             return PVMFFailure;
   3505         }
   3506         if (tmpOutgoingMsg->cseq != iIncomingMsg.cseq)
   3507         {
   3508             //FIFO server messed up
   3509             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPRequestResponseMismatch;
   3510             return PVMFFailure;
   3511         }
   3512         iOutgoingMsgQueue.pop();
   3513     }
   3514     else if (tmpOutgoingMsg->method == METHOD_GET)
   3515     {//TBD varify this is the http GET response
   3516         iOutgoingMsgQueue.pop();
   3517     }
   3518 
   3519     //check session ID as well
   3520     if (200 == iIncomingMsg.statusCode)
   3521     {
   3522         //OK
   3523         processCommonResponse(iIncomingMsg);
   3524         //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_SETUP_DONE);
   3525         //break;
   3526 
   3527         if (tmpOutgoingMsg->method == METHOD_SETUP)
   3528         {
   3529             for (uint32 i = 0; i < iSessionInfo.iSelectedStream.size(); i++)
   3530             {
   3531                 if (!oscl_strncmp(tmpOutgoingMsg->originalURI.c_str(), iSessionInfo.iSelectedStream[i].iMediaURI.get_cstr(), tmpOutgoingMsg->originalURI.length()))
   3532                 {
   3533                     if (iIncomingMsg.numOfTransportEntries)
   3534                     {
   3535                         {//For transport options, we only let server choose
   3536                             //between "RTP/AVP/UDP" or "x-pn-tng/tcp"; and for "x-pn-tng/tcp",
   3537                             //we only do http cloaking. 06/03/21
   3538                             ibIsRealRDT = false;
   3539                             if ((iIncomingMsg.transport[0].protocol != RtspTransport::RTP_PROTOCOL)
   3540                                     || (iIncomingMsg.transport[0].profile != RtspTransport::AVP_PROFILE))
   3541                             {//PVMFRTSPClientEngineNodeErrorUnsupportedTransport
   3542                                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
   3543                                 return PVMFFailure;
   3544                             }
   3545                         }
   3546 
   3547                         iSessionInfo.iSelectedStream[i].ssrcIsSet = iIncomingMsg.transport[0].ssrcIsSet;
   3548                         if (iIncomingMsg.transport[0].ssrcIsSet)
   3549                         {
   3550                             iSessionInfo.iSelectedStream[i].iSSRC = iIncomingMsg.transport[0].ssrc;
   3551                         }
   3552                         if (!(iIncomingMsg.transport[0].server_portIsSet || iIncomingMsg.transport[0].channelIsSet))
   3553                         {
   3554                             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
   3555                             return PVMFFailure;
   3556                         }
   3557                         if (iIncomingMsg.transport[0].server_portIsSet)
   3558                         {
   3559                             iSessionInfo.iSelectedStream[i].iSerRTPPort = iIncomingMsg.transport[0].server_port1;   //RTP
   3560                             iSessionInfo.iSelectedStream[i].iSerRTCPPort = iIncomingMsg.transport[0].server_port2;  //RTCP
   3561                         }
   3562                         if (iIncomingMsg.transport[0].channelIsSet)
   3563                         {
   3564                             iSessionInfo.iSelectedStream[i].iSerRTPPort = iIncomingMsg.transport[0].channel1;   //RTP
   3565                             iSessionInfo.iSelectedStream[i].iSerRTCPPort = iIncomingMsg.transport[0].channel2;  //RTCP
   3566 
   3567                             //since we're here, let's set the channel id for the port as well
   3568                             for (int32 j = iPortVector.size() - 1; j >= 0; j--)
   3569                             {
   3570                                 if (((PVMFRTSPPort*)(iPortVector[j]))->iSdpTrackID == iSessionInfo.iSelectedStream[i].iSDPStreamId)
   3571                                 {
   3572                                     PVMFRTSPPort *pvPort = (PVMFRTSPPort*)(iPortVector[j]);
   3573                                     pvPort->iChannelID = (pvPort->bIsMedia)
   3574                                                          ? iSessionInfo.iSelectedStream[i].iSerRTPPort
   3575                                                          : iSessionInfo.iSelectedStream[i].iSerRTCPPort;
   3576                                     pvPort->bIsChannelIDSet = true;
   3577                                 }
   3578                             }
   3579                         }
   3580                         iSessionInfo.iSelectedStream[i].iSerIpAddr.Set(iSessionInfo.iSrvAdd.ipAddr.Str());
   3581                     }
   3582                     else
   3583                     {
   3584                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::processIncomingMessage() ERROR iIncomingMsg.numOfTransportEntries = %d Ln %d", iIncomingMsg.numOfTransportEntries, __LINE__));
   3585                         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
   3586                         return PVMFFailure;
   3587                     }
   3588                     break;
   3589                 }
   3590             }
   3591 
   3592             if (!iSessionInfo.tSIDIsSetFlag)
   3593             {
   3594                 //server does not send the session ID
   3595                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMissingSessionIdInServerResponse;
   3596                 return PVMFFailure;
   3597             }
   3598             uint32 clock = 0;
   3599             bool overflowFlag = false;
   3600             iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
   3601             clock -= (uint32)iSessionInfo.clientServerDelay;
   3602             iSessionInfo.clientServerDelay = clock;
   3603             iSessionInfo.roundTripDelay =
   3604                 Oscl_Int64_Utils::get_uint64_lower32(iSessionInfo.clientServerDelay);
   3605         }
   3606         else if (tmpOutgoingMsg->method == METHOD_PLAY)
   3607         {
   3608             if (iSessionInfo.iActPlayRange.format == RtspRangeType::INVALID_RANGE)
   3609             {//play
   3610                 iSessionInfo.iActPlayRange  = iSessionInfo.iReqPlayRange;
   3611             }
   3612 
   3613             if (iIncomingMsg.rangeIsSet)
   3614             {
   3615                 if ((iSessionInfo.iActPlayRange.format == iIncomingMsg.range.format)
   3616                         && (iIncomingMsg.range.format == RtspRangeType::NPT_RANGE))
   3617                 {
   3618                     if (iIncomingMsg.range.start_is_set)
   3619                     {
   3620                         iSessionInfo.iActPlayRange.start_is_set = true;
   3621                         iSessionInfo.iActPlayRange.npt_start    = iIncomingMsg.range.npt_start;
   3622                     }
   3623                     if (iIncomingMsg.range.end_is_set)
   3624                     {
   3625                         iSessionInfo.iActPlayRange.end_is_set = true;
   3626                         iSessionInfo.iActPlayRange.npt_end  = iIncomingMsg.range.npt_end;
   3627                     }
   3628                 }
   3629                 else
   3630                 {//the server actually changes the range format in one session
   3631                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::processIncomingMessage() ERROR iIncomingMsg.range.format = %d Ln %d", iIncomingMsg.range.format, __LINE__));
   3632                 }
   3633             }
   3634 
   3635             for (uint32 idx = 0; idx < iIncomingMsg.numOfRtpInfoEntries; idx++)
   3636             {
   3637                 RTSPRTPInfo *rtpinfo = iIncomingMsg.rtpInfo + idx;
   3638                 if (!rtpinfo->urlIsSet)
   3639                 {//error
   3640                     //break;
   3641                 }
   3642                 char *url_temp = (char *) rtpinfo->url.c_str();
   3643                 //int url_len = rtpinfo->url.length() + 1;//Added to prevent erroneous track selection.
   3644 
   3645                 for (uint32 i = 0; i < iSessionInfo.iSelectedStream.size(); i++)
   3646                 {
   3647                     int sdp_track_id = iSessionInfo.iSelectedStream[i].iSDPStreamId;
   3648                     //simplified check here.
   3649                     if (NULL == oscl_strstr((iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(sdp_track_id))->getControlURL(), url_temp))
   3650                     {
   3651                         if (NULL == oscl_strstr(url_temp, (iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(sdp_track_id))->getControlURL()))
   3652                         {
   3653                             continue;
   3654                         }
   3655                     }
   3656                     iSessionInfo.iSelectedStream[i].seqIsSet = rtpinfo->seqIsSet;
   3657                     iSessionInfo.iSelectedStream[i].seq = rtpinfo->seq;
   3658                     iSessionInfo.iSelectedStream[i].rtptimeIsSet = rtpinfo->rtptimeIsSet;
   3659                     iSessionInfo.iSelectedStream[i].rtptime = rtpinfo->rtptime;
   3660                     iSessionInfo.iSelectedStream[i].iSerIpAddr.Set(iSessionInfo.iSrvAdd.ipAddr.Str());
   3661                 }
   3662             }
   3663             uint32 clock = 0;
   3664             bool overflowFlag = false;
   3665             iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
   3666             clock -= (uint32)iSessionInfo.clientServerDelay;
   3667             iSessionInfo.clientServerDelay = clock;
   3668             iSessionInfo.roundTripDelay =
   3669                 Oscl_Int64_Utils::get_uint64_lower32(iSessionInfo.clientServerDelay);
   3670         }
   3671         else if (tmpOutgoingMsg->method == iKeepAliveMethod)
   3672         {
   3673             if ((iState == PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE) ||
   3674                     ((bKeepAliveInPlay) && (iState == PVRTSP_ENGINE_NODE_STATE_PLAY_DONE)))
   3675             {
   3676                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::processIncomingMessage() start keep-alive timer %d. Ln %d", TIMEOUT_KEEPALIVE, __LINE__));
   3677                 iWatchdogTimer->Request(REQ_TIMER_KEEPALIVE_ID, 0, TIMEOUT_KEEPALIVE);
   3678             }
   3679         }
   3680 
   3681         if (tmpOutgoingMsg)
   3682             OSCL_DELETE(tmpOutgoingMsg);
   3683     }
   3684     else if ((iIncomingMsg.statusCode >= 300) && (iIncomingMsg.statusCode < 400))
   3685     {
   3686         //redirect
   3687         int32 infocode;
   3688         MapRTSPCodeToEventCode(iIncomingMsg.statusCode, infocode);
   3689         ReportInfoEvent(PVMFInfoRemoteSourceNotification, NULL, &iEventUUID, &infocode);
   3690         OSCL_DELETE(tmpOutgoingMsg);
   3691 
   3692         const StrPtrLen *tmpBaseURLLoc = iIncomingMsg.queryField("Location");
   3693         //const StrPtrLen *tmpBaseURLLoc = iIncomingMsg.queryField("Content-Location");
   3694         if (tmpBaseURLLoc)
   3695         {
   3696             if (!parseURL(tmpBaseURLLoc->c_str()))
   3697             {
   3698                 return PVMFFailure;
   3699             }
   3700         }
   3701         else
   3702         {
   3703             return PVMFFailure;   //If Location is not present in response
   3704         }
   3705         iErrorRecoveryAttempt = iNumRedirectTrials-- ? 1 : 0;
   3706         if (iErrorRecoveryAttempt == 0)
   3707         {
   3708             iCurrentErrorCode = infocode; // Send error to application
   3709             return PVMFFailure;
   3710         }
   3711         return PVMFInfoRemoteSourceNotification;
   3712     }
   3713     else
   3714     {
   3715         if (tmpOutgoingMsg)
   3716         {
   3717             if (tmpOutgoingMsg->method == METHOD_OPTIONS)
   3718             {
   3719                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::processIncomingMessage() OPTIONS ERROR %d Line %d", iIncomingMsg.statusCode, __LINE__));
   3720                 OSCL_DELETE(tmpOutgoingMsg);
   3721                 return iOutgoingMsgQueue.empty() ? PVMFSuccess : PVMFPending;
   3722             }
   3723         }
   3724 
   3725         //error
   3726         MapRTSPCodeToEventCode(iIncomingMsg.statusCode, iCurrentErrorCode);
   3727         OSCL_DELETE(tmpOutgoingMsg);
   3728         return PVMFFailure;
   3729     }
   3730 
   3731     return iOutgoingMsgQueue.empty() ? PVMFSuccess : PVMFPending;
   3732     //return PVMFSuccess;
   3733 }
   3734 
   3735 void PVRTSPEngineNode::MapRTSPCodeToEventCode(RTSPStatusCode aStatusCode,
   3736         int32& aEventCode)
   3737 {
   3738     switch (aStatusCode)
   3739     {
   3740         case 300:
   3741             //"300"      ; Multiple Choices
   3742             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode300;
   3743             break;
   3744         case 301:
   3745             //"301"      ; Moved Permanently
   3746             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode301;
   3747             break;
   3748         case 302:
   3749             //"302"      ; Moved Temporarily
   3750             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode302;
   3751             break;
   3752         case 303:
   3753             //"303"      ; See Other
   3754             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode303;
   3755             break;
   3756         case 304:
   3757             //"304"      ; Not Modified
   3758             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode304;
   3759             break;
   3760         case 305:
   3761             //"305"      ; Use Proxy
   3762             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode305;
   3763             break;
   3764         case 400:
   3765             //"400"      ; Bad Request
   3766             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode400;
   3767             break;
   3768         case 401:
   3769             //"401"      ; Unauthorized
   3770             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode401;
   3771             break;
   3772         case 402:
   3773             //"402"      ; Payment Required
   3774             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode402;
   3775             break;
   3776         case 403:
   3777             //"403"      ; Forbidden
   3778             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode403;
   3779             break;
   3780         case 404:
   3781             //"404"      ; Not Found
   3782             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode404;
   3783             break;
   3784         case 405:
   3785             //"405"      ; Method Not Allowed
   3786             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode405;
   3787             break;
   3788         case 406:
   3789             //"406"      ; Not Acceptable
   3790             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode406;
   3791             break;
   3792         case 407:
   3793             //"407"      ; Proxy Authentication Required
   3794             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode407;
   3795             break;
   3796         case 408:
   3797             //"408"      ; Request Time-out
   3798             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode408;
   3799             break;
   3800         case 410:
   3801             //"410"      ; Gone
   3802             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode410;
   3803             break;
   3804         case 411:
   3805             //"411"      ; Length Required
   3806             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode411;
   3807             break;
   3808         case 412:
   3809             //"412"      ; Precondition Failed
   3810             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode412;
   3811             break;
   3812         case 413:
   3813             //"413"      ; Request Entity Too Large
   3814             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode413;
   3815             break;
   3816         case 414:
   3817             //"414"      ; Request-URI Too Large
   3818             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode414;
   3819             break;
   3820         case 415:
   3821             //"415"      ; Unsupported Media Type
   3822             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode415;
   3823             break;
   3824         case 451:
   3825             //"451"      ; Parameter Not Understood
   3826             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode451;
   3827             break;
   3828         case 452:
   3829             //"452"      ; Conference Not Found
   3830             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode452;
   3831             break;
   3832         case 453:
   3833             //"453"      ; Not Enough Bandwidth
   3834             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode453;
   3835             break;
   3836         case 454:
   3837             //"454"      ; Session Not Found
   3838             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode454;
   3839             break;
   3840         case 455:
   3841             //"455"      ; Method Not Valid in This State
   3842             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode455;
   3843             break;
   3844         case 456:
   3845             //"456"      ; Header Field Not Valid for Resource
   3846             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode456;
   3847             break;
   3848         case 457:
   3849             //"457"      ; Invalid Range
   3850             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode457;
   3851             break;
   3852         case 458:
   3853             //"458"      ; Parameter Is Read-Only
   3854             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode458;
   3855             break;
   3856         case 459:
   3857             //"459"      ; Aggregate operation not allowed
   3858             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode459;
   3859             break;
   3860         case 460:
   3861             //"460"      ; Only aggregate operation allowed
   3862             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode460;
   3863             break;
   3864         case 461:
   3865             //"461"      ; Unsupported transport
   3866             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode461;
   3867             break;
   3868         case 462:
   3869             //"462"      ; Destination unreachable
   3870             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode462;
   3871             break;
   3872         case 500:
   3873             //"500"      ; Internal Server Error
   3874             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode500;
   3875             break;
   3876         case 501:
   3877             //"501"      ; Not Implemented
   3878             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode501;
   3879             break;
   3880         case 502:
   3881             //"502"      ; Bad Gateway
   3882             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode502;
   3883             break;
   3884         case 503:
   3885             //"503"      ; Service Unavailable
   3886             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode503;
   3887             break;
   3888         case 504:
   3889             //"504"      ; Gateway Time-out
   3890             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode504;
   3891             break;
   3892         case 505:
   3893             //"505"      ; RTSP Version not supported
   3894             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode505;
   3895             break;
   3896         case 551:
   3897             //"551"      ; Option not supported
   3898             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode551;
   3899             break;
   3900         default:
   3901             // Unknown
   3902             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPCodeUnknown;
   3903             break;
   3904     }
   3905 }
   3906 
   3907 PVMFStatus PVRTSPEngineNode::DoPauseNode(PVRTSPEngineCommand &aCmd)
   3908 {
   3909     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoPauseNode() In"));
   3910 
   3911     //If session is completed, then do not send the pause command to the server..
   3912     if (IsSessionCompleted())
   3913     {
   3914         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoPauseNode() Skipping sending pause 'cos of session expiry"));
   3915         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
   3916         return PVMFSuccess;
   3917     }
   3918 
   3919     if (iInterfaceState != EPVMFNodeStarted)
   3920     {
   3921         return PVMFErrInvalidState;
   3922     }
   3923     return SendRtspPause(aCmd);
   3924 }
   3925 
   3926 PVMFStatus PVRTSPEngineNode::DoStopNode(PVRTSPEngineCommand &aCmd)
   3927 {
   3928     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoStopNode() In"));
   3929 
   3930     if ((iInterfaceState != EPVMFNodeStarted) && (iInterfaceState != EPVMFNodePaused))
   3931     {
   3932         if (iInterfaceState == EPVMFNodeError)
   3933         {
   3934             return PVMFSuccess;
   3935         }
   3936         return PVMFErrInvalidState;
   3937     }
   3938     return SendRtspTeardown(aCmd);
   3939 }
   3940 
   3941 PVMFStatus PVRTSPEngineNode::SendRtspPause(PVRTSPEngineCommand &aCmd)
   3942 {
   3943     OSCL_UNUSED_ARG(aCmd);
   3944 
   3945     PVMFStatus iRet = PVMFPending;
   3946     switch (iState)
   3947     {
   3948         case PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE:
   3949         {
   3950             iRet = PVMFSuccess;
   3951             break;
   3952         }
   3953         case PVRTSP_ENGINE_NODE_STATE_PLAY_DONE:
   3954         {
   3955             if (bNoSendPending)
   3956             {
   3957                 RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
   3958                 if (tmpOutgoingMsg == NULL)
   3959                 {
   3960                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   3961                     return  PVMFFailure;
   3962                 }
   3963 
   3964                 if (PVMFSuccess != composePauseRequest(*tmpOutgoingMsg))
   3965                 {
   3966                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposePauseRequestError;
   3967                     OSCL_DELETE(tmpOutgoingMsg);
   3968                     return  PVMFFailure;
   3969                 }
   3970 
   3971                 if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
   3972                 {
   3973                     /* need to pop the msg based on cseq, NOT necessarily the early ones,
   3974                     although YES in this case.
   3975                     //for(int idx=0; idx < iSessionInfo.trackSelectionList->getNumTracks(); idx++ )
   3976                     for(int idx=0; idx < iSessionInfo.iSDPinfo->getNumMediaObjects(); idx++ )
   3977                     {
   3978                     //iOutgoingMsgQueue.pop();
   3979                     }
   3980                         */
   3981                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   3982                     OSCL_DELETE(tmpOutgoingMsg);
   3983                     iRet =  PVMFFailure;
   3984                     break;
   3985                 }
   3986 
   3987                 bNoSendPending = false;
   3988                 iOutgoingMsgQueue.push(tmpOutgoingMsg);
   3989                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_PAUSE);
   3990 
   3991                 //setup the watch dog for server response
   3992                 iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG);
   3993             }
   3994             break;
   3995         }
   3996         case PVRTSP_ENGINE_NODE_STATE_WAIT_PAUSE:
   3997         {
   3998             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
   3999             {
   4000                 iRet = processIncomingMessage(iIncomingMsg);
   4001                 if (iRet != PVMFPending)
   4002                 {
   4003                     //cancell the watchdog
   4004                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   4005                     if (iRet == PVMFSuccess)
   4006                     {
   4007                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
   4008                     }
   4009                     else if ((iRet == PVMFFailure) && (iCurrentErrorCode == PVMFRTSPClientEngineNodeErrorRTSPErrorCode455))
   4010                     {//"455"      ; Method Not Valid in This State
   4011                         iRet = PVMFSuccess;
   4012                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
   4013                     }
   4014                     else
   4015                     {   //revert to previous state,
   4016                         //which means don't change to EPVMFNodeError state
   4017                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
   4018                     }
   4019                 }
   4020             }
   4021             else if (RTSPParser::ENTITY_BODY_IS_READY == iRTSPParserState)
   4022             {//got MS TCP RTP packets
   4023                 //processSDP(REINTERPRET_CAST(mbchar*, pSDPBuf.ptr), pSDPBuf.len-1);
   4024                 //processSDP((mbchar*)pSDPBuf.ptr, pSDPBuf.len-1);
   4025                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_DESCRIBE_DONE);
   4026                 iRet =  PVMFSuccess;
   4027             }
   4028             else if (!clearEventQueue())
   4029             {
   4030                 //cancell the watchdog
   4031                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   4032 
   4033                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketError;
   4034                 iRet =  PVMFFailure;
   4035             }
   4036             break;
   4037         }
   4038         default:
   4039         {
   4040             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::SendRtspPause() iState=%d Line %d", iState, __LINE__));
   4041             iRet = PVMFErrInvalidState;
   4042             break;
   4043         }
   4044     }
   4045 
   4046     return iRet;
   4047 }
   4048 
   4049 PVMFStatus PVRTSPEngineNode::DoResetNode(PVRTSPEngineCommand &aCmd)
   4050 {
   4051     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoResetNode() In"));
   4052     if (iGetPostCorrelationObject != NULL)
   4053     {
   4054         OSCL_DELETE(iGetPostCorrelationObject);
   4055         iGetPostCorrelationObject = NULL;
   4056     }
   4057     return SendRtspTeardown(aCmd);
   4058 }
   4059 
   4060 
   4061 PVMFStatus PVRTSPEngineNode::SendRtspTeardown(PVRTSPEngineCommand &aCmd)
   4062 {
   4063     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspTeardown() In"));
   4064     OSCL_UNUSED_ARG(aCmd);
   4065     /* Allow reset from any state */
   4066     PVMFStatus iRet = PVMFPending;
   4067     switch (iState)
   4068     {
   4069         case PVRTSP_ENGINE_NODE_STATE_SETUP_DONE:
   4070         case PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE:
   4071         case PVRTSP_ENGINE_NODE_STATE_PLAY_DONE:
   4072         {
   4073             if (bNoSendPending)
   4074             {
   4075                 RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
   4076                 if (tmpOutgoingMsg == NULL)
   4077                 {
   4078                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   4079                     return  PVMFFailure;
   4080                 }
   4081 
   4082                 if (PVMFSuccess != composeStopRequest(*tmpOutgoingMsg))
   4083                 {
   4084                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposeStopRequestError;
   4085                     OSCL_DELETE(tmpOutgoingMsg);
   4086                     return  PVMFFailure;
   4087                 }
   4088                 if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
   4089                 {
   4090                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   4091                     OSCL_DELETE(tmpOutgoingMsg);
   4092                     //maybe server closed the connection or some other errors
   4093                     bNoRecvPending = false; //prevent doing recv() after the TEARDOWN
   4094                     iRet = PVMFSuccess;
   4095                     ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
   4096                     break;
   4097                 }
   4098 
   4099                 //setup the watchdog for server response
   4100                 iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG_TEARDOWN);
   4101 
   4102                 bNoSendPending = false;
   4103                 iOutgoingMsgQueue.push(tmpOutgoingMsg);
   4104                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_STOP);
   4105             }
   4106             break;
   4107         }
   4108 
   4109         case PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK:
   4110             if ((iNumHostCallback + iNumConnectCallback + iNumSendCallback + iNumRecvCallback) == 0
   4111                     && resetSocket() != PVMFPending)
   4112             {
   4113                 iRet = PVMFSuccess;
   4114                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
   4115             }
   4116             break;
   4117 
   4118         case PVRTSP_ENGINE_NODE_STATE_WAIT_STOP:
   4119             if (clearEventQueue() && (RTSPParser::REQUEST_IS_READY != iRTSPParserState))
   4120             {//no error and didn't get sth, TEARDOWN response or sth else, doesn't matter
   4121                 break;
   4122             }
   4123             //just go to default to cleanup
   4124         default:
   4125         {
   4126             bNoRecvPending = false; //prevent doing recv() after the TEARDOWN
   4127             bNoSendPending = false; //prevent doing send() after the TEARDOWN
   4128 
   4129             clearOutgoingMsgQueue();
   4130             iSocketEventQueue.clear();
   4131 
   4132             PVMFStatus status = resetSocket();
   4133 
   4134             iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
   4135             iWatchdogTimer->Cancel(REQ_TIMER_KEEPALIVE_ID);
   4136             REQ_TIMER_WATCHDOG_ID = REQ_TIMER_KEEPALIVE_ID = 0;
   4137 
   4138             if ((iNumHostCallback + iNumConnectCallback + iNumSendCallback + iNumRecvCallback) == 0
   4139                     && status != PVMFPending)
   4140             {
   4141                 iRet = PVMFSuccess;
   4142                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
   4143             }
   4144             else
   4145             {
   4146                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK);
   4147             }
   4148             break;
   4149         }
   4150     }
   4151 
   4152     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspTeardown() Out"));
   4153 
   4154     return iRet;
   4155 }
   4156 
   4157 PVMFStatus PVRTSPEngineNode::DoQueryUuid(PVRTSPEngineCommand &aCmd)
   4158 {
   4159     //This node supports Query UUID from any state
   4160 
   4161     OSCL_String* mimetype;
   4162     Oscl_Vector<PVUuid, PVRTSPEngineNodeAllocator> *uuidvec;
   4163     bool exactmatch;
   4164     aCmd.PVRTSPEngineCommandBase::Parse(mimetype, uuidvec, exactmatch);
   4165 
   4166     //Try to match the input mimetype against any of
   4167     //the custom interfaces for this node
   4168     //Match against custom interface1...
   4169     if (*mimetype == PVMF_RTSPENGINENODE_CUSTOM1_MIMETYPE
   4170             //also match against base mimetypes for custom interface1,
   4171             //unless exactmatch is set.
   4172             || (!exactmatch && *mimetype == PVMF_RTSPENGINENODE_MIMETYPE)
   4173             || (!exactmatch && *mimetype == PVMF_RTSPENGINENODE_BASEMIMETYPE))
   4174     {
   4175         uuidvec->push_back(KPVRTSPEngineNodeExtensionUuid);
   4176     }
   4177 
   4178     return PVMFSuccess;
   4179 }
   4180 
   4181 PVMFStatus PVRTSPEngineNode::DoQueryInterface(PVRTSPEngineCommand &aCmd)
   4182 {
   4183     //This node supports Query Interface from any state
   4184 
   4185     PVUuid* uuid;
   4186     PVInterface** ptr;
   4187     aCmd.PVRTSPEngineCommandBase::Parse(uuid, ptr);
   4188 
   4189     if (*uuid == KPVRTSPEngineNodeExtensionUuid)
   4190     {
   4191         if (!iExtensionInterface)
   4192         {
   4193             iExtensionInterface = OSCL_NEW(PVRTSPEngineNodeExtensionInterfaceImpl, (this));
   4194             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4195                             (0, "PVRTSPEngineNode:DoQueryInterface iExtensionInterface %x "
   4196                              , iExtensionInterface));
   4197         }
   4198         if (iExtensionInterface)
   4199         {
   4200             if (iExtensionInterface->queryInterface(*uuid, *ptr))
   4201             {
   4202                 return PVMFSuccess;
   4203             }
   4204             else
   4205             {
   4206                 return PVMFErrNotSupported;
   4207             }
   4208         }
   4209         else
   4210         {
   4211             return PVMFErrNoMemory;
   4212         }
   4213     }
   4214     else
   4215     {//not supported
   4216         *ptr = NULL;
   4217         return PVMFErrNotSupported;
   4218     }
   4219 }
   4220 
   4221 void PVRTSPEngineNode::ReportErrorEvent(PVMFEventType aEventType,
   4222                                         OsclAny* aEventData,
   4223                                         PVUuid* aEventUUID,
   4224                                         int32* aEventCode)
   4225 {
   4226     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4227                     (0, "PVRTSPEngineNode:NodeErrorEvent Type %d Data %d"
   4228                      , aEventType, aEventData));
   4229 
   4230     if (aEventUUID && aEventCode)
   4231     {
   4232         PVMFBasicErrorInfoMessage* eventmsg =
   4233             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
   4234         PVMFAsyncEvent asyncevent(PVMFErrorEvent,
   4235                                   aEventType,
   4236                                   NULL,
   4237                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
   4238                                   aEventData,
   4239                                   NULL,
   4240                                   0);
   4241         PVMFNodeInterface::ReportErrorEvent(asyncevent);
   4242         eventmsg->removeRef();
   4243     }
   4244     else
   4245     {
   4246         PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
   4247     }
   4248 }
   4249 
   4250 void PVRTSPEngineNode::ReportInfoEvent(PVMFEventType aEventType,
   4251                                        OsclAny* aEventData,
   4252                                        PVUuid* aEventUUID,
   4253                                        int32* aEventCode)
   4254 {
   4255     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4256                     (0, "PVRTSPEngineNode:NodeInfoEvent Type %d Data %d"
   4257                      , aEventType, aEventData));
   4258 
   4259     if (aEventUUID && aEventCode)
   4260     {
   4261         PVMFBasicErrorInfoMessage* eventmsg =
   4262             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
   4263         PVMFAsyncEvent asyncevent(PVMFInfoEvent,
   4264                                   aEventType,
   4265                                   NULL,
   4266                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
   4267                                   aEventData,
   4268                                   NULL,
   4269                                   0);
   4270         PVMFNodeInterface::ReportInfoEvent(asyncevent);
   4271         eventmsg->removeRef();
   4272     }
   4273     else
   4274     {
   4275         PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
   4276     }
   4277 }
   4278 
   4279 
   4280 /////////////////////////////////////////////////////
   4281 // Port Processing routines
   4282 /////////////////////////////////////////////////////
   4283 void PVRTSPEngineNode::HandlePortActivity(const PVMFPortActivity &aActivity)
   4284 {
   4285     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
   4286                     (0, "0x%x PVRTSPEngineNode::HandlePortActivity: port=0x%x, type=%d IQ=%d OQ=%d",
   4287                      this, aActivity.iPort, aActivity.iType, aActivity.iPort->IncomingMsgQueueSize(), aActivity.iPort->OutgoingMsgQueueSize()));
   4288     switch (aActivity.iType)
   4289     {
   4290         case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
   4291             //An outgoing message was queued on this port.
   4292             //We only need to queue a port activity event on the
   4293             //first message.  Additional events will be queued during
   4294             //the port processing as needed.
   4295             if (aActivity.iPort->OutgoingMsgQueueSize() == 1)
   4296                 QueuePortActivity(aActivity);
   4297             break;
   4298         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
   4299             iTheBusyPort = aActivity.iPort;
   4300             break;
   4301 
   4302         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
   4303         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
   4304             //iTheBusyPort = iTheBusyPort;
   4305             break;
   4306 
   4307         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
   4308             if (iTheBusyPort == aActivity.iPort)
   4309             {
   4310                 for (int32 i = iPortVector.size() - 1; i >= 0; i--)
   4311                 {
   4312                     if (((PVMFRTSPPort*)(iPortVector[i]))->OutgoingMsgQueueSize() > 0)
   4313                     {
   4314                         PVMFPortActivity activity(aActivity.iPort, PVMF_PORT_ACTIVITY_OUTGOING_MSG);
   4315                         QueuePortActivity(activity);
   4316                     }
   4317                 }
   4318 
   4319                 if (iRTSPParserState == RTSPParser::EMBEDDED_DATA_IS_READY)
   4320                 {
   4321                     if (!ibBlockedOnFragGroups)
   4322                     {
   4323                         DispatchEmbeddedData(iIncomingMsg.channelID);
   4324                     }
   4325                 }
   4326                 iTheBusyPort = NULL;
   4327             }
   4328             break;
   4329 
   4330         case PVMF_PORT_ACTIVITY_CONNECT:
   4331         default:
   4332             break;
   4333     }
   4334 }
   4335 
   4336 /////////////////////////////////////////////////////
   4337 // Port Processing routines
   4338 /////////////////////////////////////////////////////
   4339 
   4340 void PVRTSPEngineNode::QueuePortActivity(const PVMFPortActivity &aActivity)
   4341 {
   4342     //queue a new port activity event
   4343     int32 err;
   4344     OSCL_TRY(err, iPortActivityQueue.push_back(aActivity););
   4345     if (err != OsclErrNone)
   4346     {
   4347         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4348                         (0, "0x%x PVRTSPEngineNode::QueuePortActivity: Error - iPortActivityQueue.push_back() failed", this));
   4349         ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
   4350     }
   4351     else
   4352     {
   4353         //wake up the AO to process the port activity event.
   4354         RunIfNotReady();
   4355     }
   4356 }
   4357 
   4358 void PVRTSPEngineNode::TimeoutOccurred(int32 timerID, int32 timeoutInfo)
   4359 {
   4360     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::TimeoutOccurred() in timerID=%d", timerID));
   4361     OSCL_UNUSED_ARG(timeoutInfo);
   4362 
   4363     if (!IsAdded())
   4364     {//prevent the leave 49. should never get here
   4365         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::TimeoutOccurred() ERROR line %d", __LINE__));
   4366         return;
   4367     }
   4368     if ((timerID != REQ_TIMER_WATCHDOG_ID) && (timerID != REQ_TIMER_KEEPALIVE_ID) && (PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK == iState))
   4369     {//waiting for the callback to finish the Stop() or Reset()
   4370         RunIfNotReady();
   4371         return;
   4372     }
   4373 
   4374     if (timerID == REQ_TIMER_WATCHDOG_ID)
   4375     {//watchdog
   4376         SocketEvent tmpSockEvent;
   4377         tmpSockEvent.iSockId    = timerID;
   4378         tmpSockEvent.iSockFxn = EPVSocketRecv;
   4379         tmpSockEvent.iSockEvent = EPVSocketTimeout;
   4380         tmpSockEvent.iSockError = 0;
   4381 
   4382         iSocketEventQueue.push_back(tmpSockEvent);
   4383         RunIfNotReady();
   4384     }
   4385     else if (timerID == REQ_TIMER_KEEPALIVE_ID)
   4386     {//keep-alive
   4387         if ((bNoSendPending) &&
   4388                 ((iState == PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE)
   4389                  || ((bKeepAliveInPlay) && (iState == PVRTSP_ENGINE_NODE_STATE_PLAY_DONE))))
   4390         {
   4391             RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
   4392             if (tmpOutgoingMsg == NULL)
   4393             {
   4394                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::TimeoutOccurred ERROR out-of-memory. Ln %d", __LINE__));
   4395                 //iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   4396                 return;
   4397             }
   4398 
   4399             if (PVMFSuccess != composeKeepAliveRequest(*tmpOutgoingMsg))
   4400             {
   4401                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::TimeoutOccurred ERROR composeKeepAliveRequest fail. Ln %d", __LINE__));
   4402                 OSCL_DELETE(tmpOutgoingMsg);
   4403                 //iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposeStopRequestError;
   4404                 return;
   4405             }
   4406             if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
   4407             {
   4408                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   4409                 OSCL_DELETE(tmpOutgoingMsg);
   4410                 return;
   4411                 //iRet =  PVMFFailure;
   4412                 //break;
   4413             }
   4414 
   4415             bNoSendPending = false;
   4416             iOutgoingMsgQueue.push(tmpOutgoingMsg);
   4417         }
   4418     }
   4419 }
   4420 
   4421 PVMFStatus PVRTSPEngineNode::composeKeepAliveRequest(RTSPOutgoingMessage &aMsg)
   4422 {
   4423     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::composeKeepAliveRequest() in"));
   4424 
   4425     aMsg.reset();
   4426     aMsg.numOfTransportEntries = 0;
   4427     aMsg.msgType = RTSPRequestMsg;
   4428     aMsg.method = iKeepAliveMethod;
   4429     aMsg.cseq = iOutgoingSeq++;
   4430     aMsg.cseqIsSet = true;
   4431     aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
   4432     aMsg.userAgentIsSet = true;
   4433 
   4434     if (iSessionInfo.iSID.get_size())
   4435     {
   4436         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
   4437         aMsg.sessionIdIsSet = true;
   4438     }
   4439 
   4440     if (composeSessionURL(aMsg) != PVMFSuccess)
   4441     {
   4442         return PVMFFailure;
   4443     }
   4444 
   4445     if (aMsg.compose() == false)
   4446     {
   4447         return PVMFFailure;
   4448     }
   4449     return PVMFSuccess;
   4450 }
   4451 
   4452 OSCL_EXPORT_REF PVMFStatus  PVRTSPEngineNode::SetKeepAliveMethod_timeout(int32 aTimeout)
   4453 {
   4454     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod_timeout() in aTimeout=%d", aTimeout));
   4455 
   4456     //user server timeout if aTimeout == 0
   4457     aTimeout = aTimeout / 1000; //sec
   4458     if (aTimeout)
   4459     {
   4460         if (aTimeout > 0)//if(aTimeout > 3000)
   4461         {
   4462             TIMEOUT_KEEPALIVE = aTimeout;
   4463         }
   4464         else
   4465         {
   4466             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod() ERROR aTimeout=%d. Ln %d", aTimeout, __LINE__));
   4467             return PVMFFailure;
   4468         }
   4469     }
   4470     else
   4471     {
   4472         TIMEOUT_KEEPALIVE = PVRTSPENGINENODE_DEFAULT_KEEP_ALIVE_INTERVAL;
   4473     }
   4474 
   4475     return PVMFSuccess;
   4476 }
   4477 
   4478 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetKeepAliveMethod_use_SET_PARAMETER(bool aUseSetParameter)
   4479 {
   4480     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod_timeout() in aUseSetParameter=%d", aUseSetParameter));
   4481     iKeepAliveMethod = aUseSetParameter ? METHOD_SET_PARAMETER : METHOD_OPTIONS;
   4482 
   4483     return PVMFSuccess;
   4484 }
   4485 
   4486 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetKeepAliveMethod_keep_alive_in_play(bool aKeepAliveInPlay)
   4487 {
   4488     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod_timeout() in aKeepAliveInPlay=%d", aKeepAliveInPlay));
   4489     bKeepAliveInPlay = aKeepAliveInPlay;
   4490 
   4491     return PVMFSuccess;
   4492 }
   4493 
   4494 
   4495 OSCL_EXPORT_REF PVMFStatus  PVRTSPEngineNode::GetKeepAliveMethod(int32 &aTimeout, bool &aUseSetParameter, bool &aKeepAliveInPlay)
   4496 {
   4497     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::GetKeepAliveMethod() in"));
   4498 
   4499     aTimeout = TIMEOUT_KEEPALIVE * 1000;
   4500     aUseSetParameter = (METHOD_SET_PARAMETER == iKeepAliveMethod);
   4501     aKeepAliveInPlay = bKeepAliveInPlay;
   4502 
   4503     return PVMFSuccess;
   4504 }
   4505 
   4506 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetRTSPTimeOut(int32 &aTimeout)
   4507 {
   4508     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::GetRTSPTimeOut() In"));
   4509 
   4510     aTimeout = TIMEOUT_WATCHDOG;
   4511     return PVMFSuccess;
   4512 }
   4513 
   4514 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetRTSPTimeOut(int32 aTimeout)
   4515 {
   4516     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetRTSPTimeOut() In"));
   4517 
   4518     TIMEOUT_WATCHDOG = aTimeout;
   4519     return PVMFSuccess;
   4520 }
   4521 
   4522 PVMFStatus PVRTSPEngineNode::DoRequestPort(PVRTSPEngineCommand &aCmd, PVMFRTSPPort* &aPort)
   4523 {
   4524     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoRequestPort() In"));
   4525 
   4526     aPort = NULL;
   4527 
   4528     //retrieve port tag.
   4529     int32 tag;
   4530     OSCL_String* portconfig;
   4531     aCmd.PVRTSPEngineCommandBase::Parse(tag, portconfig);
   4532 
   4533     OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpPortConfig = portconfig->get_cstr();
   4534     char *head = tmpPortConfig.get_str();
   4535     if ((!head) ||
   4536             ((tag != PVMF_RTSP_NODE_PORT_TYPE_OUTPUT) && (tag != PVMF_RTSP_NODE_PORT_TYPE_INPUT_OUTPUT)))
   4537     {
   4538         return PVMFErrArgument;//invalide portconfig.
   4539     }
   4540 
   4541     //portconfig should be "sdpTrackIndex=5/media" or "sdpTrackIndex=5/feedback"
   4542 
   4543 
   4544     bool bIsMedia = true;
   4545     OSCL_StackString<128> IsMedia("/media");
   4546     char *tmpCh = OSCL_CONST_CAST(char*, oscl_strstr(head, IsMedia.get_cstr()));
   4547     if (!tmpCh)
   4548     {
   4549         OSCL_StackString<128> IsFeedback("/feedback");
   4550         tmpCh = OSCL_CONST_CAST(char*, oscl_strstr(head, IsFeedback.get_cstr()));
   4551         if (!tmpCh)
   4552         {
   4553             return PVMFErrArgument;
   4554         }
   4555         bIsMedia = false;
   4556     }
   4557     *tmpCh = '\0';  //set the delimiter for atoi
   4558     OSCL_StackString<128> sdpTrackIndex("sdpTrackIndex=");
   4559     tmpCh = OSCL_CONST_CAST(char*, oscl_strstr(head, sdpTrackIndex.get_cstr()));
   4560     if (!tmpCh)
   4561     {
   4562         return PVMFErrArgument;
   4563     }
   4564 
   4565     tmpCh += sdpTrackIndex.get_size();
   4566     uint32 atoi_tmp;
   4567     int32 tmpId = -1; //invalide sdp track id
   4568     if (PV_atoi(tmpCh, 'd', atoi_tmp))
   4569     {
   4570         tmpId = atoi_tmp;
   4571     }
   4572 
   4573     if (tmpId < 0)
   4574     {
   4575         return PVMFErrArgument;//invalide portconfig.
   4576     }
   4577 
   4578     // statements were moved to sep. function to  remove compiler warnings caused by OSCL_TRY()
   4579     return DoAddPort(tmpId, bIsMedia, tag, aPort);
   4580 }
   4581 
   4582 
   4583 PVMFStatus PVRTSPEngineNode::DoAddPort(int32 id, bool isMedia, int32 tag, PVMFRTSPPort* &aPort)
   4584 {
   4585     int32 leavecode;
   4586 
   4587     OSCL_TRY(leavecode,
   4588              aPort = OSCL_STATIC_CAST(PVMFRTSPPort*, OSCL_NEW(PVMFRTSPPort, (id, isMedia, tag, this)));
   4589              iPortVector.AddL(aPort);
   4590             );
   4591 
   4592     if (leavecode != OsclErrNone)
   4593     {
   4594         if (NULL == aPort)
   4595         {
   4596             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DoAddPort() new port fail ERROR leavecode=%d Ln %d", leavecode, __LINE__));
   4597         }
   4598 
   4599         return PVMFErrNoMemory;
   4600     }
   4601 
   4602     return PVMFSuccess;
   4603 }
   4604 
   4605 PVMFStatus PVRTSPEngineNode::DoReleasePort(PVRTSPEngineCommand &aCmd)
   4606 {
   4607     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoReleasePort() In"));
   4608 
   4609     //Find the port in the port vector
   4610     PVMFPortInterface* port;
   4611     aCmd.PVRTSPEngineCommandBase::Parse(port);
   4612 
   4613     return PVMFSuccess;
   4614 }
   4615 
   4616 /* allocate aReqBufSize memory for iEmbeddedData
   4617 return true if memory is successfully allocated
   4618 */
   4619 bool PVRTSPEngineNode::PrepareEmbeddedDataMemory(uint32 aReqBufSize, OsclMemoryFragment &aMemFrag)
   4620 {
   4621     //PVMFSimpleMediaBufferCombinedAlloc media_data_alloc;
   4622     //OsclSharedPtr<PVMFMediaDataImpl> media_data_imp = media_data_alloc.allocate(aReqBufSize);
   4623     // Allocator for simple media data buffer impl
   4624 
   4625     OsclSharedPtr<PVMFMediaDataImpl> media_data_imp;
   4626     int32 errcode;
   4627     OSCL_TRY(errcode, media_data_imp = iMediaDataImplAlloc->allocate(aReqBufSize));
   4628     if (errcode != 0)
   4629     {
   4630         OSCL_ASSERT(false);//there is no limit for the allocator num of buffers for now
   4631 
   4632         ReportErrorEvent(PVMFErrArgument, NULL);
   4633         return false;
   4634     }
   4635 
   4636     //OsclSharedPtr<PVMFMediaDataImpl> media_data_imp = myAllocate(aReqBufSize);
   4637 
   4638     // create a media data buffer
   4639     iEmbeddedDataPtr = PVMFMediaData::createMediaData(media_data_imp,   &iAlloc);
   4640 
   4641     iEmbeddedDataPtr->setMediaFragFilledLen(0, aReqBufSize);
   4642 
   4643     OsclRefCounterMemFrag refCtrMemFragOut;
   4644     iEmbeddedDataPtr->getMediaFragment(0, refCtrMemFragOut);
   4645 
   4646     aMemFrag = refCtrMemFragOut.getMemFrag();
   4647 
   4648     return (aMemFrag.ptr == NULL) ? false : true;
   4649 }
   4650 
   4651 /* dispatch the embedded data in iEmbeddedData to different ports according to channel id
   4652 return true if send success
   4653 */
   4654 bool PVRTSPEngineNode::DispatchEmbeddedData(uint32 aChannelID)
   4655 {
   4656     if (iTheBusyPort)
   4657     {
   4658         return false;
   4659     }
   4660 
   4661     if (ibIsRealRDT)
   4662     {
   4663         return DispatchEmbeddedRdtData();
   4664     }
   4665 
   4666     PVMFRTSPPort* pvPort = NULL;
   4667     for (int32 i = iPortVector.size() - 1; i >= 0; i--)
   4668     {
   4669         if ((((PVMFRTSPPort*)(iPortVector[i]))->iChannelID == aChannelID)
   4670                 && ((PVMFRTSPPort*)(iPortVector[i]))->bIsChannelIDSet)
   4671         {
   4672             pvPort = (PVMFRTSPPort*)(iPortVector[i]);
   4673             break;
   4674         }
   4675     }
   4676     if (pvPort == NULL)
   4677     {//no pvMF port is setup to get this channel, discard the data
   4678         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedData() channel:%d data discarded.", aChannelID));
   4679         iEmbeddedDataPtr.Unbind();
   4680         return true;
   4681     }
   4682 
   4683     PVMFSharedMediaMsgPtr aMediaMsgPtr;
   4684     convertToPVMFMediaMsg(aMediaMsgPtr, iEmbeddedDataPtr);
   4685     PVMFStatus status = pvPort->QueueOutgoingMsg(aMediaMsgPtr);
   4686     if (status != PVMFSuccess)
   4687     {
   4688         if (status == PVMFErrBusy)
   4689         {
   4690             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::DispatchEmbeddedData() BUSY:%d, Outgoing queue size=%d.", status, pvPort->OutgoingMsgQueueSize()));
   4691         }
   4692         else
   4693         {
   4694             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedData() ERROR:%d, Outgoing queue size=%d. Data discarded!", status, pvPort->OutgoingMsgQueueSize()));
   4695             ReportErrorEvent(PVMFErrPortProcessing);
   4696         }
   4697         return false;
   4698     }
   4699     return true;
   4700 }
   4701 
   4702 bool PVRTSPEngineNode::DispatchEmbeddedRdtData()
   4703 {
   4704     IPayloadParser::Payload incomingFrag;
   4705     Oscl_Vector<IPayloadParser::Payload, OsclMemAllocator> vRdtPackets;
   4706 
   4707     // retrieve the incoming RDT packet mem fragment
   4708     OsclRefCounterMemFrag frag;
   4709     iEmbeddedDataPtr->getMediaFragment(0, frag);
   4710     incomingFrag.vfragments.push_back(frag);
   4711 
   4712     // parse the RDT headers and retrieve the payloads
   4713     if (ipRdtParser->Parse(incomingFrag, vRdtPackets) != PayloadParserStatus_Success)
   4714     {
   4715         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() Unable to parse RDT packet!"));
   4716         iEmbeddedDataPtr.Unbind();
   4717         return true;
   4718     }
   4719 
   4720     uint32 i = 0;
   4721     for (i = 0; i < vRdtPackets.size(); i++)
   4722     {
   4723         if (!ipFragGroupAllocator->IsMsgAvailable())
   4724         {
   4725             // drop this packet
   4726             iEmbeddedDataPtr.Unbind();
   4727             vRdtPackets.clear();
   4728             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
   4729                             (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() Out of memory! Stopping processing and dropping packet"));
   4730 
   4731             // block processing until we get a callback
   4732             ibBlockedOnFragGroups = true;
   4733             ipFragGroupAllocator->notifyfreechunkavailable(*this, NULL);
   4734         }
   4735 
   4736         OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
   4737         int32 err;
   4738         mediaDataImplOut = AllocateMediaData(err);
   4739         OSCL_ASSERT(err == OsclErrNone); // we just checked that a message is available
   4740         if (err != OsclErrNone)
   4741         {
   4742             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() Unable to allocate media data impl!"));
   4743             return true;
   4744         }
   4745 
   4746         IPayloadParser::Payload rdtOut = vRdtPackets[i];
   4747         mediaDataImplOut->setMarkerInfo(rdtOut.marker);
   4748         mediaDataImplOut->appendMediaFragment(rdtOut.vfragments[0]);
   4749 
   4750         PVMFSharedMediaDataPtr mediaDataOut = PVMFMediaData::createMediaData(mediaDataImplOut);
   4751         mediaDataOut->setSeqNum(rdtOut.sequence);
   4752         mediaDataOut->setStreamID(rdtOut.stream);
   4753         mediaDataOut->setTimestamp(rdtOut.timestamp);
   4754 
   4755         // which port?
   4756         PVMFRTSPPort* pvPort = NULL;
   4757         for (int p = iPortVector.size() - 1; p >= 0; p--)
   4758         {
   4759             if ((uint)((PVMFRTSPPort*)(iPortVector[p]))->iRdtStreamId == rdtOut.stream)
   4760             {
   4761 
   4762                 pvPort = (PVMFRTSPPort*)(iPortVector[p]);
   4763                 break;
   4764             }
   4765         }
   4766 
   4767         if (pvPort == NULL)
   4768         {//no pvMF port is setup to get this channel, discard the data
   4769             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() channel:%d data discarded.", rdtOut.stream));
   4770             iEmbeddedDataPtr.Unbind();
   4771             return true;
   4772         }
   4773 
   4774         PVMFSharedMediaMsgPtr mediaMsgPtr;
   4775         convertToPVMFMediaMsg(mediaMsgPtr, mediaDataOut);
   4776 
   4777         PVMFStatus status = pvPort->QueueOutgoingMsg(mediaMsgPtr);
   4778         if (status != PVMFSuccess)
   4779         {
   4780             if (status == PVMFErrBusy)
   4781             {
   4782                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() BUSY:%d, Outgoing queue size=%d.", status, pvPort->OutgoingMsgQueueSize()));
   4783             }
   4784             else
   4785             {
   4786                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() ERROR:%d, Outgoing queue size=%d. Data discarded!", status, pvPort->OutgoingMsgQueueSize()));
   4787                 ReportErrorEvent(PVMFErrPortProcessing);
   4788             }
   4789 
   4790             return false;
   4791         }
   4792     }
   4793 
   4794     return true;
   4795 }
   4796 
   4797 PVMFStatus PVRTSPEngineNode::DoFlush(PVRTSPEngineCommand& aCmd)
   4798 {
   4799     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoFlush() In"));
   4800     OSCL_UNUSED_ARG(aCmd);
   4801 
   4802     if ((iInterfaceState != EPVMFNodeStarted) && (iInterfaceState != EPVMFNodePaused))
   4803     {
   4804         return PVMFErrInvalidState;
   4805     }
   4806 
   4807     //Notify all ports to suspend their input
   4808     {
   4809         for (uint32 i = 0; i < iPortVector.size(); i++)
   4810             iPortVector[i]->SuspendInput();
   4811     }
   4812 
   4813     //the flush is asynchronous.  Completion is detected in the Run.
   4814     //Make sure the AO is active to finish the flush..
   4815     RunIfNotReady();
   4816     return PVMFPending;
   4817 }
   4818 
   4819 PVMFStatus PVRTSPEngineNode::sendSocketOutgoingMsg(SocketContainer &aSock, RTSPOutgoingMessage &aMsg)
   4820 {
   4821     StrPtrLen *tmpStrPtrLen = aMsg.retrieveComposedBuffer();
   4822     if (NULL == tmpStrPtrLen)
   4823     {
   4824         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::sendSocketOutgoingMsg() retrieveComposedBuffer() ERROR, line %d", __LINE__));
   4825         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPCompose501ResponseError;
   4826         return  PVMFFailure;
   4827     }
   4828     //PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"C ---> S\n%s", tmpStrPtrLen->c_str()));
   4829     if (aSock.iSocket->Send((const uint8*)tmpStrPtrLen->c_str(), tmpStrPtrLen->length(), TIMEOUT_SEND) != EPVSocketPending)
   4830     {
   4831         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::sendSocketOutgoingMsg() Send() ERROR, line %d", __LINE__));
   4832         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   4833         return PVMFFailure;
   4834     }
   4835     SetSendPending(aSock);
   4836     iNumSendCallback++;
   4837     return PVMFSuccess;
   4838 }
   4839 
   4840 PVMFStatus PVRTSPEngineNode::sendSocketOutgoingMsg(SocketContainer &aSock, const uint8* aSendBuf, uint32 aSendLen)
   4841 {
   4842     if (aSock.iSocket->Send(aSendBuf, aSendLen, TIMEOUT_SEND) != EPVSocketPending)
   4843     {
   4844         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::sendSocketOutgoingMsg() Send() ERROR, line %d", __LINE__));
   4845         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
   4846         return PVMFFailure;
   4847     }
   4848     SetSendPending(aSock);
   4849     iNumSendCallback++;
   4850     return PVMFSuccess;
   4851 }
   4852 
   4853 //drive the parser, return true if there is a pending event
   4854 bool PVRTSPEngineNode::rtspParserLoop(void)
   4855 {
   4856     if ((iRTSPParser == NULL) || (NULL != iTheBusyPort)
   4857             || (iRecvSocket.iSocket == NULL) || (EPVMFNodeError == iInterfaceState))
   4858     {
   4859         return false;
   4860     }
   4861 
   4862     bool bLoop = true, ret = false;
   4863     while (bLoop)
   4864     {
   4865         iRTSPParserState = iRTSPParser->getState();
   4866         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::rtspParserLoop() RTSPParser state %d", iRTSPParserState));
   4867 
   4868         switch (iRTSPParserState)
   4869         {
   4870             case RTSPParser::WAITING_FOR_DATA:
   4871             {
   4872                 if (bNoRecvPending)
   4873                 {
   4874                     TPVSocketEvent tmpEvent = EPVSocketFailure;
   4875                     const StrPtrLen *tmpbuf = iRTSPParser->getDataBufferSpec();
   4876                     if (tmpbuf) // unlikely to fail, err rtn from getDataBufferSpec
   4877                     {
   4878                         tmpEvent = iRecvSocket.iSocket->Recv((uint8*)tmpbuf->c_str(), tmpbuf->length(), TIMEOUT_RECV);
   4879                     }
   4880                     if (tmpEvent != EPVSocketPending)
   4881                     {
   4882                         int32 errcode = PVMFRTSPClientEngineNodeErrorSocketRecvError;
   4883                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() Recv failed"));
   4884                         ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &errcode);
   4885                         ChangeExternalState(EPVMFNodeError);
   4886                     }
   4887                     else
   4888                     {
   4889                         SetRecvPending(iRecvSocket);
   4890                         iNumRecvCallback++;
   4891                     }
   4892                     bNoRecvPending = false;
   4893                 }
   4894                 bLoop = false;
   4895                 break;
   4896             }
   4897             case RTSPParser::WAITING_FOR_REQUEST_MEMORY:
   4898             {
   4899                 iIncomingMsg.reset();
   4900                 if (!iRTSPParser->registerNewRequestStruct(&iIncomingMsg))
   4901                 {
   4902                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerNewRequestStruct failed"));
   4903                     ChangeExternalState(EPVMFNodeError);
   4904                 }
   4905                 break;
   4906             }
   4907             case RTSPParser::ENTITY_BODY_IS_READY:
   4908                 ((uint8*)iEntityMemFrag.ptr)[iEntityMemFrag.len-1] = '\0';
   4909                 //let the Doxxx() to process the entity body, like sdp, still img, and server msg
   4910             case RTSPParser::REQUEST_IS_READY:
   4911             {
   4912                 bLoop = false;
   4913                 ret = true;
   4914                 break;
   4915             }
   4916             case RTSPParser::WAITING_FOR_ENTITY_BODY_MEMORY:
   4917             {/*
   4918 OsclSharedPtr<PVMFMediaDataImpl> media_data_imp;
   4919 int32 errcode;
   4920 OSCL_TRY(errcode, media_data_imp = iMediaDataImplAlloc->allocate(iIncomingMsg.contentLength+1));
   4921 if (errcode != OsclErrNone)
   4922 {
   4923 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0,"PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
   4924 
   4925 OSCL_ASSERT(false);//there is no limit for the allocator num of buffers for now
   4926 ChangeExternalState(EPVMFNodeError);
   4927 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   4928 ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &iCurrentErrorCode);
   4929 
   4930 bLoop = false;
   4931 ret = true;
   4932 break;
   4933 }
   4934 
   4935 media_data_imp->getMediaFragment(0, iEntityMemFrag);
   4936 (iEntityMemFrag.getMemFrag()).len = iEntityMemFrag.getCapacity();
   4937 */
   4938                 if ((iEntityMemFrag.len > 0) || (iEntityMemFrag.ptr != NULL))
   4939                 {
   4940                     OSCL_FREE(iEntityMemFrag.ptr);
   4941                     iEntityMemFrag.len = 0;
   4942                     iEntityMemFrag.ptr = NULL;
   4943                 }
   4944 
   4945                 iEntityMemFrag.len = 0;
   4946                 iEntityMemFrag.ptr = OSCL_MALLOC(iIncomingMsg.contentLength + 1);
   4947                 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0,"PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
   4948 
   4949                 OsclError::LeaveIfNull(iEntityMemFrag.ptr);
   4950                 iEntityMemFrag.len = (iIncomingMsg.contentLength + 1);
   4951 
   4952                 if (!iRTSPParser->registerEntityBody(&iEntityMemFrag))
   4953                 {
   4954                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
   4955 
   4956                     //iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
   4957                     ChangeExternalState(EPVMFNodeError);
   4958                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPParserError;
   4959                     ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &iCurrentErrorCode);
   4960                     bLoop = false;
   4961                     ret = true;
   4962                 }
   4963 
   4964                 break;
   4965             }
   4966 
   4967             case RTSPParser::WAITING_FOR_EMBEDDED_DATA_MEMORY:
   4968             {//TCP streaming
   4969                 RTSPEntityBody iEmbeddedData;
   4970                 if (!PrepareEmbeddedDataMemory(iIncomingMsg.contentLength, iEmbeddedData))
   4971                 {//no memory available TBD
   4972                     bLoop = false;
   4973                     break;
   4974                 }
   4975 
   4976                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::rtspParserLoop() RTP pkts channelID=%d, len=%d", iIncomingMsg.channelID, iIncomingMsg.contentLength));
   4977                 iRTSPParser->registerEmbeddedDataMemory(&iEmbeddedData);
   4978                 break;
   4979             }
   4980             case RTSPParser::EMBEDDED_DATA_IS_READY:
   4981             {//process the data
   4982                 if (!ibBlockedOnFragGroups)
   4983                 {
   4984                     if (! DispatchEmbeddedData(iIncomingMsg.channelID)) //, iEmbeddedData))
   4985                     {//send busy or fails
   4986                         bLoop = false;
   4987                     }
   4988                 }
   4989                 break;
   4990             }
   4991             case RTSPParser::ERROR_REQUEST_TOO_BIG:
   4992             {
   4993                 int32 errcode = PVMFRTSPClientEngineNodeErrorRTSPRequestTooBig;
   4994                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
   4995                 ChangeExternalState(EPVMFNodeError);
   4996                 ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &errcode);
   4997                 bLoop = false;
   4998                 break;
   4999             }
   5000             case RTSPParser::INTERNAL_ERROR:
   5001             default:
   5002             {
   5003                 int32 errcode = PVMFRTSPClientEngineNodeErrorRTSPParserError;
   5004                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
   5005                 ChangeExternalState(EPVMFNodeError);
   5006                 ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &errcode);
   5007                 bLoop = false;
   5008                 break;
   5009             }
   5010         }
   5011     }
   5012     return ret;
   5013 }
   5014 
   5015 
   5016 
   5017 void PVRTSPEngineNode::freechunkavailable(OsclAny*)
   5018 {
   5019     ibBlockedOnFragGroups = false;
   5020 }
   5021 
   5022 PVMFStatus PVRTSPEngineNode::DoErrorRecovery(PVRTSPEngineCommand &aCmd)
   5023 {
   5024     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoReleasePort() In"));
   5025 
   5026     //get error context
   5027     PVRTSPErrorContext* errorContext = OSCL_STATIC_CAST(PVRTSPErrorContext*, aCmd.iParam1);
   5028     if (errorContext == NULL)
   5029     {
   5030         return PVMFFailure;
   5031     }
   5032 
   5033     PVMFStatus myRet = PVMFPending;
   5034 
   5035     {
   5036         if (PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE > iState)
   5037         {
   5038             myRet = SendRtspDescribe(aCmd);
   5039         }
   5040         else if (PVRTSP_ENGINE_NODE_STATE_SETUP_DONE > iState)
   5041         {
   5042             myRet = SendRtspSetup(aCmd);
   5043             if (myRet == PVMFSuccess)
   5044             {//send OPTIONS and keep the connection alive
   5045                 //and wait for new Start() request
   5046                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
   5047             }
   5048         }
   5049     }
   5050 
   5051     if ((PVMFSuccess != myRet) && (PVMFPending != myRet))
   5052     {/*error during error handling
   5053      1. decrease the recovery count counter
   5054      2. reset the socket
   5055      3. change the iState to restart again
   5056         */
   5057         if (iErrorRecoveryAttempt-- <= 0)
   5058         {
   5059             return PVMFFailure;
   5060         }
   5061         //TBD reset the socket
   5062         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_IDLE);
   5063         RunIfNotReady();
   5064     }
   5065     else if (iState >= errorContext->iErrState)
   5066     {
   5067         return PVMFSuccess;
   5068     }
   5069 
   5070     if (PVMFSuccess == myRet)
   5071     {
   5072         RunIfNotReady();
   5073     }
   5074 
   5075     return PVMFPending;
   5076 }
   5077 
   5078 
   5079 //This routine is called repeatedly to drive the socket cleanup sequence.
   5080 // Step 1: Cancel DNS & socket operations & wait on completion
   5081 // Step 2: Shutdown sockets & wait on completion
   5082 // Step 3: Delete sockets
   5083 //
   5084 // If "Immediate" is set we just delete sockets without shutdown sequence.
   5085 PVMFStatus PVRTSPEngineNode::resetSocket(bool aImmediate)
   5086 {
   5087     //Make sure things aren't already cleaned up.
   5088     if (!iDNS.IsBusy()
   5089             && !iSendSocket.iSocket
   5090             && !iRecvSocket.iSocket)
   5091     {
   5092         //Nothing to do!
   5093         if (iLogger)
   5094         {
   5095             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Nothing to do!"));
   5096         }
   5097         return PVMFSuccess;
   5098     }
   5099 
   5100     if (aImmediate)
   5101     {
   5102         //force immediate cleanup, for use in destructor where we can't wait
   5103         //on any async ops.
   5104 
   5105         //see if we have one socket or two.
   5106         bool oneSocket = (iSendSocket.iSocket == iRecvSocket.iSocket);
   5107         if (iSendSocket.iSocket)
   5108         {
   5109             iSendSocket.iSocket->~OsclTCPSocket();
   5110             iAlloc.deallocate(iSendSocket.iSocket);
   5111             iSendSocket.iSocket = NULL;
   5112         }
   5113         if (iRecvSocket.iSocket)
   5114         {
   5115             //guard against duplicate destroy/free
   5116             if (!oneSocket)
   5117             {
   5118                 iRecvSocket.iSocket->~OsclTCPSocket();
   5119                 iAlloc.deallocate(iRecvSocket.iSocket);
   5120             }
   5121             iRecvSocket.iSocket = NULL;
   5122         }
   5123         return PVMFSuccess;
   5124     }
   5125 
   5126     bool waitOnAsyncOp = false;
   5127     while (!waitOnAsyncOp)
   5128     {
   5129         switch (iSocketCleanupState)
   5130         {
   5131             case ESocketCleanup_Idle:
   5132                 //Start a new sequence.
   5133                 iSocketCleanupState = ESocketCleanup_CancelCurrentOp;
   5134                 break;
   5135 
   5136             case ESocketCleanup_CancelCurrentOp:
   5137                 //Step 1: Cancel current operations
   5138 
   5139                 //Cancel ops on DNS
   5140                 if (iDNS.iDns)
   5141                 {
   5142                     if (iDNS.iState.iPending
   5143                             && !iDNS.iState.iCanceled)
   5144                     {
   5145                         iDNS.iDns->CancelGetHostByName();
   5146                         iDNS.iState.iCanceled = true;
   5147                         if (iLogger)
   5148                         {
   5149                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel GetHostByName"));
   5150                         }
   5151                     }
   5152                 }
   5153 
   5154                 //Cancel ops on send socket.
   5155                 if (iSendSocket.iSocket)
   5156                 {
   5157                     if (iSendSocket.iConnectState.iPending
   5158                             && !iSendSocket.iConnectState.iCanceled)
   5159                     {
   5160                         iSendSocket.iSocket->CancelConnect();
   5161                         iSendSocket.iConnectState.iCanceled = true;
   5162                         if (iLogger)
   5163                         {
   5164                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Connect"));
   5165                         }
   5166                     }
   5167                     if (iSendSocket.iSendState.iPending
   5168                             && !iSendSocket.iSendState.iCanceled)
   5169                     {
   5170                         iSendSocket.iSocket->CancelSend();
   5171                         iSendSocket.iSendState.iCanceled = true;
   5172                         if (iLogger)
   5173                         {
   5174                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Send"));
   5175                         }
   5176                     }
   5177                     if (iSendSocket.iRecvState.iPending
   5178                             && !iSendSocket.iRecvState.iCanceled)
   5179                     {
   5180                         iSendSocket.iSocket->CancelRecv();
   5181                         iSendSocket.iRecvState.iCanceled = true;
   5182                         if (iLogger)
   5183                         {
   5184                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Recv"));
   5185                         }
   5186                     }
   5187                     OSCL_ASSERT(!iSendSocket.iShutdownState.iPending);
   5188                 }
   5189 
   5190                 //Cancel ops on recv socket only when it's
   5191                 //a unique socket.
   5192                 if (iRecvSocket.iSocket
   5193                         && iRecvSocket.iSocket != iSendSocket.iSocket)
   5194                 {
   5195                     if (iRecvSocket.iConnectState.iPending
   5196                             && !iRecvSocket.iConnectState.iCanceled)
   5197                     {
   5198                         iRecvSocket.iSocket->CancelConnect();
   5199                         iRecvSocket.iConnectState.iCanceled = true;
   5200                         if (iLogger)
   5201                         {
   5202                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Connect (recv sock)"));
   5203                         }
   5204                     }
   5205                     if (iRecvSocket.iSendState.iPending
   5206                             && !iRecvSocket.iSendState.iCanceled)
   5207                     {
   5208                         iRecvSocket.iSocket->CancelSend();
   5209                         iRecvSocket.iSendState.iCanceled = true;
   5210                         if (iLogger)
   5211                         {
   5212                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Send (recv sock)"));
   5213                         }
   5214                     }
   5215                     if (iRecvSocket.iRecvState.iPending
   5216                             && !iRecvSocket.iRecvState.iCanceled)
   5217                     {
   5218                         iRecvSocket.iSocket->CancelRecv();
   5219                         iRecvSocket.iRecvState.iCanceled = true;
   5220                         if (iLogger)
   5221                         {
   5222                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Recv (recv sock)"));
   5223                         }
   5224                     }
   5225                     OSCL_ASSERT(!iRecvSocket.iShutdownState.iPending);
   5226                 }
   5227 
   5228                 if (iDNS.IsBusy()
   5229                         || iSendSocket.IsBusy()
   5230                         || iRecvSocket.IsBusy())
   5231                 {
   5232                     waitOnAsyncOp = true;
   5233                 }
   5234 
   5235                 //Either go to wait state or continue to Step 2.
   5236                 if (waitOnAsyncOp)
   5237                     iSocketCleanupState = ESocketCleanup_WaitOnCancel;
   5238                 else
   5239                     iSocketCleanupState = ESocketCleanup_Shutdown;
   5240                 break;
   5241 
   5242             case ESocketCleanup_WaitOnCancel:
   5243                 //Wait on cancel completion for all.
   5244 
   5245                 if (iDNS.IsBusy()
   5246                         || iSendSocket.IsBusy()
   5247                         || iRecvSocket.IsBusy())
   5248                 {
   5249                     waitOnAsyncOp = true;
   5250                 }
   5251 
   5252                 if (!waitOnAsyncOp)
   5253                     iSocketCleanupState = ESocketCleanup_Shutdown;
   5254                 break;
   5255 
   5256             case ESocketCleanup_Shutdown:
   5257                 //Step 2: shutdown both sockets
   5258 
   5259                 if (iDNS.iDns)
   5260                 {
   5261                     OSCL_ASSERT(!iDNS.IsBusy());
   5262                 }
   5263 
   5264                 if (iSendSocket.iSocket)
   5265                 {
   5266                     OSCL_ASSERT(!iSendSocket.IsBusy());
   5267 
   5268                     if (iSendSocket.iSocket->Shutdown(EPVSocketBothShutdown, TIMEOUT_SHUTDOWN) == EPVSocketPending)
   5269                     {
   5270                         iSendSocket.iShutdownState.iPending = true;
   5271                         waitOnAsyncOp = true;
   5272                         if (iLogger)
   5273                         {
   5274                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown"));
   5275                         }
   5276                     }
   5277                     //else shutdown failed, ignore & continue
   5278                     else
   5279                     {
   5280                         if (iLogger)
   5281                         {
   5282                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown Failed"));
   5283                         }
   5284                     }
   5285                 }
   5286 
   5287                 //shutown recv socket only when it's a unique socket.
   5288                 if (iRecvSocket.iSocket
   5289                         && iRecvSocket.iSocket != iSendSocket.iSocket)
   5290                 {
   5291                     OSCL_ASSERT(!iRecvSocket.IsBusy());
   5292 
   5293                     if (iRecvSocket.iSocket->Shutdown(EPVSocketBothShutdown, TIMEOUT_SHUTDOWN) == EPVSocketPending)
   5294                     {
   5295                         iRecvSocket.iShutdownState.iPending = true;
   5296                         waitOnAsyncOp = true;
   5297                         if (iLogger)
   5298                         {
   5299                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown (recv sock)"));
   5300                         }
   5301                     }
   5302                     //else shutdown failed, ignore & continue
   5303                     else
   5304                     {
   5305                         if (iLogger)
   5306                         {
   5307                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown Failed (recv sock)"));
   5308                         }
   5309                     }
   5310                 }
   5311 
   5312                 //Either go to wait state or continue to Step 3.
   5313                 if (waitOnAsyncOp)
   5314                     iSocketCleanupState = ESocketCleanup_WaitOnShutdown;
   5315                 else
   5316                     iSocketCleanupState = ESocketCleanup_Delete;
   5317                 break;
   5318 
   5319             case ESocketCleanup_WaitOnShutdown:
   5320                 //Wait on shutdown completion for both sockets.
   5321 
   5322                 if (iSendSocket.IsBusy()
   5323                         || iRecvSocket.IsBusy())
   5324                 {
   5325                     waitOnAsyncOp = true;
   5326                 }
   5327 
   5328                 if (!waitOnAsyncOp)
   5329                     iSocketCleanupState = ESocketCleanup_Delete;
   5330                 break;
   5331 
   5332             case ESocketCleanup_Delete:
   5333                 // Step 3: Delete sockets
   5334 
   5335                 // Note: we assume this calling context is not the socket callback, so
   5336                 // it's safe to delete the OsclSocket object here.
   5337 
   5338             {
   5339                 //see if we have one socket or two.
   5340                 bool oneSocket = (iSendSocket.iSocket == iRecvSocket.iSocket);
   5341                 if (iSendSocket.iSocket)
   5342                 {
   5343                     OSCL_ASSERT(!iSendSocket.IsBusy());
   5344                     if (iLogger)
   5345                     {
   5346                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Delete TCP"));
   5347                     }
   5348                     iSendSocket.iSocket->~OsclTCPSocket();
   5349                     iAlloc.deallocate(iSendSocket.iSocket);
   5350                     iSendSocket.iSocket = NULL;
   5351                 }
   5352                 if (iRecvSocket.iSocket)
   5353                 {
   5354                     OSCL_ASSERT(!iRecvSocket.IsBusy());
   5355                     //guard against duplicate destroy/free
   5356                     if (!oneSocket)
   5357                     {
   5358                         if (iLogger)
   5359                         {
   5360                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Delete TCP (recv sock)"));
   5361                         }
   5362                         iRecvSocket.iSocket->~OsclTCPSocket();
   5363                         iAlloc.deallocate(iRecvSocket.iSocket);
   5364                     }
   5365                     iRecvSocket.iSocket = NULL;
   5366                 }
   5367 
   5368                 bNoSendPending = bNoRecvPending = false;
   5369 
   5370                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_IDLE);
   5371             }
   5372             iSocketCleanupState = ESocketCleanup_Idle;
   5373             if (iLogger)
   5374             {
   5375                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Done!"));
   5376             }
   5377             return PVMFSuccess; //Done!
   5378 
   5379             default:
   5380                 OSCL_ASSERT(0);
   5381                 break;
   5382         }
   5383     }
   5384 
   5385     return (waitOnAsyncOp) ? PVMFPending : PVMFSuccess;
   5386 }
   5387 
   5388 void PVRTSPEngineNode::SetSendPending(SocketContainer& aSock)
   5389 {
   5390     //Set "send pending" condition on a socket container.
   5391     //update recv socket container only when we have a unique recv socket,
   5392     //otherwise update send socket container.
   5393     if (aSock.iSocket == iRecvSocket.iSocket
   5394             && iRecvSocket.iSocket != iSendSocket.iSocket)
   5395         iRecvSocket.iSendState.iPending = true;
   5396     else
   5397     {
   5398         iSendSocket.iSendState.iPending = true;
   5399         OSCL_ASSERT(aSock.iSocket == iSendSocket.iSocket);
   5400     }
   5401 }
   5402 
   5403 void PVRTSPEngineNode::SetRecvPending(SocketContainer& aSock)
   5404 {
   5405     //Set "recv pending" condition on a socket container.
   5406     //update recv socket container only when we have a unique recv socket,
   5407     //otherwise update send socket container.
   5408     if (aSock.iSocket == iRecvSocket.iSocket
   5409             && iRecvSocket.iSocket != iSendSocket.iSocket)
   5410         iRecvSocket.iRecvState.iPending = true;
   5411     else
   5412     {
   5413         iSendSocket.iRecvState.iPending = true;
   5414         OSCL_ASSERT(aSock.iSocket == iSendSocket.iSocket);
   5415     }
   5416 }
   5417 
   5418 OsclLeaveCode PVRTSPEngineNode::RunError(OsclLeaveCode aError)
   5419 {
   5420     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::RunError() aError=%d", aError));
   5421 
   5422 
   5423     //return OsclErrNone;
   5424     return aError;
   5425 }
   5426 
   5427 void PVRTSPEngineNode::clearOutgoingMsgQueue()
   5428 {
   5429     while (!iOutgoingMsgQueue.empty())
   5430     {
   5431         //pop the outgoing msg queue and see the match
   5432         RTSPOutgoingMessage* tmpOutgoingMsg = iOutgoingMsgQueue.top();
   5433         iOutgoingMsgQueue.pop();
   5434         if (tmpOutgoingMsg)
   5435             OSCL_DELETE(tmpOutgoingMsg);
   5436     }
   5437 }
   5438 
   5439 void PVRTSPEngineNode::partialResetSessionInfo()
   5440 {
   5441     iOutgoingSeq = 0;
   5442     setupTrackIndex = 0;
   5443     iSessionInfo.iSID = "";
   5444 
   5445     iSessionInfo.iReqPlayRange.format = RtspRangeType::INVALID_RANGE;
   5446     iSessionInfo.bExternalSDP = false;
   5447     iSessionInfo.pvServerIsSetFlag = false;
   5448     iSessionInfo.roundTripDelay = 0;
   5449     iSessionInfo.iSDPinfo.Unbind();
   5450 }
   5451 
   5452 void PVRTSPEngineNode::ResetSessionInfo()
   5453 {
   5454     iOutgoingSeq = 0;
   5455     setupTrackIndex = 0;
   5456     iSessionInfo.iSID = "";
   5457 
   5458     iSessionInfo.iReqPlayRange.format = RtspRangeType::INVALID_RANGE;
   5459     iSessionInfo.bExternalSDP = false;
   5460     iSessionInfo.pvServerIsSetFlag = false;
   5461     iSessionInfo.roundTripDelay = 0;
   5462     iSessionInfo.iSDPinfo.Unbind();
   5463 }
   5464 
   5465 //clear the internal event queue "iSocketEventQueue"
   5466 //return false if any of the event indicate failure
   5467 bool PVRTSPEngineNode::clearEventQueue(void)
   5468 {
   5469     bool myRet = true;
   5470     while (!iSocketEventQueue.empty())
   5471     {
   5472         SocketEvent tmpSockEvent(iSocketEventQueue.front());
   5473         iSocketEventQueue.erase(&iSocketEventQueue.front());
   5474         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::clearEventQueue() In iFxn=%d iSockEvent=%d iSockError=%d ", tmpSockEvent.iSockFxn, tmpSockEvent.iSockEvent, tmpSockEvent.iSockError));
   5475 
   5476         if (tmpSockEvent.iSockEvent != EPVSocketSuccess)
   5477         {
   5478             myRet = false;
   5479             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::clearEventQueue() Socket Error"));
   5480         }
   5481     }
   5482 
   5483     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::clearEventQueue() Out myRet=%d ", myRet));
   5484     return myRet;
   5485 }
   5486 
   5487 ////////////////////////////////////////////////////////////////////////////////
   5488 /// GetPostCorrelationObject Implementation
   5489 ////////////////////////////////////////////////////////////////////////////////
   5490 #define KGetPostCorrelationFile _STRLIT("get_post_correlation_number.dat")
   5491 
   5492 GetPostCorrelationObject* GetPostCorrelationObject::create(OSCL_TCHAR* aFileName)
   5493 {
   5494     GetPostCorrelationObject *object = OSCL_NEW(GetPostCorrelationObject, ());
   5495     if (!object) return NULL;
   5496     if (!object->construct(aFileName))
   5497     {
   5498         OSCL_DELETE(object);
   5499         return NULL;
   5500     }
   5501     return object;
   5502 }
   5503 
   5504 bool GetPostCorrelationObject::construct(OSCL_TCHAR* aFileName)
   5505 {
   5506     iGetPostCorrelation = 1;
   5507     iFileCreated = false;
   5508     iFs.Connect();
   5509 
   5510     OSCL_TCHAR* aLocalFileName = aFileName;
   5511     if (!aLocalFileName) aLocalFileName = (OSCL_TCHAR*)KGetPostCorrelationFile;
   5512     if (iGetPostCorrelationFile.Open(aLocalFileName, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY, iFs) == 0)
   5513     {
   5514         // get the current iGetPostCorrelation
   5515         iGetPostCorrelationFile.Read(&iGetPostCorrelation, sizeof(iGetPostCorrelation), 1);
   5516         iGetPostCorrelationFile.Close();
   5517     }
   5518 
   5519     if (iGetPostCorrelationFile.Open(aLocalFileName, Oscl_File::MODE_READWRITE | Oscl_File::MODE_BINARY, iFs))
   5520     {
   5521         iFs.Close();
   5522         return false;
   5523     }
   5524 
   5525     iFileCreated = true;
   5526     return true;
   5527 }
   5528 
   5529 GetPostCorrelationObject::~GetPostCorrelationObject()
   5530 {
   5531     if (iFileCreated) closeFile();
   5532     iFileCreated = false;
   5533 }
   5534 
   5535 void GetPostCorrelationObject::closeFile()
   5536 {
   5537     writeToFile();
   5538     iGetPostCorrelationFile.Close();
   5539     iFs.Close();
   5540 }
   5541 
   5542 
   5543 bool GetPostCorrelationObject::writeToFile()
   5544 {
   5545     // always write at the beginning
   5546     if (iGetPostCorrelationFile.Seek(0, Oscl_File::SEEKSET)) return false;
   5547     if (iGetPostCorrelationFile.Write(&iGetPostCorrelation, sizeof(iGetPostCorrelation), 1) != 1)
   5548     {
   5549         return false;
   5550     }
   5551 
   5552     // Flush the data to file
   5553     iGetPostCorrelationFile.Flush();
   5554     return true;
   5555 }
   5556 
   5557 bool GetPostCorrelationObject::update()
   5558 {
   5559     if (!iFileCreated) return false;
   5560 
   5561     // increase iGetPostCorrelation by 1 within [1, 255]
   5562     if (iGetPostCorrelation == 255) iGetPostCorrelation = 1;
   5563     else ++iGetPostCorrelation;
   5564 
   5565     return writeToFile();
   5566 }
   5567 
   5568 
   5569 
   5570 
   5571 /**
   5572  * Called by the command handler AO to do the Cancel All
   5573  */
   5574 PVMFStatus PVRTSPEngineNode::DoCancelAllCommands(PVRTSPEngineCommand& aCmd)
   5575 {
   5576     /* cancel all queued commands */
   5577     while (!iPendingCmdQueue.empty())
   5578         CommandComplete(iPendingCmdQueue, iPendingCmdQueue[1], PVMFErrCancelled);
   5579 
   5580     if (iRunningCmdQueue.size() > 1)
   5581     {
   5582         MoveCmdToCancelQueue(aCmd);
   5583         return PVMFPending;
   5584     }
   5585 
   5586     return PVMFSuccess;
   5587 }
   5588 
   5589 void PVRTSPEngineNode::MoveCmdToCancelQueue(PVRTSPEngineCommand& aCmd)
   5590 {
   5591     /*
   5592      * note: the StoreL cannot fail since the queue is never more than 1 deep
   5593      * and we reserved space.
   5594      */
   5595     iCancelCmdQueue.StoreL(aCmd);
   5596     iRunningCmdQueue.Erase(&aCmd);
   5597 }
   5598 
   5599 
   5600 OsclSharedPtr<PVMFMediaDataImpl> PVRTSPEngineNode::AllocateMediaData(int32& errCode)
   5601 {
   5602     OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
   5603     OSCL_TRY(errCode, mediaDataImplOut = ipFragGroupAllocator->allocate());
   5604     return mediaDataImplOut;
   5605 }
   5606