• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
PVRTSPEngineNode(int32 aPriority)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 
~PVRTSPEngineNode()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 
ThreadLogon()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 
ThreadLogoff()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 
GetCapability(PVMFNodeCapability & aNodeCapability)326 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetCapability(PVMFNodeCapability& aNodeCapability)
327 {
328     OSCL_UNUSED_ARG(aNodeCapability);
329     return PVMFFailure;
330 }
331 
GetPorts(const PVMFPortFilter * aFilter)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 
QueryUUID(PVMFSessionId aSession,const PvmfMimeString & aMimeType,Oscl_Vector<PVUuid,PVRTSPEngineNodeAllocator> & aUuids,bool aExactUuidsOnly,const OsclAny * aContext)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 
addRef()356 OSCL_EXPORT_REF void PVRTSPEngineNode::addRef()
357 {
358 
359 }
360 
removeRef()361 OSCL_EXPORT_REF void PVRTSPEngineNode::removeRef()
362 {
363 
364 }
365 
queryInterface(const PVUuid & uuid,PVInterface * & iface)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 
QueryInterface(PVMFSessionId aSession,const PVUuid & aUuid,PVInterface * & aInterfacePtr,const OsclAny * aContext)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 
RequestPort(PVMFSessionId aSession,int32 aPortTag,const PvmfMimeString * aPortConfig,const OsclAny * aContext)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 
ReleasePort(PVMFSessionId aSession,PVMFPortInterface & aPort,const OsclAny * aContext)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 
Init(PVMFSessionId aSession,const OsclAny * aContext)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 
Prepare(PVMFSessionId aSession,const OsclAny * aContext)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 
Start(PVMFSessionId aSession,const OsclAny * aContext)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 
Pause(PVMFSessionId aSession,const OsclAny * aContext)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 
Stop(PVMFSessionId aSession,const OsclAny * aContext)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 
Reset(PVMFSessionId aSession,const OsclAny * aContext)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 
Flush(PVMFSessionId aSession,const OsclAny * aContext)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 
CancelCommand(PVMFSessionId aSession,PVMFCommandId aCmdId,const OsclAny * aContextData)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 
CancelAllCommands(PVMFSessionId aSession,const OsclAny * aContextData)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
SetStreamingType(PVRTSPStreamingType aType)523 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetStreamingType(PVRTSPStreamingType aType)
524 {
525     iSessionInfo.iStreamingType = aType;
526     return PVMFSuccess;
527 }
528 
SetSessionURL(OSCL_wString & aURL)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 
SetRtspProxy(OSCL_String & aRtspProxyName,uint32 aRtspProxyPort)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 }
GetRtspProxy(OSCL_String & aRtspProxyName,uint32 & aRtspProxyPort)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 
SetSDPInfo(OsclSharedPtr<SDPInfo> & aSDPinfo,Oscl_Vector<StreamInfo,PVRTSPEngineNodeAllocator> & aSelectedStream)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 
GetSDP(OsclRefCounterMemFrag & aSDPMemFrag)618 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetSDP(OsclRefCounterMemFrag& aSDPMemFrag)
619 {
620     aSDPMemFrag = iSessionInfo.pSDPBuf;
621     return PVMFSuccess;
622 }
623 
GetServerInfo(PVRTSPEngineNodeServerInfo & aServerInfo)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 
GetStreamInfo(Oscl_Vector<StreamInfo,PVRTSPEngineNodeAllocator> & aSelectedStream)633 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetStreamInfo(Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> &aSelectedStream)
634 {
635     aSelectedStream = iSessionInfo.iSelectedStream;
636     return PVMFSuccess;
637 }
638 
GetUserAgent(OSCL_wString & aUserAgent)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 
SetClientParameters(OSCL_wString & aUserAgent,OSCL_wString & aUserNetwork,OSCL_wString & aDeviceInfo)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 
IsRdtTransport()724 OSCL_EXPORT_REF bool PVRTSPEngineNode::IsRdtTransport()
725 {
726     return ibIsRealRDT;
727 }
728 
729 
SetPortRdtStreamId(PVMFPortInterface * pPort,int iRdtStreamId)730 OSCL_EXPORT_REF void PVRTSPEngineNode::SetPortRdtStreamId(PVMFPortInterface* pPort,
731         int iRdtStreamId)
732 {
733     ((PVMFRTSPPort*)pPort)->iRdtStreamId = iRdtStreamId;
734 }
735 
SetRealChallengeCalculator(IRealChallengeGen * pChallengeCalc)736 OSCL_EXPORT_REF void PVRTSPEngineNode::SetRealChallengeCalculator(IRealChallengeGen* pChallengeCalc)
737 {
738     ipRealChallengeGen = pChallengeCalc;
739 }
740 
SetRdtParser(IPayloadParser * pRdtParser)741 OSCL_EXPORT_REF void PVRTSPEngineNode::SetRdtParser(IPayloadParser* pRdtParser)
742 {
743     ipRdtParser = pRdtParser;
744 }
745 
SetAuthenticationParameters(OSCL_wString & aUserID,OSCL_wString & aAuthentication,OSCL_wString & aExpiration,OSCL_wString & aApplicationSpecificString,OSCL_wString & aVerification,OSCL_wString & aSignature)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 
SetRequestPlayRange(const RtspRangeType & aRange)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 
GetActualPlayRange(RtspRangeType & aRange)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
HandleSocketEvent(int32 aId,TPVSocketFxn aFxn,TPVSocketEvent aEvent,int32 aError)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
HandleDNSEvent(int32 aId,TPVDNSFxn aFxn,TPVDNSEvent aEvent,int32 aError)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 
Run()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 */
FlushPending()1178 bool PVRTSPEngineNode::FlushPending()
1179 {
1180     return (iRunningCmdQueue.size() > 0
1181             && iRunningCmdQueue.front().iCmd == PVMF_GENERIC_NODE_FLUSH);
1182 }
1183 
ProcessPortActivity()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 /////////////////////////////////////////////////////
ProcessOutgoingMsg(PVMFPortInterface * aPort)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 */
ProcessCommand(PVRTSPEngineCommand & aInCmd)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 
DispatchCommand(PVRTSPEngineCommand & aCmd)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 */
CommandComplete(PVRTSPEngineNodeCmdQ & aCmdQ,PVRTSPEngineCommand & aCmd,PVMFStatus aStatus,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)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
AddCmdToQueue(PVRTSPEngineCommand & aCmd)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 
ChangeExternalState(TPVMFNodeInterfaceState aNewState)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 
ChangeInternalState(PVRTSPEngineState aNewState)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 
DoInitNode(PVRTSPEngineCommand & aCmd)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 
SendRtspDescribe(PVRTSPEngineCommand & aCmd)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 
DoPrepareNode(PVRTSPEngineCommand & aCmd)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 
SendRtspSetup(PVRTSPEngineCommand & aCmd)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 
parseURL(const OSCL_wString & aURL)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 
parseURL(const char * aUrl)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     mbchar *server_port_ptr = OSCL_CONST_CAST(mbchar*, oscl_strstr(server_ip_ptr, ":"));
2369     mbchar *clip_name = OSCL_CONST_CAST(mbchar*, oscl_strstr(server_ip_ptr, "/"));
2370     if (clip_name != NULL)
2371     {
2372         *clip_name++ = '\0';
2373     }
2374 
2375     /* Locate the port number if provided. */
2376     iSessionInfo.iSrvAdd.port = (iSessionInfo.iStreamingType == PVRTSP_RM_HTTP) ? DEFAULT_HTTP_PORT : DEFAULT_RTSP_PORT;
2377     if ((server_port_ptr != NULL)  && (*(server_port_ptr + 1) != '/'))
2378     {
2379         *(server_port_ptr++) = '\0';
2380         uint32 atoi_tmp;
2381         if (PV_atoi(server_port_ptr, 'd', atoi_tmp))
2382         {
2383             iSessionInfo.iSrvAdd.port = atoi_tmp;
2384         }
2385     }
2386 
2387     OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpServerName(server_ip_ptr, oscl_strlen(server_ip_ptr));
2388     iSessionInfo.iServerName = tmpServerName;
2389 
2390 //iSessionInfo.iSrvAdd.port = 20080;
2391 //iSessionInfo.iServerName = "172.16.2.42";
2392 
2393     return true;
2394 }
2395 
2396 PVMFStatus
composeOptionsRequest(RTSPOutgoingMessage & iMsg)2397 PVRTSPEngineNode::composeOptionsRequest(RTSPOutgoingMessage &iMsg)
2398 {
2399     iMsg.reset();
2400 
2401     iMsg.numOfTransportEntries = 0;
2402     iMsg.msgType = RTSPRequestMsg;
2403     iMsg.method = METHOD_OPTIONS;
2404     iMsg.originalURI.setPtrLen(iSessionInfo.iSessionURL.get_cstr(), iSessionInfo.iSessionURL.get_size());
2405     iMsg.cseq = iOutgoingSeq++;
2406     iMsg.cseqIsSet = true;
2407     iMsg.acceptIsSet = false;
2408     iMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
2409     iMsg.userAgentIsSet = true;
2410 
2411     {
2412         // setup parameters for the options command. this is necessary
2413         // for real rdt support.
2414         StrCSumPtrLen ClientChallenge = _STRLIT_CHAR("ClientChallenge");
2415         OSCL_HeapString<PVRTSPEngineNodeAllocator> ClientChallenge_Val("9e26d33f2984236010ef6253fb1887f7");
2416         iMsg.addField(&ClientChallenge, ClientChallenge_Val.get_cstr());
2417 
2418         StrCSumPtrLen PlayerStarttime = _STRLIT_CHAR("PlayerStarttime");
2419         OSCL_HeapString<PVRTSPEngineNodeAllocator> PlayerStarttime_Val("[28/03/2003:22:50:23 00:00]");
2420         iMsg.addField(&PlayerStarttime, PlayerStarttime_Val.get_cstr());
2421 
2422         StrCSumPtrLen CompanyID = _STRLIT_CHAR("CompanyID");
2423         OSCL_HeapString<PVRTSPEngineNodeAllocator> CompanyID_Val("KnKV4M4I/B2FjJ1TToLycw==");
2424         iMsg.addField(&CompanyID, CompanyID_Val.get_cstr());
2425 
2426         StrCSumPtrLen playerGuid = _STRLIT_CHAR("GUID");
2427         OSCL_StackString<64> playerGuidVal = _STRLIT_CHAR("00000000-0000-0000-0000-000000000000");
2428         iMsg.addField(&playerGuid, playerGuidVal.get_cstr());
2429     }
2430 
2431     if (iMsg.compose() == false)
2432     {
2433         return PVMFFailure;
2434     }
2435     else
2436     {
2437         return PVMFSuccess;
2438     }
2439 }
2440 
2441 /*
2442 * Function : int composeDescribeRequest()
2443 * Date      : 09/13/2002
2444 * Purpose  : Composes RTSP DESCRIBE request
2445 * In/out   :
2446 * Return   :
2447 * Modified :
2448 */
2449 PVMFStatus
composeDescribeRequest(RTSPOutgoingMessage & iMsg)2450 PVRTSPEngineNode::composeDescribeRequest(RTSPOutgoingMessage &iMsg)
2451 {
2452     iMsg.reset();
2453     iMsg.numOfTransportEntries = 0;
2454     iMsg.msgType = RTSPRequestMsg;
2455     iMsg.method = METHOD_DESCRIBE;
2456     iMsg.originalURI.setPtrLen(iSessionInfo.iSessionURL.get_cstr(), iSessionInfo.iSessionURL.get_size());
2457     iMsg.cseq = iOutgoingSeq++;
2458     iMsg.cseqIsSet = true;
2459     iMsg.accept = "application/sdp";
2460     iMsg.acceptIsSet = true;
2461     iMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
2462     iMsg.userAgentIsSet = true;
2463 
2464     if (oscl_strlen(iSessionInfo.iUserNetwork.get_cstr()))
2465     {
2466         StrCSumPtrLen UserNetwork = _STRLIT_CHAR("User-Network");
2467         iMsg.addField(&UserNetwork, iSessionInfo.iUserNetwork.get_cstr());
2468     }
2469     if (oscl_strlen(iSessionInfo.iDeviceInfo.get_cstr()))
2470     {
2471         StrCSumPtrLen DeviceInfo = _STRLIT_CHAR("DeviceInfo");
2472         iMsg.addField(&DeviceInfo, iSessionInfo.iDeviceInfo.get_cstr());
2473     }
2474     if (oscl_strlen(iSessionInfo.iUserID.get_cstr()) && oscl_strlen(iSessionInfo.iAuthentication.get_cstr()))
2475     {
2476         OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("user=");
2477         myBuf += iSessionInfo.iUserID.get_cstr();
2478         myBuf += ";authentication=";
2479         myBuf += iSessionInfo.iAuthentication.get_cstr();
2480 
2481         StrCSumPtrLen User_id = _STRLIT_CHAR("ID");
2482         iMsg.addField(&User_id, myBuf.get_cstr());
2483     }
2484     if (oscl_strlen(iSessionInfo.iExpiration.get_cstr()))
2485     {
2486         StrCSumPtrLen Expiration = _STRLIT_CHAR("Expiration");
2487         iMsg.addField(&Expiration, iSessionInfo.iExpiration.get_cstr());
2488     }
2489     if (oscl_strlen(iSessionInfo.iApplicationSpecificString.get_cstr()))
2490     {
2491         StrCSumPtrLen Application_specific_string = _STRLIT_CHAR("Application-Specific-String");
2492         iMsg.addField(&Application_specific_string, iSessionInfo.iApplicationSpecificString.get_cstr());
2493     }
2494 
2495     if (iSessionInfo.iVerification.get_size() && iSessionInfo.iSignature.get_size())
2496     {
2497         OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("filler=");
2498         myBuf += iSessionInfo.iVerification.get_cstr();
2499         myBuf += ";signature=";
2500         myBuf += iSessionInfo.iSignature.get_cstr();
2501 
2502         StrCSumPtrLen Verification = _STRLIT_CHAR("Verification");
2503         iMsg.addField(&Verification, myBuf.get_cstr());
2504     }
2505 
2506     {//If the Accept-Encoding field-value is empty, then only the "identity"
2507         // encoding is acceptable.
2508         StrCSumPtrLen AcceptEncoding = _STRLIT_CHAR("Accept-Encoding");
2509         iMsg.addField(&AcceptEncoding, "");
2510     }
2511 
2512     if (iMsg.compose() == false)
2513     {
2514         return PVMFFailure;
2515     }
2516 
2517     iSessionInfo.clientServerDelay = 0;
2518     uint32 clock = 0;
2519     bool overflowFlag = false;
2520     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
2521     iSessionInfo.clientServerDelay = clock;
2522 
2523     //iSessionInfo.composedMessage = iMsg.retrieveComposedBuffer();
2524     return PVMFSuccess;
2525 }
2526 
processServerRequest(RTSPIncomingMessage & aMsg)2527 PVMFStatus PVRTSPEngineNode::processServerRequest(RTSPIncomingMessage &aMsg)
2528 {//input: server request in aMsg;
2529     //just send the response. bingo.
2530     //all S->C are optional, including ANNOUNCE, GET_PARAMETER, SET_PARAMETER, OPTIONS
2531     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::processServerRequest() In"));
2532 
2533     if (iSrvResponse == NULL)
2534     {
2535         iSrvResponse =  OSCL_NEW(RTSPOutgoingMessage, ());
2536         if (iSrvResponse == NULL)
2537         {
2538             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
2539             return  PVMFFailure;
2540         }
2541     }
2542 
2543     iSrvResponse->reset();
2544     iSrvResponse->msgType = RTSPResponseMsg;
2545     iSrvResponse->numOfTransportEntries = 0;
2546 
2547     if (aMsg.method == METHOD_END_OF_STREAM)
2548     {//
2549         iSrvResponse->statusCode =  CodeOK;
2550         iSrvResponse->reasonString = "OK";
2551         ReportInfoEvent(PVMFInfoEndOfData);
2552     }
2553     else if (aMsg.method == METHOD_SET_PARAMETER)
2554     {//
2555         iSrvResponse->statusCode =  CodeOK;
2556         iSrvResponse->reasonString = "OK";
2557     }
2558     else
2559     {
2560         iSrvResponse->statusCode =  CodeNotImplemented;
2561         iSrvResponse->reasonString = "Not Implemented";
2562     }
2563     //iSrvResponse->statusCode = CodeParameterNotUnderstood;
2564     //iSrvResponse->reasonString = "Parameter Not Understood";
2565     iSrvResponse->cseq = aMsg.cseq;
2566     iSrvResponse->cseqIsSet = true;
2567 
2568     if (iSessionInfo.iSID.get_size())
2569     {
2570         iSrvResponse->sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
2571         iSrvResponse->sessionIdIsSet = true;
2572     }
2573     if (iSrvResponse->compose() == false)
2574     {
2575         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPCompose501ResponseError;
2576         OSCL_DELETE(iSrvResponse);
2577         iSrvResponse = NULL;
2578         return PVMFFailure;
2579     }
2580 
2581     if (bNoSendPending)// bSrvRespPending
2582     {
2583         if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *iSrvResponse))
2584         {
2585             /* need to pop the msg based on cseq, NOT necessarily the early ones,
2586             although YES in this case.
2587             //for(int idx=0; idx < iSessionInfo.trackSelectionList->getNumTracks(); idx++ )
2588             for(int idx=0; idx < iSessionInfo.iSDPinfo->getNumMediaObjects(); idx++ )
2589             {
2590             //iOutgoingMsgQueue.pop();
2591             }
2592                 */
2593             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
2594             OSCL_DELETE(iSrvResponse);
2595             iSrvResponse = NULL;
2596             return  PVMFFailure;
2597         }
2598 
2599         bNoSendPending = false;
2600     }
2601     else
2602     {
2603         bSrvRespPending = true;
2604     }
2605 
2606     return PVMFSuccess;
2607 }
2608 
2609 /**
2610 * This API processes server requests with entity bodies.
2611 *
2612 * @param aMsg The server request.
2613 * @param aEntityMemFrag The oscl memory fragment which holds the entity body.
2614 * @returns PVMF status.
2615 */
processEntityBody(RTSPIncomingMessage & aMsg,OsclMemoryFragment & aEntityMemFrag)2616 PVMFStatus PVRTSPEngineNode::processEntityBody(RTSPIncomingMessage &aMsg, OsclMemoryFragment &aEntityMemFrag)
2617 {   //all S->C are optional, including ANNOUNCE, GET_PARAMETER, SET_PARAMETER, OPTIONS
2618     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::processEntityBody() In"));
2619 
2620     if (iEntityMemFrag.ptr == NULL)
2621     {//the entity body hasn't come yet.
2622         //return PVMFFailure;
2623         return PVMFPending;
2624     }
2625 
2626     if (iSrvResponse == NULL)
2627     {
2628         iSrvResponse =  OSCL_NEW(RTSPOutgoingMessage, ());
2629         if (iSrvResponse == NULL)
2630         {
2631             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
2632             return  PVMFFailure;
2633         }
2634     }
2635 
2636     iSrvResponse->reset();
2637     iSrvResponse->msgType = RTSPResponseMsg;
2638     iSrvResponse->numOfTransportEntries = 0;
2639 
2640     if (aMsg.method == METHOD_SET_PARAMETER)
2641     {//
2642         iSrvResponse->statusCode =  CodeOK;
2643         iSrvResponse->reasonString = "OK";
2644     }
2645     else
2646     {
2647         iSrvResponse->statusCode =  CodeNotImplemented;
2648         iSrvResponse->reasonString = "Not Implemented";
2649     }
2650     //iSrvResponse->statusCode = CodeParameterNotUnderstood;
2651     //iSrvResponse->reasonString = "Parameter Not Understood";
2652     iSrvResponse->cseq = aMsg.cseq;
2653     iSrvResponse->cseqIsSet = true;
2654 
2655     if (iSessionInfo.iSID.get_size())
2656     {
2657         iSrvResponse->sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
2658         iSrvResponse->sessionIdIsSet = true;
2659     }
2660     if (iSrvResponse->compose() == false)
2661     {
2662         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPCompose501ResponseError;
2663         OSCL_DELETE(iSrvResponse);
2664         iSrvResponse = NULL;
2665         return PVMFFailure;
2666     }
2667 
2668     if (bNoSendPending)// bSrvRespPending
2669     {
2670         if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *iSrvResponse))
2671         {
2672             /* need to pop the msg based on cseq, NOT necessarily the early ones,
2673             although YES in this case.
2674             //for(int idx=0; idx < iSessionInfo.trackSelectionList->getNumTracks(); idx++ )
2675             for(int idx=0; idx < iSessionInfo.iSDPinfo->getNumMediaObjects(); idx++ )
2676             {
2677             //iOutgoingMsgQueue.pop();
2678             }
2679                 */
2680             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
2681             OSCL_DELETE(iSrvResponse);
2682             iSrvResponse = NULL;
2683             return  PVMFFailure;
2684         }
2685 
2686         bNoSendPending = false;
2687     }
2688     else
2689     {
2690         bSrvRespPending = true;
2691     }
2692 
2693     PVMFStatus tmpRet = PVMFSuccess;
2694     OSCL_UNUSED_ARG(aEntityMemFrag);
2695     return tmpRet;
2696 }
2697 
2698 
DoStartNode(PVRTSPEngineCommand & aCmd)2699 PVMFStatus PVRTSPEngineNode::DoStartNode(PVRTSPEngineCommand &aCmd)
2700 {
2701     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoStartNode() In"));
2702     OSCL_UNUSED_ARG(aCmd);
2703 
2704     //If session is completed, then do not send the play command to the server..
2705     if (IsSessionCompleted() && !bRepositioning)
2706     {
2707         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoStartNode() Skipping sending play 'cos of session expiry"));
2708         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
2709         return PVMFSuccess;
2710     }
2711 
2712     if (iInterfaceState != EPVMFNodePrepared &&
2713             iInterfaceState != EPVMFNodePaused)
2714     {
2715         return PVMFErrInvalidState;
2716     }
2717 
2718     return  SendRtspPlay(aCmd);
2719 }
2720 
SendRtspPlay(PVRTSPEngineCommand & aCmd)2721 PVMFStatus PVRTSPEngineNode::SendRtspPlay(PVRTSPEngineCommand &aCmd)
2722 {
2723     OSCL_UNUSED_ARG(aCmd);
2724 
2725     PVMFStatus iRet = PVMFPending;
2726     switch (iState)
2727     {
2728         case PVRTSP_ENGINE_NODE_STATE_SETUP_DONE:
2729         case PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE:
2730         {
2731             if (!bNoSendPending)
2732             {
2733                 break;
2734             }
2735             //compose and send PLAY
2736             //if ASF streaming, the SET_PARAMETER should be pipelined as well
2737             RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
2738             if (tmpOutgoingMsg == NULL)
2739             {
2740                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
2741                 iRet =  PVMFFailure;
2742                 break;
2743             }
2744             if (PVMFSuccess != composePlayRequest(*tmpOutgoingMsg))
2745             {
2746                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposePlayRequestError;
2747                 OSCL_DELETE(tmpOutgoingMsg);
2748                 iRet =  PVMFFailure;
2749                 break;
2750             }
2751 
2752             if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
2753             {
2754                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
2755                 OSCL_DELETE(tmpOutgoingMsg);
2756                 iRet =  PVMFFailure;
2757                 break;
2758             }
2759 
2760             bNoSendPending = false;
2761             iOutgoingMsgQueue.push(tmpOutgoingMsg);
2762 
2763             ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_PLAY);
2764             //setup the watch dog for server response
2765             iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG);
2766             RunIfNotReady();
2767             break;
2768         }
2769         case PVRTSP_ENGINE_NODE_STATE_WAIT_PLAY:
2770         {
2771             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
2772             {
2773                 iRet = processIncomingMessage(iIncomingMsg);
2774                 if (iRet != PVMFPending)
2775                 {
2776                     //cancell the watchdog
2777                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
2778                     if (iRet == PVMFSuccess)
2779                     {
2780                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
2781                     }
2782                 }
2783             }
2784             else if (RTSPParser::ENTITY_BODY_IS_READY == iRTSPParserState)
2785             {//got MS TCP RTP packets
2786                 //processSDP(REINTERPRET_CAST(mbchar*, pSDPBuf.ptr), pSDPBuf.len-1);
2787                 //processSDP((mbchar*)pSDPBuf.ptr, pSDPBuf.len-1);
2788                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_DESCRIBE_DONE);
2789                 iRet = processIncomingMessage(iIncomingMsg);
2790                 if (iRet != PVMFPending)
2791                 {
2792                     //cancell the watchdog
2793                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
2794                     if (iRet == PVMFSuccess)
2795                     {
2796                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
2797                     }
2798                 }
2799             }
2800             else if (!clearEventQueue())
2801             {
2802                 //cancell the watchdog
2803                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
2804 
2805                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketError;
2806                 iRet =  PVMFFailure;
2807             }
2808             break;
2809         }
2810 
2811         default:
2812         {
2813             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::SendRtspPlay() iState=%d Line %d", iState, __LINE__));
2814             iRet = PVMFErrInvalidState;
2815             break;
2816         }
2817     }
2818 
2819     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspPlay() Out"));
2820     return iRet;
2821 }
2822 
composeSetupRequest(RTSPOutgoingMessage & iMsg,StreamInfo & aSelected)2823 PVMFStatus PVRTSPEngineNode::composeSetupRequest(RTSPOutgoingMessage &iMsg, StreamInfo &aSelected)
2824 {
2825     //Reset the data structure
2826     iMsg.reset();
2827 
2828     if (iSessionInfo.iSDPinfo.GetRep() == NULL) return PVMFFailure;
2829 
2830     //Here we decide if the selected track is a still image or not
2831     mediaInfo *tmpMediaInfo = iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(aSelected.iSDPStreamId);
2832     if (NULL == tmpMediaInfo)
2833     {
2834         return PVMFFailure;
2835     }
2836     StrCSumPtrLen still_image = "X-MP4V-IMAGE";
2837     if (!oscl_strncmp(tmpMediaInfo->getMIMEType(), still_image.c_str(), still_image.length()))
2838     {
2839         StrPtrLen contentType = "text/parameters";
2840         StrCSumPtrLen image = "Image\r\n";
2841 
2842         iMsg.contentType = contentType;
2843         iMsg.contentTypeIsSet = true;
2844         iMsg.contentLength = image.length();
2845         iMsg.contentLengthIsSet = true;
2846         iMsg.accept = "X-MP4V-IMAGE";
2847         iMsg.acceptIsSet = true;
2848         iMsg.method = METHOD_GET_PARAMETER;
2849         iMsg.numOfTransportEntries = 0;
2850 
2851         /*
2852         mbchar mediaURL[RTSP_MAX_FULL_REQUEST_SIZE];
2853         mediaURL[0] = '\0';
2854 
2855           oscl_strncpy( mediaURL,
2856           ( iSessionInfo.contentBaseFlag )? iSessionInfo.contentBaseURL:requestURL,
2857           oscl_strlen(( iSessionInfo.contentBaseFlag )? iSessionInfo.contentBaseURL:requestURL) );
2858           mediaURL[oscl_strlen(( iSessionInfo.contentBaseFlag )? iSessionInfo.contentBaseURL:requestURL)] = '\0';
2859           iMsg.originalURI = mediaURL;
2860         */
2861     }
2862     else
2863     {
2864         //Set standard fields
2865         iMsg.method = METHOD_SETUP;
2866         iMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
2867         iMsg.userAgentIsSet = true;
2868 
2869         {
2870             iMsg.numOfTransportEntries = 1;
2871             iMsg.transport[0].protocol = RtspTransport::RTP_PROTOCOL;
2872             iMsg.transport[0].protocolIsSet = true;
2873             iMsg.transport[0].profile = RtspTransport::AVP_PROFILE;
2874             iMsg.transport[0].profileIsSet = true;
2875             iMsg.transport[0].delivery = RtspTransport::UNICAST_DELIVERY;
2876             iMsg.transport[0].deliveryIsSet = true;
2877             if ((iSessionInfo.iStreamingType == PVRTSP_3GPP_UDP)
2878                     || (iSessionInfo.iStreamingType == PVRTSP_MS_UDP))
2879             {
2880                 iMsg.transport[0].transportType = RtspTransport::UDP_TRANSPORT;
2881                 iMsg.transport[0].transportTypeIsSet = true;
2882 
2883                 iMsg.transport[0].channelIsSet = false;
2884 
2885                 iMsg.transport[0].client_portIsSet = true;
2886                 iMsg.transport[0].client_port1 = OSCL_STATIC_CAST(uint16, aSelected.iCliRTPPort);   //dataPort;
2887                 iMsg.transport[0].client_port2 = OSCL_STATIC_CAST(uint16, aSelected.iCliRTCPPort);  //feedbackPort;
2888 
2889                 if (iSessionInfo.iStreamingType == PVRTSP_MS_UDP)
2890                 {//check here!
2891                     iMsg.transport[0].client_port2 = 0;
2892                 }
2893 
2894                 /* Send recommended block size of RTP packet to the server.  CJ 09/10/2001 */
2895                 StrCSumPtrLen blockSize = "Blocksize";
2896                 oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr), iRTSPEngTmpBuf.len, "%d", RECOMMENDED_RTP_BLOCK_SIZE);
2897                 iMsg.addField(&blockSize, ((mbchar*)iRTSPEngTmpBuf.ptr));
2898             }
2899             else
2900             {
2901                 iMsg.transport[0].transportType = RtspTransport::TCP_TRANSPORT;
2902                 iMsg.transport[0].transportTypeIsSet = true;
2903 
2904                 iMsg.transport[0].client_portIsSet = false;
2905 
2906                 iMsg.transport[0].channelIsSet = false;
2907                 //iMsg.transport[0].channel1 = 8888;//aSelected.iSerRTPPort;
2908                 //iMsg.transport[0].channel2 = 9999;//aSelected.iSerRTCPPort;
2909             }
2910 
2911             iMsg.transport[0].appendIsSet = false;
2912             iMsg.transport[0].layersIsSet = false;
2913             iMsg.transport[0].modeIsSet = false;
2914             iMsg.transport[0].portIsSet = false;
2915             iMsg.transport[0].server_portIsSet = false;
2916             iMsg.transport[0].ttlIsSet = false;
2917             iMsg.transport[0].ssrcIsSet = false;
2918         }
2919 
2920         {/*
2921             StrCSumPtrLen mytransport = "Transport";
2922             iMsg.addField(&mytransport, "x-real-rdt/udp;client_port=6970");
2923             iMsg.numOfTransportEntries = 0;
2924             */
2925         }
2926         //Compose etag
2927         if (oscl_strlen((iSessionInfo.iSDPinfo->getSessionInfo())->getETag()) != 0)
2928         {
2929             if (oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr), iRTSPEngTmpBuf.len, "\"%s\"", (iSessionInfo.iSDPinfo->getSessionInfo())->getETag()) != 1)
2930             {
2931                 StrCSumPtrLen etag = "If-Match";
2932                 iMsg.addField(&etag, ((mbchar*)iRTSPEngTmpBuf.ptr));
2933             }
2934         }
2935 
2936         if (oscl_strlen(iSessionInfo.iUserNetwork.get_cstr()))
2937         {
2938             StrCSumPtrLen UserNetwork = _STRLIT_CHAR("User-Network");
2939             iMsg.addField(&UserNetwork, iSessionInfo.iUserNetwork.get_cstr());
2940         }
2941         if (oscl_strlen(iSessionInfo.iDeviceInfo.get_cstr()))
2942         {
2943             StrCSumPtrLen DeviceInfo = _STRLIT_CHAR("DeviceInfo");
2944             iMsg.addField(&DeviceInfo, iSessionInfo.iDeviceInfo.get_cstr());
2945         }
2946         if (oscl_strlen(iSessionInfo.iUserID.get_cstr()) && oscl_strlen(iSessionInfo.iAuthentication.get_cstr()))
2947         {
2948             OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("user=");
2949             myBuf += iSessionInfo.iUserID.get_cstr();
2950             myBuf += ";authentication=";
2951             myBuf += iSessionInfo.iAuthentication.get_cstr();
2952 
2953             StrCSumPtrLen User_id = _STRLIT_CHAR("ID");
2954             iMsg.addField(&User_id, myBuf.get_cstr());
2955         }
2956         if (oscl_strlen(iSessionInfo.iExpiration.get_cstr()))
2957         {
2958             StrCSumPtrLen Expiration = _STRLIT_CHAR("Expiration");
2959             iMsg.addField(&Expiration, iSessionInfo.iExpiration.get_cstr());
2960         }
2961         if (oscl_strlen(iSessionInfo.iApplicationSpecificString.get_cstr()))
2962         {
2963             StrCSumPtrLen Application_specific_string = _STRLIT_CHAR("Application-Specific-String");
2964             iMsg.addField(&Application_specific_string, iSessionInfo.iApplicationSpecificString.get_cstr());
2965         }
2966         if (iSessionInfo.iVerification.get_size() && iSessionInfo.iSignature.get_size())
2967         {
2968             OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("filler=");
2969             myBuf += iSessionInfo.iVerification.get_cstr();
2970             myBuf += ";signature=";
2971             myBuf += iSessionInfo.iSignature.get_cstr();
2972 
2973             StrCSumPtrLen Verification = _STRLIT_CHAR("Verification");
2974             iMsg.addField(&Verification, myBuf.get_cstr());
2975         }
2976 
2977         //Compose the media level URL for use in a RTSP request message.
2978         if (composeMediaURL(aSelected.iSDPStreamId, iMsg.originalURI) != PVMFSuccess)
2979         {
2980             return PVMFFailure;
2981         }
2982         aSelected.iMediaURI = iMsg.originalURI.c_str();
2983 
2984         if (aSelected.b3gppAdaptationIsSet)
2985         {// 3GPP release-6 rate adaptation
2986             mbchar buffer[256];
2987 
2988             OSCL_HeapString<PVRTSPEngineNodeAllocator> myBuf("url=\"");
2989             myBuf += iMsg.originalURI.c_str();
2990             myBuf += "\";size=";
2991             oscl_snprintf(buffer, 256, "%d", aSelected.iBufSize);
2992             myBuf += buffer;
2993             myBuf += ";target-time=";
2994             oscl_snprintf(buffer, 256, "%d", aSelected.iTargetTime);
2995             myBuf += buffer;
2996 
2997             StrCSumPtrLen _3GPPadaptation = "3GPP-Adaptation";
2998             iMsg.addField(&_3GPPadaptation, myBuf.get_str());
2999         }
3000     }
3001 
3002     iMsg.msgType = RTSPRequestMsg;
3003     iMsg.cseq = iOutgoingSeq++;
3004     iMsg.cseqIsSet = true;
3005 
3006     //OSCL_StackString<32> tmpSID = _STRLIT_CHAR("d5ac74e39ac8d75f");
3007     //iSessionInfo.iSID.set(tmpSID.get_cstr(), tmpSID.get_size());
3008 
3009     if (iSessionInfo.iSID.get_size())
3010     {
3011         iMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
3012         iMsg.sessionIdIsSet = true;
3013     }
3014 
3015     if (iMsg.compose() == false)
3016     {
3017         return PVMFFailure;
3018     }
3019 
3020     iSessionInfo.clientServerDelay = 0;
3021     uint32 clock = 0;
3022     bool overflowFlag = false;
3023     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
3024     iSessionInfo.clientServerDelay = clock;
3025 
3026     return PVMFSuccess;
3027 }
3028 
composePlayRequest(RTSPOutgoingMessage & aMsg)3029 PVMFStatus PVRTSPEngineNode::composePlayRequest(RTSPOutgoingMessage &aMsg)
3030 {
3031     aMsg.reset();
3032     aMsg.numOfTransportEntries = 0;
3033     aMsg.msgType = RTSPRequestMsg;
3034     aMsg.method = METHOD_PLAY;
3035     aMsg.cseq = iOutgoingSeq++;
3036     aMsg.cseqIsSet = true;
3037 
3038     if (iSessionInfo.iSID.get_size())
3039     {
3040         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
3041         aMsg.sessionIdIsSet = true;
3042     }
3043 
3044     //Add range field only if it is a PLAY request
3045     //if( (iState != EResumeSession) && (!upstreamClient) )
3046     if ((iState != PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE)
3047             || (bRepositioning)
3048             || (iInterfaceState == EPVMFNodePrepared))
3049         //if( iState == PVRTSP_ENGINE_NODE_STATE_SETUP_DONE )
3050     {
3051         bRepositioning = false;
3052         OSCL_StackString<8> npt = _STRLIT_CHAR("npt=");
3053         oscl_strncpy(((mbchar*)iRTSPEngTmpBuf.ptr), npt.get_cstr(), npt.get_size());
3054         ((mbchar*)iRTSPEngTmpBuf.ptr)[npt.get_size()] = '\0';
3055 
3056         if (iSessionInfo.iReqPlayRange.format == RtspRangeType::NPT_RANGE)
3057         {
3058             if (iSessionInfo.iReqPlayRange.start_is_set == true)
3059             {
3060                 if (iSessionInfo.iReqPlayRange.npt_start.npt_format == NptTimeFormat::NPT_SEC)
3061                 {
3062                     oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr) + oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)), \
3063                                   (64 - oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr))), "%d.%03d-", \
3064                                   iSessionInfo.iReqPlayRange.npt_start.npt_sec.sec, iSessionInfo.iReqPlayRange.npt_start.npt_sec.milli_sec);
3065                 }
3066                 else if (iSessionInfo.iReqPlayRange.npt_start.npt_format == NptTimeFormat::NOW)
3067                 {
3068                     oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr) + oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)), \
3069                                   (64 - oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr))), "now-");
3070                 }
3071                 else
3072                 {
3073                     return PVMFFailure;
3074                 }
3075             }
3076 
3077             if (iSessionInfo.iReqPlayRange.end_is_set == true)
3078             {
3079                 if (iSessionInfo.iReqPlayRange.npt_end.npt_format == NptTimeFormat::NPT_SEC)
3080                 {
3081                     if ((iSessionInfo.iReqPlayRange.npt_end.npt_sec.sec != 0)
3082                             || (iSessionInfo.iReqPlayRange.npt_end.npt_sec.milli_sec != 0))
3083                     {
3084                         oscl_snprintf(((mbchar*)iRTSPEngTmpBuf.ptr) + oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)), \
3085                                       (64 - oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr))), "%d.%03d", \
3086                                       iSessionInfo.iReqPlayRange.npt_end.npt_sec.sec, iSessionInfo.iReqPlayRange.npt_end.npt_sec.milli_sec);
3087                     }
3088                 }
3089                 else
3090                 {
3091                     return PVMFFailure;
3092                 }
3093             }
3094 
3095             StrCSumPtrLen Range = _STRLIT_CHAR("Range");
3096             aMsg.addField(&Range, ((mbchar*)iRTSPEngTmpBuf.ptr));
3097         }
3098     }
3099 
3100     {//put user agent in SETUP an PLAY for testing for Real. IOT testing Jun 02, 05
3101         aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
3102         aMsg.userAgentIsSet = true;
3103     }
3104 
3105     if (composeSessionURL(aMsg) != PVMFSuccess)
3106     {
3107         return PVMFFailure;
3108     }
3109 
3110     if (aMsg.compose() == false)
3111     {
3112         return PVMFFailure;
3113     }
3114 
3115     //iSessionInfo.composedMessage = aMsg.retrieveComposedBuffer();
3116 
3117     iSessionInfo.clientServerDelay = 0;
3118     uint32 clock = 0;
3119     bool overflowFlag = false;
3120     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
3121     iSessionInfo.clientServerDelay = clock;
3122 
3123     return PVMFSuccess;
3124 }
3125 
composePauseRequest(RTSPOutgoingMessage & aMsg)3126 PVMFStatus PVRTSPEngineNode::composePauseRequest(RTSPOutgoingMessage &aMsg)
3127 {
3128     aMsg.reset();
3129     aMsg.numOfTransportEntries = 0;
3130     aMsg.msgType = RTSPRequestMsg;
3131     aMsg.method = METHOD_PAUSE;
3132     aMsg.cseq = iOutgoingSeq++;
3133     aMsg.cseqIsSet = true;
3134 
3135     if (iSessionInfo.iSID.get_size())
3136     {
3137         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
3138         aMsg.sessionIdIsSet = true;
3139     }
3140 
3141     {//put user agent in SETUP an PLAY for testing for Real. IOT testing Jun 02, 05
3142         aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
3143         aMsg.userAgentIsSet = true;
3144     }
3145 
3146     if (composeSessionURL(aMsg) != PVMFSuccess)
3147     {
3148         return PVMFFailure;
3149     }
3150 
3151     if (aMsg.compose() == false)
3152     {
3153         return PVMFFailure;
3154     }
3155 
3156     iSessionInfo.clientServerDelay = 0;
3157     uint32 clock = 0;
3158     bool overflowFlag = false;
3159     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
3160     iSessionInfo.clientServerDelay = clock;
3161 
3162     return PVMFSuccess;
3163 }
3164 
3165 
composeStopRequest(RTSPOutgoingMessage & aMsg)3166 PVMFStatus PVRTSPEngineNode::composeStopRequest(RTSPOutgoingMessage &aMsg)
3167 {
3168     aMsg.reset();
3169     aMsg.numOfTransportEntries = 0;
3170     aMsg.msgType = RTSPRequestMsg;
3171     aMsg.method = METHOD_TEARDOWN;
3172     aMsg.cseq = iOutgoingSeq++;
3173     aMsg.cseqIsSet = true;
3174 
3175     aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
3176     aMsg.userAgentIsSet = true;
3177 
3178     if (iSessionInfo.iSID.get_size())
3179     {
3180         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
3181         aMsg.sessionIdIsSet = true;
3182     }
3183 
3184     if (composeSessionURL(aMsg) != PVMFSuccess)
3185     {
3186         return PVMFFailure;
3187     }
3188 
3189     StrCSumPtrLen connection = "Connection";
3190     aMsg.addField(&connection, "close");
3191 
3192     if (aMsg.compose() == false)
3193     {
3194         return PVMFFailure;
3195     }
3196 
3197     iSessionInfo.clientServerDelay = 0;
3198     uint32 clock = 0;
3199     bool overflowFlag = false;
3200     iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
3201     iSessionInfo.clientServerDelay = clock;
3202 
3203     return PVMFSuccess;
3204 }
3205 
3206 /*
3207 * Function : PVMFStatus composeSessionURL()
3208 * Date     : 10/30/2002
3209 * Purpose  : Composing a session level URL for use in a RTSP request message.
3210 * In/out   :
3211 * Return   : PVMFSuccess upon succeessful composition. PVMFFailure otherwise.
3212 * Modified :
3213 */
composeSessionURL(RTSPOutgoingMessage & aMsg)3214 PVMFStatus PVRTSPEngineNode::composeSessionURL(RTSPOutgoingMessage &aMsg)
3215 {
3216     OSCL_StackString<16> rtsp_str = _STRLIT_CHAR("rtsp");
3217     const char *sdpSessionURL = (iSessionInfo.iSDPinfo->getSessionInfo())->getControlURL();
3218     if (sdpSessionURL == NULL)
3219     {
3220         return PVMFFailure;
3221     }
3222 
3223     //1. SDP from DESCRIBE response
3224     if (iSessionInfo.bExternalSDP)
3225     {
3226         if (!oscl_strncmp(sdpSessionURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
3227         {
3228             aMsg.originalURI = sdpSessionURL;
3229             return PVMFSuccess;
3230         }
3231         return PVMFFailure;
3232     }
3233     else
3234     {
3235         char *baseURL;
3236         if (iSessionInfo.iContentBaseURL.get_size())
3237         {
3238             baseURL = iSessionInfo.iContentBaseURL.get_str();
3239         }
3240         else
3241         {
3242             baseURL = iSessionInfo.iSessionURL.get_str();
3243         }
3244 
3245         //Case where control url is *
3246         ((mbchar*)iRTSPEngTmpBuf.ptr)[0] = '\0';
3247         uint tmpLen = iRTSPEngTmpBuf.len;
3248         mbchar asterisk[] = {"*"};
3249         if (!oscl_strncmp(sdpSessionURL, asterisk, oscl_strlen(asterisk)))
3250         {
3251             oscl_strncpy(((mbchar*)iRTSPEngTmpBuf.ptr), baseURL, oscl_strlen(baseURL));
3252             ((mbchar*)iRTSPEngTmpBuf.ptr)[oscl_strlen(baseURL)] = '\0';
3253 
3254             if (((mbchar*)iRTSPEngTmpBuf.ptr)[oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)) - 1] == '/')
3255             {
3256                 ((mbchar*)iRTSPEngTmpBuf.ptr)[oscl_strlen(((mbchar*)iRTSPEngTmpBuf.ptr)) - 1] = '\0';
3257             }
3258             aMsg.originalURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
3259         }
3260         //Case where control url is absolute
3261         else if (!oscl_strncmp(sdpSessionURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
3262         {
3263             aMsg.originalURI = sdpSessionURL;
3264         }
3265         //other cases
3266         else if (composeURL((const char *)baseURL, sdpSessionURL, \
3267                             ((mbchar*)iRTSPEngTmpBuf.ptr), tmpLen) == true)
3268         {
3269             aMsg.originalURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
3270         }
3271         else
3272         {
3273             return PVMFFailure;
3274         }
3275     }
3276     return PVMFSuccess;
3277 }
3278 
composeMediaURL(int aTrackID,StrPtrLen & aMediaURI)3279 PVMFStatus PVRTSPEngineNode::composeMediaURL(int aTrackID, StrPtrLen &aMediaURI)
3280 {
3281     OSCL_StackString<16> rtsp_str = _STRLIT_CHAR("rtsp");
3282 
3283     const char *sdpMediaURL = (iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(aTrackID))->getControlURL();
3284     if (sdpMediaURL == NULL)
3285     {
3286         return PVMFFailure;
3287     }
3288 
3289     if (!oscl_strncmp(sdpMediaURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
3290     {
3291         {
3292             aMediaURI = sdpMediaURL;
3293         }
3294 
3295     }
3296     else
3297     {
3298         const char *sdpSessionURL = (iSessionInfo.iSDPinfo->getSessionInfo())->getControlURL();
3299 
3300         if (!oscl_strncmp(sdpSessionURL, rtsp_str.get_cstr(), rtsp_str.get_size()))
3301         {
3302             ((mbchar*)iRTSPEngTmpBuf.ptr)[0] = '\0';
3303             uint tmpLen = iRTSPEngTmpBuf.len;
3304 
3305             if (composeURL(sdpSessionURL, sdpMediaURL,
3306                            ((mbchar*)iRTSPEngTmpBuf.ptr), tmpLen) != true)
3307             {
3308                 return PVMFFailure;
3309             }
3310 
3311             aMediaURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
3312         }
3313         //Compose absolute URL
3314         else
3315         {
3316             char *baseURL;
3317             if (iSessionInfo.iContentBaseURL.get_size())
3318             {
3319                 baseURL = iSessionInfo.iContentBaseURL.get_str();
3320             }
3321             else
3322             {
3323                 baseURL = iSessionInfo.iSessionURL.get_str();
3324             }
3325 
3326             {
3327                 uint tmpLen = iRTSPEngTmpBuf.len;
3328                 if (composeURL((const char *)baseURL,
3329                                sdpMediaURL,
3330                                ((mbchar*)iRTSPEngTmpBuf.ptr), tmpLen) != true)
3331                 {
3332                     return PVMFFailure;
3333                 }
3334             }
3335             aMediaURI = ((mbchar*)iRTSPEngTmpBuf.ptr);
3336         }
3337     }
3338     return PVMFSuccess;
3339 }
3340 
processCommonResponse(RTSPIncomingMessage & aMsg)3341 PVMFStatus PVRTSPEngineNode::processCommonResponse(RTSPIncomingMessage &aMsg)
3342 {
3343     /*Parse content base - this is needed to compose URLs for future RTSP requests*/
3344 
3345     if (iSessionInfo.iContentBaseURL.get_size() == 0)
3346     {
3347         if (aMsg.contentBase.length())
3348         {
3349             OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpBaseURL(aMsg.contentBase.c_str(), aMsg.contentBase.length());
3350             iSessionInfo.iContentBaseURL = tmpBaseURL;
3351         }
3352         else
3353         {
3354             const StrPtrLen *tmpBaseURLLoc = aMsg.queryField("Content-Location");
3355             if (tmpBaseURLLoc)
3356             {
3357                 OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpBaseURL(tmpBaseURLLoc->c_str(), tmpBaseURLLoc->length());
3358                 iSessionInfo.iContentBaseURL = tmpBaseURL;
3359             }
3360         }
3361     }
3362 
3363     /*Extract session id from the server response. This is done only once per session and the following condition ensures it. */
3364     //might need to check the SID match
3365     if ((aMsg.sessionIdIsSet) && (iSessionInfo.iSID.get_size() == 0))
3366     {
3367         //because the RTSP parser just gives "d2ecb87b0816b4a;timeout=60"
3368         char *timeout_location = OSCL_CONST_CAST(char*, oscl_strstr(aMsg.sessionId.c_str(), ";timeout"));
3369         if (NULL != timeout_location)
3370         {
3371             OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpSID(aMsg.sessionId.c_str(), timeout_location - aMsg.sessionId.c_str());
3372             iSessionInfo.iSID = tmpSID;
3373 
3374             //should be timeout-RTT.
3375             int32 tmpTimeout = (aMsg.timeout - 5);
3376             if ((TIMEOUT_KEEPALIVE > tmpTimeout) && (tmpTimeout > 0))
3377             {
3378                 TIMEOUT_KEEPALIVE = tmpTimeout;
3379             }
3380         }
3381         else
3382         {
3383             OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpSID(aMsg.sessionId.c_str(), aMsg.sessionId.length());
3384             iSessionInfo.iSID = tmpSID;
3385         }
3386         iSessionInfo.tSIDIsSetFlag = true;
3387     }
3388 
3389     /*Parse preroll duration from server response (if available)*/
3390     iSessionInfo.prerollDuration = 0;
3391 
3392     const StrPtrLen *tmpBufSize = aMsg.queryField("Buffersize");
3393 
3394     if (tmpBufSize != NULL)
3395     {
3396         //        pSessionInfo->prerollDuration = atoi( aMsg.queryField(buffer)->getPtr() );
3397         uint32 atoi_tmp;
3398         PV_atoi(tmpBufSize->c_str(), 'd', atoi_tmp);
3399         iSessionInfo.prerollDuration = atoi_tmp;
3400     }
3401 
3402     /*
3403      * Check for PVServer - needed to perform firewall port remapping
3404      */
3405     const StrPtrLen *serverTag = aMsg.queryField("Server");
3406     OSCL_StackString<8> pvServerTag(_STRLIT_CHAR("PVSS"));
3407     if (serverTag != NULL)
3408     {
3409         uint32 minLen = OSCL_MIN((pvServerTag.get_size()), ((uint32)(serverTag->size())));
3410         if (!oscl_strncmp(serverTag->c_str(), pvServerTag.get_cstr(), minLen))
3411         {
3412             iSessionInfo.pvServerIsSetFlag = true;
3413         }
3414         else
3415         {
3416             iSessionInfo.pvServerIsSetFlag = false;
3417         }
3418     }
3419     /*
3420      * Check for PVServer version number
3421      */
3422     if (NULL != serverTag)
3423     {
3424         if (iSessionInfo.pvServerIsSetFlag)
3425         {
3426             OSCL_StackString<8> pvServerVersionNumberLocator(_STRLIT_CHAR("/"));
3427             const char *versionNumberLocation = oscl_strstr(serverTag->c_str(), pvServerVersionNumberLocator.get_cstr());
3428             if (NULL != versionNumberLocation)
3429             {
3430                 uint32 versionNumber = 0;
3431                 if (PV_atoi(versionNumberLocation + 1, 'd', 1, versionNumber))
3432                 {
3433                     iSessionInfo.iServerVersionNumber = versionNumber;
3434                 }
3435             }
3436         }
3437     }
3438 
3439     return PVMFSuccess;
3440 }
3441 
processIncomingMessage(RTSPIncomingMessage & iIncomingMsg)3442 PVMFStatus PVRTSPEngineNode::processIncomingMessage(RTSPIncomingMessage &iIncomingMsg)
3443 {
3444     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::processIncomingMessage() in"));
3445 
3446     if (RTSPOk != iIncomingMsg.isMalformed())
3447     {
3448         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
3449         return PVMFFailure;
3450     }
3451     if (RTSPRequestMsg == iIncomingMsg.msgType)
3452     {
3453         if (METHOD_BINARY_DATA == iIncomingMsg.method)
3454         {//need to check the rtsp parcom
3455             /*
3456             iIncomingMsg.bufferSize;
3457             iIncomingMsg.contentLength;
3458             iIncomingMsg.fullRequestBuffer;
3459             iIncomingMsg.fullRequestBufferSizeUsed;
3460             */
3461             //iIncomingMsg.reset();
3462             return PVMFPending;
3463         }
3464         //PVMFStatus tmpRet = ( (iIncomingMsg.contentLengthIsSet) && (iIncomingMsg.contentLength > 0) )
3465         PVMFStatus tmpRet = ((iIncomingMsg.contentLengthIsSet))
3466                             ? processEntityBody(iIncomingMsg, iEntityMemFrag)
3467                             : processServerRequest(iIncomingMsg);
3468         return (tmpRet == PVMFSuccess) ? PVMFPending : tmpRet;
3469     }
3470 
3471     if (RTSPResponseMsg != iIncomingMsg.msgType)
3472     {
3473         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorIncorrectRTSPMessageType;
3474         return PVMFFailure;
3475     }
3476 
3477     if (iOutgoingMsgQueue.empty())
3478     {
3479         //we don't expect a response at this moment.
3480         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorUnknownRTSPMessage;
3481         return PVMFFailure;
3482     }
3483 
3484     //pop the outgoing msg queue and see the match
3485     RTSPOutgoingMessage* tmpOutgoingMsg = iOutgoingMsgQueue.top();
3486     if (tmpOutgoingMsg->cseqIsSet)
3487     {
3488         //we always send seq. But just to be sure
3489         if (!iIncomingMsg.cseqIsSet)
3490         {
3491             //server should reply with seq
3492             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMissingSeqNumInServerResponse;
3493             return PVMFFailure;
3494         }
3495         if (tmpOutgoingMsg->cseq != iIncomingMsg.cseq)
3496         {
3497             //FIFO server messed up
3498             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPRequestResponseMismatch;
3499             return PVMFFailure;
3500         }
3501         iOutgoingMsgQueue.pop();
3502     }
3503     else if (tmpOutgoingMsg->method == METHOD_GET)
3504     {//TBD varify this is the http GET response
3505         iOutgoingMsgQueue.pop();
3506     }
3507 
3508     //check session ID as well
3509     if (200 == iIncomingMsg.statusCode)
3510     {
3511         //OK
3512         processCommonResponse(iIncomingMsg);
3513         //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_SETUP_DONE);
3514         //break;
3515 
3516         if (tmpOutgoingMsg->method == METHOD_SETUP)
3517         {
3518             for (uint32 i = 0; i < iSessionInfo.iSelectedStream.size(); i++)
3519             {
3520                 if (!oscl_strncmp(tmpOutgoingMsg->originalURI.c_str(), iSessionInfo.iSelectedStream[i].iMediaURI.get_cstr(), tmpOutgoingMsg->originalURI.length()))
3521                 {
3522                     if (iIncomingMsg.numOfTransportEntries)
3523                     {
3524                         {//For transport options, we only let server choose
3525                             //between "RTP/AVP/UDP" or "x-pn-tng/tcp"; and for "x-pn-tng/tcp",
3526                             //we only do http cloaking. 06/03/21
3527                             ibIsRealRDT = false;
3528                             if ((iIncomingMsg.transport[0].protocol != RtspTransport::RTP_PROTOCOL)
3529                                     || (iIncomingMsg.transport[0].profile != RtspTransport::AVP_PROFILE))
3530                             {//PVMFRTSPClientEngineNodeErrorUnsupportedTransport
3531                                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
3532                                 return PVMFFailure;
3533                             }
3534                         }
3535 
3536                         iSessionInfo.iSelectedStream[i].ssrcIsSet = iIncomingMsg.transport[0].ssrcIsSet;
3537                         if (iIncomingMsg.transport[0].ssrcIsSet)
3538                         {
3539                             iSessionInfo.iSelectedStream[i].iSSRC = iIncomingMsg.transport[0].ssrc;
3540                         }
3541                         if (!(iIncomingMsg.transport[0].server_portIsSet || iIncomingMsg.transport[0].channelIsSet))
3542                         {
3543                             iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
3544                             return PVMFFailure;
3545                         }
3546                         if (iIncomingMsg.transport[0].server_portIsSet)
3547                         {
3548                             iSessionInfo.iSelectedStream[i].iSerRTPPort = iIncomingMsg.transport[0].server_port1;   //RTP
3549                             iSessionInfo.iSelectedStream[i].iSerRTCPPort = iIncomingMsg.transport[0].server_port2;  //RTCP
3550                         }
3551                         if (iIncomingMsg.transport[0].channelIsSet)
3552                         {
3553                             iSessionInfo.iSelectedStream[i].iSerRTPPort = iIncomingMsg.transport[0].channel1;   //RTP
3554                             iSessionInfo.iSelectedStream[i].iSerRTCPPort = iIncomingMsg.transport[0].channel2;  //RTCP
3555 
3556                             //since we're here, let's set the channel id for the port as well
3557                             for (int32 j = iPortVector.size() - 1; j >= 0; j--)
3558                             {
3559                                 if (((PVMFRTSPPort*)(iPortVector[j]))->iSdpTrackID == iSessionInfo.iSelectedStream[i].iSDPStreamId)
3560                                 {
3561                                     PVMFRTSPPort *pvPort = (PVMFRTSPPort*)(iPortVector[j]);
3562                                     pvPort->iChannelID = (pvPort->bIsMedia)
3563                                                          ? iSessionInfo.iSelectedStream[i].iSerRTPPort
3564                                                          : iSessionInfo.iSelectedStream[i].iSerRTCPPort;
3565                                     pvPort->bIsChannelIDSet = true;
3566                                 }
3567                             }
3568                         }
3569                         iSessionInfo.iSelectedStream[i].iSerIpAddr.Set(iSessionInfo.iSrvAdd.ipAddr.Str());
3570                     }
3571                     else
3572                     {
3573                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::processIncomingMessage() ERROR iIncomingMsg.numOfTransportEntries = %d Ln %d", iIncomingMsg.numOfTransportEntries, __LINE__));
3574                         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMalformedRTSPMessage;
3575                         return PVMFFailure;
3576                     }
3577                     break;
3578                 }
3579             }
3580 
3581             if (!iSessionInfo.tSIDIsSetFlag)
3582             {
3583                 //server does not send the session ID
3584                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorMissingSessionIdInServerResponse;
3585                 return PVMFFailure;
3586             }
3587             uint32 clock = 0;
3588             bool overflowFlag = false;
3589             iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
3590             clock -= (uint32)iSessionInfo.clientServerDelay;
3591             iSessionInfo.clientServerDelay = clock;
3592             iSessionInfo.roundTripDelay =
3593                 Oscl_Int64_Utils::get_uint64_lower32(iSessionInfo.clientServerDelay);
3594         }
3595         else if (tmpOutgoingMsg->method == METHOD_PLAY)
3596         {
3597             if (iSessionInfo.iActPlayRange.format == RtspRangeType::INVALID_RANGE)
3598             {//play
3599                 iSessionInfo.iActPlayRange  = iSessionInfo.iReqPlayRange;
3600             }
3601 
3602             if (iIncomingMsg.rangeIsSet)
3603             {
3604                 if ((iSessionInfo.iActPlayRange.format == iIncomingMsg.range.format)
3605                         && (iIncomingMsg.range.format == RtspRangeType::NPT_RANGE))
3606                 {
3607                     if (iIncomingMsg.range.start_is_set)
3608                     {
3609                         iSessionInfo.iActPlayRange.start_is_set = true;
3610                         iSessionInfo.iActPlayRange.npt_start    = iIncomingMsg.range.npt_start;
3611                     }
3612                     if (iIncomingMsg.range.end_is_set)
3613                     {
3614                         iSessionInfo.iActPlayRange.end_is_set = true;
3615                         iSessionInfo.iActPlayRange.npt_end  = iIncomingMsg.range.npt_end;
3616                     }
3617                 }
3618                 else
3619                 {//the server actually changes the range format in one session
3620                     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::processIncomingMessage() ERROR iIncomingMsg.range.format = %d Ln %d", iIncomingMsg.range.format, __LINE__));
3621                 }
3622             }
3623 
3624             for (uint32 idx = 0; idx < iIncomingMsg.numOfRtpInfoEntries; idx++)
3625             {
3626                 RTSPRTPInfo *rtpinfo = iIncomingMsg.rtpInfo + idx;
3627                 if (!rtpinfo->urlIsSet)
3628                 {//error
3629                     //break;
3630                 }
3631                 char *url_temp = (char *) rtpinfo->url.c_str();
3632                 //int url_len = rtpinfo->url.length() + 1;//Added to prevent erroneous track selection.
3633 
3634                 for (uint32 i = 0; i < iSessionInfo.iSelectedStream.size(); i++)
3635                 {
3636                     int sdp_track_id = iSessionInfo.iSelectedStream[i].iSDPStreamId;
3637                     //simplified check here.
3638                     if (NULL == oscl_strstr((iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(sdp_track_id))->getControlURL(), url_temp))
3639                     {
3640                         if (NULL == oscl_strstr(url_temp, (iSessionInfo.iSDPinfo->getMediaInfoBasedOnID(sdp_track_id))->getControlURL()))
3641                         {
3642                             continue;
3643                         }
3644                     }
3645                     iSessionInfo.iSelectedStream[i].seqIsSet = rtpinfo->seqIsSet;
3646                     iSessionInfo.iSelectedStream[i].seq = rtpinfo->seq;
3647                     iSessionInfo.iSelectedStream[i].rtptimeIsSet = rtpinfo->rtptimeIsSet;
3648                     iSessionInfo.iSelectedStream[i].rtptime = rtpinfo->rtptime;
3649                     iSessionInfo.iSelectedStream[i].iSerIpAddr.Set(iSessionInfo.iSrvAdd.ipAddr.Str());
3650                 }
3651             }
3652             uint32 clock = 0;
3653             bool overflowFlag = false;
3654             iRoundTripClockTimeBase.GetCurrentTime32(clock, overflowFlag, PVMF_MEDIA_CLOCK_MSEC);
3655             clock -= (uint32)iSessionInfo.clientServerDelay;
3656             iSessionInfo.clientServerDelay = clock;
3657             iSessionInfo.roundTripDelay =
3658                 Oscl_Int64_Utils::get_uint64_lower32(iSessionInfo.clientServerDelay);
3659         }
3660         else if (tmpOutgoingMsg->method == iKeepAliveMethod)
3661         {
3662             if ((iState == PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE) ||
3663                     ((bKeepAliveInPlay) && (iState == PVRTSP_ENGINE_NODE_STATE_PLAY_DONE)))
3664             {
3665                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::processIncomingMessage() start keep-alive timer %d. Ln %d", TIMEOUT_KEEPALIVE, __LINE__));
3666                 iWatchdogTimer->Request(REQ_TIMER_KEEPALIVE_ID, 0, TIMEOUT_KEEPALIVE);
3667             }
3668         }
3669 
3670         if (tmpOutgoingMsg)
3671             OSCL_DELETE(tmpOutgoingMsg);
3672     }
3673     else if ((iIncomingMsg.statusCode >= 300) && (iIncomingMsg.statusCode < 400))
3674     {
3675         //redirect
3676         int32 infocode;
3677         MapRTSPCodeToEventCode(iIncomingMsg.statusCode, infocode);
3678         ReportInfoEvent(PVMFInfoRemoteSourceNotification, NULL, &iEventUUID, &infocode);
3679         OSCL_DELETE(tmpOutgoingMsg);
3680 
3681         const StrPtrLen *tmpBaseURLLoc = iIncomingMsg.queryField("Location");
3682         //const StrPtrLen *tmpBaseURLLoc = iIncomingMsg.queryField("Content-Location");
3683         if (tmpBaseURLLoc)
3684         {
3685             if (!parseURL(tmpBaseURLLoc->c_str()))
3686             {
3687                 return PVMFFailure;
3688             }
3689         }
3690         else
3691         {
3692             return PVMFFailure;   //If Location is not present in response
3693         }
3694         iErrorRecoveryAttempt = iNumRedirectTrials-- ? 1 : 0;
3695         if (iErrorRecoveryAttempt == 0)
3696         {
3697             iCurrentErrorCode = infocode; // Send error to application
3698             return PVMFFailure;
3699         }
3700         return PVMFInfoRemoteSourceNotification;
3701     }
3702     else
3703     {
3704         if (tmpOutgoingMsg)
3705         {
3706             if (tmpOutgoingMsg->method == METHOD_OPTIONS)
3707             {
3708                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::processIncomingMessage() OPTIONS ERROR %d Line %d", iIncomingMsg.statusCode, __LINE__));
3709                 OSCL_DELETE(tmpOutgoingMsg);
3710                 return iOutgoingMsgQueue.empty() ? PVMFSuccess : PVMFPending;
3711             }
3712         }
3713 
3714         //error
3715         MapRTSPCodeToEventCode(iIncomingMsg.statusCode, iCurrentErrorCode);
3716         OSCL_DELETE(tmpOutgoingMsg);
3717         return PVMFFailure;
3718     }
3719 
3720     return iOutgoingMsgQueue.empty() ? PVMFSuccess : PVMFPending;
3721     //return PVMFSuccess;
3722 }
3723 
MapRTSPCodeToEventCode(RTSPStatusCode aStatusCode,int32 & aEventCode)3724 void PVRTSPEngineNode::MapRTSPCodeToEventCode(RTSPStatusCode aStatusCode,
3725         int32& aEventCode)
3726 {
3727     switch (aStatusCode)
3728     {
3729         case 300:
3730             //"300"      ; Multiple Choices
3731             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode300;
3732             break;
3733         case 301:
3734             //"301"      ; Moved Permanently
3735             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode301;
3736             break;
3737         case 302:
3738             //"302"      ; Moved Temporarily
3739             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode302;
3740             break;
3741         case 303:
3742             //"303"      ; See Other
3743             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode303;
3744             break;
3745         case 304:
3746             //"304"      ; Not Modified
3747             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode304;
3748             break;
3749         case 305:
3750             //"305"      ; Use Proxy
3751             aEventCode = PVMRTSPClientEngineInfoRTSPRedirectCode305;
3752             break;
3753         case 400:
3754             //"400"      ; Bad Request
3755             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode400;
3756             break;
3757         case 401:
3758             //"401"      ; Unauthorized
3759             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode401;
3760             break;
3761         case 402:
3762             //"402"      ; Payment Required
3763             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode402;
3764             break;
3765         case 403:
3766             //"403"      ; Forbidden
3767             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode403;
3768             break;
3769         case 404:
3770             //"404"      ; Not Found
3771             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode404;
3772             break;
3773         case 405:
3774             //"405"      ; Method Not Allowed
3775             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode405;
3776             break;
3777         case 406:
3778             //"406"      ; Not Acceptable
3779             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode406;
3780             break;
3781         case 407:
3782             //"407"      ; Proxy Authentication Required
3783             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode407;
3784             break;
3785         case 408:
3786             //"408"      ; Request Time-out
3787             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode408;
3788             break;
3789         case 410:
3790             //"410"      ; Gone
3791             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode410;
3792             break;
3793         case 411:
3794             //"411"      ; Length Required
3795             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode411;
3796             break;
3797         case 412:
3798             //"412"      ; Precondition Failed
3799             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode412;
3800             break;
3801         case 413:
3802             //"413"      ; Request Entity Too Large
3803             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode413;
3804             break;
3805         case 414:
3806             //"414"      ; Request-URI Too Large
3807             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode414;
3808             break;
3809         case 415:
3810             //"415"      ; Unsupported Media Type
3811             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode415;
3812             break;
3813         case 451:
3814             //"451"      ; Parameter Not Understood
3815             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode451;
3816             break;
3817         case 452:
3818             //"452"      ; Conference Not Found
3819             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode452;
3820             break;
3821         case 453:
3822             //"453"      ; Not Enough Bandwidth
3823             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode453;
3824             break;
3825         case 454:
3826             //"454"      ; Session Not Found
3827             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode454;
3828             break;
3829         case 455:
3830             //"455"      ; Method Not Valid in This State
3831             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode455;
3832             break;
3833         case 456:
3834             //"456"      ; Header Field Not Valid for Resource
3835             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode456;
3836             break;
3837         case 457:
3838             //"457"      ; Invalid Range
3839             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode457;
3840             break;
3841         case 458:
3842             //"458"      ; Parameter Is Read-Only
3843             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode458;
3844             break;
3845         case 459:
3846             //"459"      ; Aggregate operation not allowed
3847             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode459;
3848             break;
3849         case 460:
3850             //"460"      ; Only aggregate operation allowed
3851             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode460;
3852             break;
3853         case 461:
3854             //"461"      ; Unsupported transport
3855             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode461;
3856             break;
3857         case 462:
3858             //"462"      ; Destination unreachable
3859             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode462;
3860             break;
3861         case 500:
3862             //"500"      ; Internal Server Error
3863             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode500;
3864             break;
3865         case 501:
3866             //"501"      ; Not Implemented
3867             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode501;
3868             break;
3869         case 502:
3870             //"502"      ; Bad Gateway
3871             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode502;
3872             break;
3873         case 503:
3874             //"503"      ; Service Unavailable
3875             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode503;
3876             break;
3877         case 504:
3878             //"504"      ; Gateway Time-out
3879             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode504;
3880             break;
3881         case 505:
3882             //"505"      ; RTSP Version not supported
3883             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode505;
3884             break;
3885         case 551:
3886             //"551"      ; Option not supported
3887             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPErrorCode551;
3888             break;
3889         default:
3890             // Unknown
3891             aEventCode = PVMFRTSPClientEngineNodeErrorRTSPCodeUnknown;
3892             break;
3893     }
3894 }
3895 
DoPauseNode(PVRTSPEngineCommand & aCmd)3896 PVMFStatus PVRTSPEngineNode::DoPauseNode(PVRTSPEngineCommand &aCmd)
3897 {
3898     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoPauseNode() In"));
3899 
3900     //If session is completed, then do not send the pause command to the server..
3901     if (IsSessionCompleted())
3902     {
3903         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoPauseNode() Skipping sending pause 'cos of session expiry"));
3904         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
3905         return PVMFSuccess;
3906     }
3907 
3908     if (iInterfaceState != EPVMFNodeStarted)
3909     {
3910         return PVMFErrInvalidState;
3911     }
3912     return SendRtspPause(aCmd);
3913 }
3914 
DoStopNode(PVRTSPEngineCommand & aCmd)3915 PVMFStatus PVRTSPEngineNode::DoStopNode(PVRTSPEngineCommand &aCmd)
3916 {
3917     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoStopNode() In"));
3918 
3919     if ((iInterfaceState != EPVMFNodeStarted) && (iInterfaceState != EPVMFNodePaused))
3920     {
3921         if (iInterfaceState == EPVMFNodeError)
3922         {
3923             return PVMFSuccess;
3924         }
3925         return PVMFErrInvalidState;
3926     }
3927     return SendRtspTeardown(aCmd);
3928 }
3929 
SendRtspPause(PVRTSPEngineCommand & aCmd)3930 PVMFStatus PVRTSPEngineNode::SendRtspPause(PVRTSPEngineCommand &aCmd)
3931 {
3932     OSCL_UNUSED_ARG(aCmd);
3933 
3934     PVMFStatus iRet = PVMFPending;
3935     switch (iState)
3936     {
3937         case PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE:
3938         {
3939             iRet = PVMFSuccess;
3940             break;
3941         }
3942         case PVRTSP_ENGINE_NODE_STATE_PLAY_DONE:
3943         {
3944             if (bNoSendPending)
3945             {
3946                 RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
3947                 if (tmpOutgoingMsg == NULL)
3948                 {
3949                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
3950                     return  PVMFFailure;
3951                 }
3952 
3953                 if (PVMFSuccess != composePauseRequest(*tmpOutgoingMsg))
3954                 {
3955                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposePauseRequestError;
3956                     OSCL_DELETE(tmpOutgoingMsg);
3957                     return  PVMFFailure;
3958                 }
3959 
3960                 if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
3961                 {
3962                     /* need to pop the msg based on cseq, NOT necessarily the early ones,
3963                     although YES in this case.
3964                     //for(int idx=0; idx < iSessionInfo.trackSelectionList->getNumTracks(); idx++ )
3965                     for(int idx=0; idx < iSessionInfo.iSDPinfo->getNumMediaObjects(); idx++ )
3966                     {
3967                     //iOutgoingMsgQueue.pop();
3968                     }
3969                         */
3970                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
3971                     OSCL_DELETE(tmpOutgoingMsg);
3972                     iRet =  PVMFFailure;
3973                     break;
3974                 }
3975 
3976                 bNoSendPending = false;
3977                 iOutgoingMsgQueue.push(tmpOutgoingMsg);
3978                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_PAUSE);
3979 
3980                 //setup the watch dog for server response
3981                 iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG);
3982             }
3983             break;
3984         }
3985         case PVRTSP_ENGINE_NODE_STATE_WAIT_PAUSE:
3986         {
3987             if (RTSPParser::REQUEST_IS_READY == iRTSPParserState)
3988             {
3989                 iRet = processIncomingMessage(iIncomingMsg);
3990                 if (iRet != PVMFPending)
3991                 {
3992                     //cancell the watchdog
3993                     iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
3994                     if (iRet == PVMFSuccess)
3995                     {
3996                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
3997                     }
3998                     else if ((iRet == PVMFFailure) && (iCurrentErrorCode == PVMFRTSPClientEngineNodeErrorRTSPErrorCode455))
3999                     {//"455"      ; Method Not Valid in This State
4000                         iRet = PVMFSuccess;
4001                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
4002                     }
4003                     else
4004                     {   //revert to previous state,
4005                         //which means don't change to EPVMFNodeError state
4006                         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PLAY_DONE);
4007                     }
4008                 }
4009             }
4010             else if (RTSPParser::ENTITY_BODY_IS_READY == iRTSPParserState)
4011             {//got MS TCP RTP packets
4012                 //processSDP(REINTERPRET_CAST(mbchar*, pSDPBuf.ptr), pSDPBuf.len-1);
4013                 //processSDP((mbchar*)pSDPBuf.ptr, pSDPBuf.len-1);
4014                 //ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_DESCRIBE_DONE);
4015                 iRet =  PVMFSuccess;
4016             }
4017             else if (!clearEventQueue())
4018             {
4019                 //cancell the watchdog
4020                 iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
4021 
4022                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketError;
4023                 iRet =  PVMFFailure;
4024             }
4025             break;
4026         }
4027         default:
4028         {
4029             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::SendRtspPause() iState=%d Line %d", iState, __LINE__));
4030             iRet = PVMFErrInvalidState;
4031             break;
4032         }
4033     }
4034 
4035     return iRet;
4036 }
4037 
DoResetNode(PVRTSPEngineCommand & aCmd)4038 PVMFStatus PVRTSPEngineNode::DoResetNode(PVRTSPEngineCommand &aCmd)
4039 {
4040     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoResetNode() In"));
4041     if (iGetPostCorrelationObject != NULL)
4042     {
4043         OSCL_DELETE(iGetPostCorrelationObject);
4044         iGetPostCorrelationObject = NULL;
4045     }
4046     return SendRtspTeardown(aCmd);
4047 }
4048 
4049 
SendRtspTeardown(PVRTSPEngineCommand & aCmd)4050 PVMFStatus PVRTSPEngineNode::SendRtspTeardown(PVRTSPEngineCommand &aCmd)
4051 {
4052     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspTeardown() In"));
4053     OSCL_UNUSED_ARG(aCmd);
4054     /* Allow reset from any state */
4055     PVMFStatus iRet = PVMFPending;
4056     switch (iState)
4057     {
4058         case PVRTSP_ENGINE_NODE_STATE_SETUP_DONE:
4059         case PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE:
4060         case PVRTSP_ENGINE_NODE_STATE_PLAY_DONE:
4061         {
4062             if (bNoSendPending)
4063             {
4064                 RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
4065                 if (tmpOutgoingMsg == NULL)
4066                 {
4067                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
4068                     return  PVMFFailure;
4069                 }
4070 
4071                 if (PVMFSuccess != composeStopRequest(*tmpOutgoingMsg))
4072                 {
4073                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposeStopRequestError;
4074                     OSCL_DELETE(tmpOutgoingMsg);
4075                     return  PVMFFailure;
4076                 }
4077                 if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
4078                 {
4079                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
4080                     OSCL_DELETE(tmpOutgoingMsg);
4081                     //maybe server closed the connection or some other errors
4082                     bNoRecvPending = false; //prevent doing recv() after the TEARDOWN
4083                     iRet = PVMFSuccess;
4084                     ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
4085                     break;
4086                 }
4087 
4088                 //setup the watchdog for server response
4089                 iWatchdogTimer->Request(REQ_TIMER_WATCHDOG_ID, 0, TIMEOUT_WATCHDOG_TEARDOWN);
4090 
4091                 bNoSendPending = false;
4092                 iOutgoingMsgQueue.push(tmpOutgoingMsg);
4093                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_STOP);
4094             }
4095             break;
4096         }
4097 
4098         case PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK:
4099             if ((iNumHostCallback + iNumConnectCallback + iNumSendCallback + iNumRecvCallback) == 0
4100                     && resetSocket() != PVMFPending)
4101             {
4102                 iRet = PVMFSuccess;
4103                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
4104             }
4105             break;
4106 
4107         case PVRTSP_ENGINE_NODE_STATE_WAIT_STOP:
4108             if (clearEventQueue() && (RTSPParser::REQUEST_IS_READY != iRTSPParserState))
4109             {//no error and didn't get sth, TEARDOWN response or sth else, doesn't matter
4110                 break;
4111             }
4112             //just go to default to cleanup
4113         default:
4114         {
4115             bNoRecvPending = false; //prevent doing recv() after the TEARDOWN
4116             bNoSendPending = false; //prevent doing send() after the TEARDOWN
4117 
4118             clearOutgoingMsgQueue();
4119             iSocketEventQueue.clear();
4120 
4121             PVMFStatus status = resetSocket();
4122 
4123             iWatchdogTimer->Cancel(REQ_TIMER_WATCHDOG_ID);
4124             iWatchdogTimer->Cancel(REQ_TIMER_KEEPALIVE_ID);
4125             REQ_TIMER_WATCHDOG_ID = REQ_TIMER_KEEPALIVE_ID = 0;
4126 
4127             if ((iNumHostCallback + iNumConnectCallback + iNumSendCallback + iNumRecvCallback) == 0
4128                     && status != PVMFPending)
4129             {
4130                 iRet = PVMFSuccess;
4131                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_CONNECT);
4132             }
4133             else
4134             {
4135                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK);
4136             }
4137             break;
4138         }
4139     }
4140 
4141     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SendRtspTeardown() Out"));
4142 
4143     return iRet;
4144 }
4145 
DoQueryUuid(PVRTSPEngineCommand & aCmd)4146 PVMFStatus PVRTSPEngineNode::DoQueryUuid(PVRTSPEngineCommand &aCmd)
4147 {
4148     //This node supports Query UUID from any state
4149 
4150     OSCL_String* mimetype;
4151     Oscl_Vector<PVUuid, PVRTSPEngineNodeAllocator> *uuidvec;
4152     bool exactmatch;
4153     aCmd.PVRTSPEngineCommandBase::Parse(mimetype, uuidvec, exactmatch);
4154 
4155     //Try to match the input mimetype against any of
4156     //the custom interfaces for this node
4157     //Match against custom interface1...
4158     if (*mimetype == PVMF_RTSPENGINENODE_CUSTOM1_MIMETYPE
4159             //also match against base mimetypes for custom interface1,
4160             //unless exactmatch is set.
4161             || (!exactmatch && *mimetype == PVMF_RTSPENGINENODE_MIMETYPE)
4162             || (!exactmatch && *mimetype == PVMF_RTSPENGINENODE_BASEMIMETYPE))
4163     {
4164         uuidvec->push_back(KPVRTSPEngineNodeExtensionUuid);
4165     }
4166 
4167     return PVMFSuccess;
4168 }
4169 
DoQueryInterface(PVRTSPEngineCommand & aCmd)4170 PVMFStatus PVRTSPEngineNode::DoQueryInterface(PVRTSPEngineCommand &aCmd)
4171 {
4172     //This node supports Query Interface from any state
4173 
4174     PVUuid* uuid;
4175     PVInterface** ptr;
4176     aCmd.PVRTSPEngineCommandBase::Parse(uuid, ptr);
4177 
4178     if (*uuid == KPVRTSPEngineNodeExtensionUuid)
4179     {
4180         if (!iExtensionInterface)
4181         {
4182             iExtensionInterface = OSCL_NEW(PVRTSPEngineNodeExtensionInterfaceImpl, (this));
4183             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
4184                             (0, "PVRTSPEngineNode:DoQueryInterface iExtensionInterface %x "
4185                              , iExtensionInterface));
4186         }
4187         if (iExtensionInterface)
4188         {
4189             if (iExtensionInterface->queryInterface(*uuid, *ptr))
4190             {
4191                 return PVMFSuccess;
4192             }
4193             else
4194             {
4195                 return PVMFErrNotSupported;
4196             }
4197         }
4198         else
4199         {
4200             return PVMFErrNoMemory;
4201         }
4202     }
4203     else
4204     {//not supported
4205         *ptr = NULL;
4206         return PVMFErrNotSupported;
4207     }
4208 }
4209 
ReportErrorEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)4210 void PVRTSPEngineNode::ReportErrorEvent(PVMFEventType aEventType,
4211                                         OsclAny* aEventData,
4212                                         PVUuid* aEventUUID,
4213                                         int32* aEventCode)
4214 {
4215     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
4216                     (0, "PVRTSPEngineNode:NodeErrorEvent Type %d Data %d"
4217                      , aEventType, aEventData));
4218 
4219     if (aEventUUID && aEventCode)
4220     {
4221         PVMFBasicErrorInfoMessage* eventmsg =
4222             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
4223         PVMFAsyncEvent asyncevent(PVMFErrorEvent,
4224                                   aEventType,
4225                                   NULL,
4226                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
4227                                   aEventData,
4228                                   NULL,
4229                                   0);
4230         PVMFNodeInterface::ReportErrorEvent(asyncevent);
4231         eventmsg->removeRef();
4232     }
4233     else
4234     {
4235         PVMFNodeInterface::ReportErrorEvent(aEventType, aEventData);
4236     }
4237 }
4238 
ReportInfoEvent(PVMFEventType aEventType,OsclAny * aEventData,PVUuid * aEventUUID,int32 * aEventCode)4239 void PVRTSPEngineNode::ReportInfoEvent(PVMFEventType aEventType,
4240                                        OsclAny* aEventData,
4241                                        PVUuid* aEventUUID,
4242                                        int32* aEventCode)
4243 {
4244     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
4245                     (0, "PVRTSPEngineNode:NodeInfoEvent Type %d Data %d"
4246                      , aEventType, aEventData));
4247 
4248     if (aEventUUID && aEventCode)
4249     {
4250         PVMFBasicErrorInfoMessage* eventmsg =
4251             OSCL_NEW(PVMFBasicErrorInfoMessage, (*aEventCode, *aEventUUID, NULL));
4252         PVMFAsyncEvent asyncevent(PVMFInfoEvent,
4253                                   aEventType,
4254                                   NULL,
4255                                   OSCL_STATIC_CAST(PVInterface*, eventmsg),
4256                                   aEventData,
4257                                   NULL,
4258                                   0);
4259         PVMFNodeInterface::ReportInfoEvent(asyncevent);
4260         eventmsg->removeRef();
4261     }
4262     else
4263     {
4264         PVMFNodeInterface::ReportInfoEvent(aEventType, aEventData);
4265     }
4266 }
4267 
4268 
4269 /////////////////////////////////////////////////////
4270 // Port Processing routines
4271 /////////////////////////////////////////////////////
HandlePortActivity(const PVMFPortActivity & aActivity)4272 void PVRTSPEngineNode::HandlePortActivity(const PVMFPortActivity &aActivity)
4273 {
4274     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
4275                     (0, "0x%x PVRTSPEngineNode::HandlePortActivity: port=0x%x, type=%d IQ=%d OQ=%d",
4276                      this, aActivity.iPort, aActivity.iType, aActivity.iPort->IncomingMsgQueueSize(), aActivity.iPort->OutgoingMsgQueueSize()));
4277     switch (aActivity.iType)
4278     {
4279         case PVMF_PORT_ACTIVITY_OUTGOING_MSG:
4280             //An outgoing message was queued on this port.
4281             //We only need to queue a port activity event on the
4282             //first message.  Additional events will be queued during
4283             //the port processing as needed.
4284             if (aActivity.iPort->OutgoingMsgQueueSize() == 1)
4285                 QueuePortActivity(aActivity);
4286             break;
4287         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_BUSY:
4288             iTheBusyPort = aActivity.iPort;
4289             break;
4290 
4291         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_BUSY:
4292         case PVMF_PORT_ACTIVITY_OUTGOING_QUEUE_READY:
4293             //iTheBusyPort = iTheBusyPort;
4294             break;
4295 
4296         case PVMF_PORT_ACTIVITY_CONNECTED_PORT_READY:
4297             if (iTheBusyPort == aActivity.iPort)
4298             {
4299                 for (int32 i = iPortVector.size() - 1; i >= 0; i--)
4300                 {
4301                     if (((PVMFRTSPPort*)(iPortVector[i]))->OutgoingMsgQueueSize() > 0)
4302                     {
4303                         PVMFPortActivity activity(aActivity.iPort, PVMF_PORT_ACTIVITY_OUTGOING_MSG);
4304                         QueuePortActivity(activity);
4305                     }
4306                 }
4307 
4308                 if (iRTSPParserState == RTSPParser::EMBEDDED_DATA_IS_READY)
4309                 {
4310                     if (!ibBlockedOnFragGroups)
4311                     {
4312                         DispatchEmbeddedData(iIncomingMsg.channelID);
4313                     }
4314                 }
4315                 iTheBusyPort = NULL;
4316             }
4317             break;
4318 
4319         case PVMF_PORT_ACTIVITY_CONNECT:
4320         default:
4321             break;
4322     }
4323 }
4324 
4325 /////////////////////////////////////////////////////
4326 // Port Processing routines
4327 /////////////////////////////////////////////////////
4328 
QueuePortActivity(const PVMFPortActivity & aActivity)4329 void PVRTSPEngineNode::QueuePortActivity(const PVMFPortActivity &aActivity)
4330 {
4331     //queue a new port activity event
4332     int32 err;
4333     OSCL_TRY(err, iPortActivityQueue.push_back(aActivity););
4334     if (err != OsclErrNone)
4335     {
4336         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
4337                         (0, "0x%x PVRTSPEngineNode::QueuePortActivity: Error - iPortActivityQueue.push_back() failed", this));
4338         ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)(aActivity.iPort));
4339     }
4340     else
4341     {
4342         //wake up the AO to process the port activity event.
4343         RunIfNotReady();
4344     }
4345 }
4346 
TimeoutOccurred(int32 timerID,int32 timeoutInfo)4347 void PVRTSPEngineNode::TimeoutOccurred(int32 timerID, int32 timeoutInfo)
4348 {
4349     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::TimeoutOccurred() in timerID=%d", timerID));
4350     OSCL_UNUSED_ARG(timeoutInfo);
4351 
4352     if (!IsAdded())
4353     {//prevent the leave 49. should never get here
4354         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::TimeoutOccurred() ERROR line %d", __LINE__));
4355         return;
4356     }
4357     if ((timerID != REQ_TIMER_WATCHDOG_ID) && (timerID != REQ_TIMER_KEEPALIVE_ID) && (PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK == iState))
4358     {//waiting for the callback to finish the Stop() or Reset()
4359         RunIfNotReady();
4360         return;
4361     }
4362 
4363     if (timerID == REQ_TIMER_WATCHDOG_ID)
4364     {//watchdog
4365         SocketEvent tmpSockEvent;
4366         tmpSockEvent.iSockId    = timerID;
4367         tmpSockEvent.iSockFxn = EPVSocketRecv;
4368         tmpSockEvent.iSockEvent = EPVSocketTimeout;
4369         tmpSockEvent.iSockError = 0;
4370 
4371         iSocketEventQueue.push_back(tmpSockEvent);
4372         RunIfNotReady();
4373     }
4374     else if (timerID == REQ_TIMER_KEEPALIVE_ID)
4375     {//keep-alive
4376         if ((bNoSendPending) &&
4377                 ((iState == PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE)
4378                  || ((bKeepAliveInPlay) && (iState == PVRTSP_ENGINE_NODE_STATE_PLAY_DONE))))
4379         {
4380             RTSPOutgoingMessage *tmpOutgoingMsg =  OSCL_NEW(RTSPOutgoingMessage, ());
4381             if (tmpOutgoingMsg == NULL)
4382             {
4383                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::TimeoutOccurred ERROR out-of-memory. Ln %d", __LINE__));
4384                 //iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
4385                 return;
4386             }
4387 
4388             if (PVMFSuccess != composeKeepAliveRequest(*tmpOutgoingMsg))
4389             {
4390                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::TimeoutOccurred ERROR composeKeepAliveRequest fail. Ln %d", __LINE__));
4391                 OSCL_DELETE(tmpOutgoingMsg);
4392                 //iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPComposeStopRequestError;
4393                 return;
4394             }
4395             if (PVMFSuccess != sendSocketOutgoingMsg(iSendSocket, *tmpOutgoingMsg))
4396             {
4397                 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
4398                 OSCL_DELETE(tmpOutgoingMsg);
4399                 return;
4400                 //iRet =  PVMFFailure;
4401                 //break;
4402             }
4403 
4404             bNoSendPending = false;
4405             iOutgoingMsgQueue.push(tmpOutgoingMsg);
4406         }
4407     }
4408 }
4409 
composeKeepAliveRequest(RTSPOutgoingMessage & aMsg)4410 PVMFStatus PVRTSPEngineNode::composeKeepAliveRequest(RTSPOutgoingMessage &aMsg)
4411 {
4412     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::composeKeepAliveRequest() in"));
4413 
4414     aMsg.reset();
4415     aMsg.numOfTransportEntries = 0;
4416     aMsg.msgType = RTSPRequestMsg;
4417     aMsg.method = iKeepAliveMethod;
4418     aMsg.cseq = iOutgoingSeq++;
4419     aMsg.cseqIsSet = true;
4420     aMsg.userAgent = iSessionInfo.iUserAgent.get_cstr();
4421     aMsg.userAgentIsSet = true;
4422 
4423     if (iSessionInfo.iSID.get_size())
4424     {
4425         aMsg.sessionId.setPtrLen(iSessionInfo.iSID.get_cstr(), iSessionInfo.iSID.get_size());
4426         aMsg.sessionIdIsSet = true;
4427     }
4428 
4429     if (composeSessionURL(aMsg) != PVMFSuccess)
4430     {
4431         return PVMFFailure;
4432     }
4433 
4434     if (aMsg.compose() == false)
4435     {
4436         return PVMFFailure;
4437     }
4438     return PVMFSuccess;
4439 }
4440 
SetKeepAliveMethod_timeout(int32 aTimeout)4441 OSCL_EXPORT_REF PVMFStatus  PVRTSPEngineNode::SetKeepAliveMethod_timeout(int32 aTimeout)
4442 {
4443     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod_timeout() in aTimeout=%d", aTimeout));
4444 
4445     //user server timeout if aTimeout == 0
4446     aTimeout = aTimeout / 1000; //sec
4447     if (aTimeout)
4448     {
4449         if (aTimeout > 0)//if(aTimeout > 3000)
4450         {
4451             TIMEOUT_KEEPALIVE = aTimeout;
4452         }
4453         else
4454         {
4455             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod() ERROR aTimeout=%d. Ln %d", aTimeout, __LINE__));
4456             return PVMFFailure;
4457         }
4458     }
4459     else
4460     {
4461         TIMEOUT_KEEPALIVE = PVRTSPENGINENODE_DEFAULT_KEEP_ALIVE_INTERVAL;
4462     }
4463 
4464     return PVMFSuccess;
4465 }
4466 
SetKeepAliveMethod_use_SET_PARAMETER(bool aUseSetParameter)4467 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetKeepAliveMethod_use_SET_PARAMETER(bool aUseSetParameter)
4468 {
4469     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod_timeout() in aUseSetParameter=%d", aUseSetParameter));
4470     iKeepAliveMethod = aUseSetParameter ? METHOD_SET_PARAMETER : METHOD_OPTIONS;
4471 
4472     return PVMFSuccess;
4473 }
4474 
SetKeepAliveMethod_keep_alive_in_play(bool aKeepAliveInPlay)4475 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetKeepAliveMethod_keep_alive_in_play(bool aKeepAliveInPlay)
4476 {
4477     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetKeepAliveMethod_timeout() in aKeepAliveInPlay=%d", aKeepAliveInPlay));
4478     bKeepAliveInPlay = aKeepAliveInPlay;
4479 
4480     return PVMFSuccess;
4481 }
4482 
4483 
GetKeepAliveMethod(int32 & aTimeout,bool & aUseSetParameter,bool & aKeepAliveInPlay)4484 OSCL_EXPORT_REF PVMFStatus  PVRTSPEngineNode::GetKeepAliveMethod(int32 &aTimeout, bool &aUseSetParameter, bool &aKeepAliveInPlay)
4485 {
4486     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::GetKeepAliveMethod() in"));
4487 
4488     aTimeout = TIMEOUT_KEEPALIVE * 1000;
4489     aUseSetParameter = (METHOD_SET_PARAMETER == iKeepAliveMethod);
4490     aKeepAliveInPlay = bKeepAliveInPlay;
4491 
4492     return PVMFSuccess;
4493 }
4494 
GetRTSPTimeOut(int32 & aTimeout)4495 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::GetRTSPTimeOut(int32 &aTimeout)
4496 {
4497     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::GetRTSPTimeOut() In"));
4498 
4499     aTimeout = TIMEOUT_WATCHDOG;
4500     return PVMFSuccess;
4501 }
4502 
SetRTSPTimeOut(int32 aTimeout)4503 OSCL_EXPORT_REF PVMFStatus PVRTSPEngineNode::SetRTSPTimeOut(int32 aTimeout)
4504 {
4505     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::SetRTSPTimeOut() In"));
4506 
4507     TIMEOUT_WATCHDOG = aTimeout;
4508     return PVMFSuccess;
4509 }
4510 
DoRequestPort(PVRTSPEngineCommand & aCmd,PVMFRTSPPort * & aPort)4511 PVMFStatus PVRTSPEngineNode::DoRequestPort(PVRTSPEngineCommand &aCmd, PVMFRTSPPort* &aPort)
4512 {
4513     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoRequestPort() In"));
4514 
4515     aPort = NULL;
4516 
4517     //retrieve port tag.
4518     int32 tag;
4519     OSCL_String* portconfig;
4520     aCmd.PVRTSPEngineCommandBase::Parse(tag, portconfig);
4521 
4522     OSCL_HeapString<PVRTSPEngineNodeAllocator> tmpPortConfig = portconfig->get_cstr();
4523     char *head = tmpPortConfig.get_str();
4524     if ((!head) ||
4525             ((tag != PVMF_RTSP_NODE_PORT_TYPE_OUTPUT) && (tag != PVMF_RTSP_NODE_PORT_TYPE_INPUT_OUTPUT)))
4526     {
4527         return PVMFErrArgument;//invalide portconfig.
4528     }
4529 
4530     //portconfig should be "sdpTrackIndex=5/media" or "sdpTrackIndex=5/feedback"
4531 
4532 
4533     bool bIsMedia = true;
4534     OSCL_StackString<128> IsMedia("/media");
4535     char *tmpCh = OSCL_CONST_CAST(char*, oscl_strstr(head, IsMedia.get_cstr()));
4536     if (!tmpCh)
4537     {
4538         OSCL_StackString<128> IsFeedback("/feedback");
4539         tmpCh = OSCL_CONST_CAST(char*, oscl_strstr(head, IsFeedback.get_cstr()));
4540         if (!tmpCh)
4541         {
4542             return PVMFErrArgument;
4543         }
4544         bIsMedia = false;
4545     }
4546     *tmpCh = '\0';  //set the delimiter for atoi
4547     OSCL_StackString<128> sdpTrackIndex("sdpTrackIndex=");
4548     tmpCh = OSCL_CONST_CAST(char*, oscl_strstr(head, sdpTrackIndex.get_cstr()));
4549     if (!tmpCh)
4550     {
4551         return PVMFErrArgument;
4552     }
4553 
4554     tmpCh += sdpTrackIndex.get_size();
4555     uint32 atoi_tmp;
4556     int32 tmpId = -1; //invalide sdp track id
4557     if (PV_atoi(tmpCh, 'd', atoi_tmp))
4558     {
4559         tmpId = atoi_tmp;
4560     }
4561 
4562     if (tmpId < 0)
4563     {
4564         return PVMFErrArgument;//invalide portconfig.
4565     }
4566 
4567     // statements were moved to sep. function to  remove compiler warnings caused by OSCL_TRY()
4568     return DoAddPort(tmpId, bIsMedia, tag, aPort);
4569 }
4570 
4571 
DoAddPort(int32 id,bool isMedia,int32 tag,PVMFRTSPPort * & aPort)4572 PVMFStatus PVRTSPEngineNode::DoAddPort(int32 id, bool isMedia, int32 tag, PVMFRTSPPort* &aPort)
4573 {
4574     int32 leavecode;
4575 
4576     OSCL_TRY(leavecode,
4577              aPort = OSCL_STATIC_CAST(PVMFRTSPPort*, OSCL_NEW(PVMFRTSPPort, (id, isMedia, tag, this)));
4578              iPortVector.AddL(aPort);
4579             );
4580 
4581     if (leavecode != OsclErrNone)
4582     {
4583         if (NULL == aPort)
4584         {
4585             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DoAddPort() new port fail ERROR leavecode=%d Ln %d", leavecode, __LINE__));
4586         }
4587 
4588         return PVMFErrNoMemory;
4589     }
4590 
4591     return PVMFSuccess;
4592 }
4593 
DoReleasePort(PVRTSPEngineCommand & aCmd)4594 PVMFStatus PVRTSPEngineNode::DoReleasePort(PVRTSPEngineCommand &aCmd)
4595 {
4596     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoReleasePort() In"));
4597 
4598     //Find the port in the port vector
4599     PVMFPortInterface* port;
4600     aCmd.PVRTSPEngineCommandBase::Parse(port);
4601 
4602     return PVMFSuccess;
4603 }
4604 
4605 /* allocate aReqBufSize memory for iEmbeddedData
4606 return true if memory is successfully allocated
4607 */
PrepareEmbeddedDataMemory(uint32 aReqBufSize,OsclMemoryFragment & aMemFrag)4608 bool PVRTSPEngineNode::PrepareEmbeddedDataMemory(uint32 aReqBufSize, OsclMemoryFragment &aMemFrag)
4609 {
4610     //PVMFSimpleMediaBufferCombinedAlloc media_data_alloc;
4611     //OsclSharedPtr<PVMFMediaDataImpl> media_data_imp = media_data_alloc.allocate(aReqBufSize);
4612     // Allocator for simple media data buffer impl
4613 
4614     OsclSharedPtr<PVMFMediaDataImpl> media_data_imp;
4615     int32 errcode;
4616     OSCL_TRY(errcode, media_data_imp = iMediaDataImplAlloc->allocate(aReqBufSize));
4617     if (errcode != 0)
4618     {
4619         OSCL_ASSERT(false);//there is no limit for the allocator num of buffers for now
4620 
4621         ReportErrorEvent(PVMFErrArgument, NULL);
4622         return false;
4623     }
4624 
4625     //OsclSharedPtr<PVMFMediaDataImpl> media_data_imp = myAllocate(aReqBufSize);
4626 
4627     // create a media data buffer
4628     iEmbeddedDataPtr = PVMFMediaData::createMediaData(media_data_imp,   &iAlloc);
4629 
4630     iEmbeddedDataPtr->setMediaFragFilledLen(0, aReqBufSize);
4631 
4632     OsclRefCounterMemFrag refCtrMemFragOut;
4633     iEmbeddedDataPtr->getMediaFragment(0, refCtrMemFragOut);
4634 
4635     aMemFrag = refCtrMemFragOut.getMemFrag();
4636 
4637     return (aMemFrag.ptr == NULL) ? false : true;
4638 }
4639 
4640 /* dispatch the embedded data in iEmbeddedData to different ports according to channel id
4641 return true if send success
4642 */
DispatchEmbeddedData(uint32 aChannelID)4643 bool PVRTSPEngineNode::DispatchEmbeddedData(uint32 aChannelID)
4644 {
4645     if (iTheBusyPort)
4646     {
4647         return false;
4648     }
4649 
4650     if (ibIsRealRDT)
4651     {
4652         return DispatchEmbeddedRdtData();
4653     }
4654 
4655     PVMFRTSPPort* pvPort = NULL;
4656     for (int32 i = iPortVector.size() - 1; i >= 0; i--)
4657     {
4658         if ((((PVMFRTSPPort*)(iPortVector[i]))->iChannelID == aChannelID)
4659                 && ((PVMFRTSPPort*)(iPortVector[i]))->bIsChannelIDSet)
4660         {
4661             pvPort = (PVMFRTSPPort*)(iPortVector[i]);
4662             break;
4663         }
4664     }
4665     if (pvPort == NULL)
4666     {//no pvMF port is setup to get this channel, discard the data
4667         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedData() channel:%d data discarded.", aChannelID));
4668         iEmbeddedDataPtr.Unbind();
4669         return true;
4670     }
4671 
4672     PVMFSharedMediaMsgPtr aMediaMsgPtr;
4673     convertToPVMFMediaMsg(aMediaMsgPtr, iEmbeddedDataPtr);
4674     PVMFStatus status = pvPort->QueueOutgoingMsg(aMediaMsgPtr);
4675     if (status != PVMFSuccess)
4676     {
4677         if (status == PVMFErrBusy)
4678         {
4679             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::DispatchEmbeddedData() BUSY:%d, Outgoing queue size=%d.", status, pvPort->OutgoingMsgQueueSize()));
4680         }
4681         else
4682         {
4683             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedData() ERROR:%d, Outgoing queue size=%d. Data discarded!", status, pvPort->OutgoingMsgQueueSize()));
4684             ReportErrorEvent(PVMFErrPortProcessing);
4685         }
4686         return false;
4687     }
4688     return true;
4689 }
4690 
DispatchEmbeddedRdtData()4691 bool PVRTSPEngineNode::DispatchEmbeddedRdtData()
4692 {
4693     IPayloadParser::Payload incomingFrag;
4694     Oscl_Vector<IPayloadParser::Payload, OsclMemAllocator> vRdtPackets;
4695 
4696     // retrieve the incoming RDT packet mem fragment
4697     OsclRefCounterMemFrag frag;
4698     iEmbeddedDataPtr->getMediaFragment(0, frag);
4699     incomingFrag.vfragments.push_back(frag);
4700 
4701     // parse the RDT headers and retrieve the payloads
4702     if (ipRdtParser->Parse(incomingFrag, vRdtPackets) != PayloadParserStatus_Success)
4703     {
4704         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() Unable to parse RDT packet!"));
4705         iEmbeddedDataPtr.Unbind();
4706         return true;
4707     }
4708 
4709     uint32 i = 0;
4710     for (i = 0; i < vRdtPackets.size(); i++)
4711     {
4712         if (!ipFragGroupAllocator->IsMsgAvailable())
4713         {
4714             // drop this packet
4715             iEmbeddedDataPtr.Unbind();
4716             vRdtPackets.clear();
4717             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR,
4718                             (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() Out of memory! Stopping processing and dropping packet"));
4719 
4720             // block processing until we get a callback
4721             ibBlockedOnFragGroups = true;
4722             ipFragGroupAllocator->notifyfreechunkavailable(*this, NULL);
4723         }
4724 
4725         OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
4726         int32 err;
4727         mediaDataImplOut = AllocateMediaData(err);
4728         OSCL_ASSERT(err == OsclErrNone); // we just checked that a message is available
4729         if (err != OsclErrNone)
4730         {
4731             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() Unable to allocate media data impl!"));
4732             return true;
4733         }
4734 
4735         IPayloadParser::Payload rdtOut = vRdtPackets[i];
4736         mediaDataImplOut->setMarkerInfo(rdtOut.marker);
4737         mediaDataImplOut->appendMediaFragment(rdtOut.vfragments[0]);
4738 
4739         PVMFSharedMediaDataPtr mediaDataOut = PVMFMediaData::createMediaData(mediaDataImplOut);
4740         mediaDataOut->setSeqNum(rdtOut.sequence);
4741         mediaDataOut->setStreamID(rdtOut.stream);
4742         mediaDataOut->setTimestamp(rdtOut.timestamp);
4743 
4744         // which port?
4745         PVMFRTSPPort* pvPort = NULL;
4746         for (int p = iPortVector.size() - 1; p >= 0; p--)
4747         {
4748             if ((uint)((PVMFRTSPPort*)(iPortVector[p]))->iRdtStreamId == rdtOut.stream)
4749             {
4750 
4751                 pvPort = (PVMFRTSPPort*)(iPortVector[p]);
4752                 break;
4753             }
4754         }
4755 
4756         if (pvPort == NULL)
4757         {//no pvMF port is setup to get this channel, discard the data
4758             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() channel:%d data discarded.", rdtOut.stream));
4759             iEmbeddedDataPtr.Unbind();
4760             return true;
4761         }
4762 
4763         PVMFSharedMediaMsgPtr mediaMsgPtr;
4764         convertToPVMFMediaMsg(mediaMsgPtr, mediaDataOut);
4765 
4766         PVMFStatus status = pvPort->QueueOutgoingMsg(mediaMsgPtr);
4767         if (status != PVMFSuccess)
4768         {
4769             if (status == PVMFErrBusy)
4770             {
4771                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() BUSY:%d, Outgoing queue size=%d.", status, pvPort->OutgoingMsgQueueSize()));
4772             }
4773             else
4774             {
4775                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::DispatchEmbeddedRdtData() ERROR:%d, Outgoing queue size=%d. Data discarded!", status, pvPort->OutgoingMsgQueueSize()));
4776                 ReportErrorEvent(PVMFErrPortProcessing);
4777             }
4778 
4779             return false;
4780         }
4781     }
4782 
4783     return true;
4784 }
4785 
DoFlush(PVRTSPEngineCommand & aCmd)4786 PVMFStatus PVRTSPEngineNode::DoFlush(PVRTSPEngineCommand& aCmd)
4787 {
4788     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoFlush() In"));
4789     OSCL_UNUSED_ARG(aCmd);
4790 
4791     if ((iInterfaceState != EPVMFNodeStarted) && (iInterfaceState != EPVMFNodePaused))
4792     {
4793         return PVMFErrInvalidState;
4794     }
4795 
4796     //Notify all ports to suspend their input
4797     {
4798         for (uint32 i = 0; i < iPortVector.size(); i++)
4799             iPortVector[i]->SuspendInput();
4800     }
4801 
4802     //the flush is asynchronous.  Completion is detected in the Run.
4803     //Make sure the AO is active to finish the flush..
4804     RunIfNotReady();
4805     return PVMFPending;
4806 }
4807 
sendSocketOutgoingMsg(SocketContainer & aSock,RTSPOutgoingMessage & aMsg)4808 PVMFStatus PVRTSPEngineNode::sendSocketOutgoingMsg(SocketContainer &aSock, RTSPOutgoingMessage &aMsg)
4809 {
4810     StrPtrLen *tmpStrPtrLen = aMsg.retrieveComposedBuffer();
4811     if (NULL == tmpStrPtrLen)
4812     {
4813         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::sendSocketOutgoingMsg() retrieveComposedBuffer() ERROR, line %d", __LINE__));
4814         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPCompose501ResponseError;
4815         return  PVMFFailure;
4816     }
4817     //PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0,"C ---> S\n%s", tmpStrPtrLen->c_str()));
4818     if (aSock.iSocket->Send((const uint8*)tmpStrPtrLen->c_str(), tmpStrPtrLen->length(), TIMEOUT_SEND) != EPVSocketPending)
4819     {
4820         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::sendSocketOutgoingMsg() Send() ERROR, line %d", __LINE__));
4821         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
4822         return PVMFFailure;
4823     }
4824     SetSendPending(aSock);
4825     iNumSendCallback++;
4826     return PVMFSuccess;
4827 }
4828 
sendSocketOutgoingMsg(SocketContainer & aSock,const uint8 * aSendBuf,uint32 aSendLen)4829 PVMFStatus PVRTSPEngineNode::sendSocketOutgoingMsg(SocketContainer &aSock, const uint8* aSendBuf, uint32 aSendLen)
4830 {
4831     if (aSock.iSocket->Send(aSendBuf, aSendLen, TIMEOUT_SEND) != EPVSocketPending)
4832     {
4833         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::sendSocketOutgoingMsg() Send() ERROR, line %d", __LINE__));
4834         iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorSocketSendError;
4835         return PVMFFailure;
4836     }
4837     SetSendPending(aSock);
4838     iNumSendCallback++;
4839     return PVMFSuccess;
4840 }
4841 
4842 //drive the parser, return true if there is a pending event
rtspParserLoop(void)4843 bool PVRTSPEngineNode::rtspParserLoop(void)
4844 {
4845     if ((iRTSPParser == NULL) || (NULL != iTheBusyPort)
4846             || (iRecvSocket.iSocket == NULL) || (EPVMFNodeError == iInterfaceState))
4847     {
4848         return false;
4849     }
4850 
4851     bool bLoop = true, ret = false;
4852     while (bLoop)
4853     {
4854         iRTSPParserState = iRTSPParser->getState();
4855         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::rtspParserLoop() RTSPParser state %d", iRTSPParserState));
4856 
4857         switch (iRTSPParserState)
4858         {
4859             case RTSPParser::WAITING_FOR_DATA:
4860             {
4861                 if (bNoRecvPending)
4862                 {
4863                     TPVSocketEvent tmpEvent = EPVSocketFailure;
4864                     const StrPtrLen *tmpbuf = iRTSPParser->getDataBufferSpec();
4865                     if (tmpbuf) // unlikely to fail, err rtn from getDataBufferSpec
4866                     {
4867                         tmpEvent = iRecvSocket.iSocket->Recv((uint8*)tmpbuf->c_str(), tmpbuf->length(), TIMEOUT_RECV);
4868                     }
4869                     if (tmpEvent != EPVSocketPending)
4870                     {
4871                         int32 errcode = PVMFRTSPClientEngineNodeErrorSocketRecvError;
4872                         PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() Recv failed"));
4873                         ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &errcode);
4874                         ChangeExternalState(EPVMFNodeError);
4875                     }
4876                     else
4877                     {
4878                         SetRecvPending(iRecvSocket);
4879                         iNumRecvCallback++;
4880                     }
4881                     bNoRecvPending = false;
4882                 }
4883                 bLoop = false;
4884                 break;
4885             }
4886             case RTSPParser::WAITING_FOR_REQUEST_MEMORY:
4887             {
4888                 iIncomingMsg.reset();
4889                 if (!iRTSPParser->registerNewRequestStruct(&iIncomingMsg))
4890                 {
4891                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerNewRequestStruct failed"));
4892                     ChangeExternalState(EPVMFNodeError);
4893                 }
4894                 break;
4895             }
4896             case RTSPParser::ENTITY_BODY_IS_READY:
4897                 ((uint8*)iEntityMemFrag.ptr)[iEntityMemFrag.len-1] = '\0';
4898                 //let the Doxxx() to process the entity body, like sdp, still img, and server msg
4899             case RTSPParser::REQUEST_IS_READY:
4900             {
4901                 bLoop = false;
4902                 ret = true;
4903                 break;
4904             }
4905             case RTSPParser::WAITING_FOR_ENTITY_BODY_MEMORY:
4906             {/*
4907 OsclSharedPtr<PVMFMediaDataImpl> media_data_imp;
4908 int32 errcode;
4909 OSCL_TRY(errcode, media_data_imp = iMediaDataImplAlloc->allocate(iIncomingMsg.contentLength+1));
4910 if (errcode != OsclErrNone)
4911 {
4912 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0,"PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
4913 
4914 OSCL_ASSERT(false);//there is no limit for the allocator num of buffers for now
4915 ChangeExternalState(EPVMFNodeError);
4916 iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
4917 ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &iCurrentErrorCode);
4918 
4919 bLoop = false;
4920 ret = true;
4921 break;
4922 }
4923 
4924 media_data_imp->getMediaFragment(0, iEntityMemFrag);
4925 (iEntityMemFrag.getMemFrag()).len = iEntityMemFrag.getCapacity();
4926 */
4927                 if ((iEntityMemFrag.len > 0) || (iEntityMemFrag.ptr != NULL))
4928                 {
4929                     OSCL_FREE(iEntityMemFrag.ptr);
4930                     iEntityMemFrag.len = 0;
4931                     iEntityMemFrag.ptr = NULL;
4932                 }
4933 
4934                 iEntityMemFrag.len = 0;
4935                 iEntityMemFrag.ptr = OSCL_MALLOC(iIncomingMsg.contentLength + 1);
4936                 //PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0,"PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
4937 
4938                 OsclError::LeaveIfNull(iEntityMemFrag.ptr);
4939                 iEntityMemFrag.len = (iIncomingMsg.contentLength + 1);
4940 
4941                 if (!iRTSPParser->registerEntityBody(&iEntityMemFrag))
4942                 {
4943                     PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
4944 
4945                     //iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorOutOfMemory;
4946                     ChangeExternalState(EPVMFNodeError);
4947                     iCurrentErrorCode = PVMFRTSPClientEngineNodeErrorRTSPParserError;
4948                     ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &iCurrentErrorCode);
4949                     bLoop = false;
4950                     ret = true;
4951                 }
4952 
4953                 break;
4954             }
4955 
4956             case RTSPParser::WAITING_FOR_EMBEDDED_DATA_MEMORY:
4957             {//TCP streaming
4958                 RTSPEntityBody iEmbeddedData;
4959                 if (!PrepareEmbeddedDataMemory(iIncomingMsg.contentLength, iEmbeddedData))
4960                 {//no memory available TBD
4961                     bLoop = false;
4962                     break;
4963                 }
4964 
4965                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_DEBUG, (0, "PVRTSPEngineNode::rtspParserLoop() RTP pkts channelID=%d, len=%d", iIncomingMsg.channelID, iIncomingMsg.contentLength));
4966                 iRTSPParser->registerEmbeddedDataMemory(&iEmbeddedData);
4967                 break;
4968             }
4969             case RTSPParser::EMBEDDED_DATA_IS_READY:
4970             {//process the data
4971                 if (!ibBlockedOnFragGroups)
4972                 {
4973                     if (! DispatchEmbeddedData(iIncomingMsg.channelID)) //, iEmbeddedData))
4974                     {//send busy or fails
4975                         bLoop = false;
4976                     }
4977                 }
4978                 break;
4979             }
4980             case RTSPParser::ERROR_REQUEST_TOO_BIG:
4981             {
4982                 int32 errcode = PVMFRTSPClientEngineNodeErrorRTSPRequestTooBig;
4983                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
4984                 ChangeExternalState(EPVMFNodeError);
4985                 ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &errcode);
4986                 bLoop = false;
4987                 break;
4988             }
4989             case RTSPParser::INTERNAL_ERROR:
4990             default:
4991             {
4992                 int32 errcode = PVMFRTSPClientEngineNodeErrorRTSPParserError;
4993                 PVLOGGER_LOGMSG(PVLOGMSG_INST_HLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::rtspParserLoop() registerEntityBody failed"));
4994                 ChangeExternalState(EPVMFNodeError);
4995                 ReportErrorEvent(PVMFErrProcessing, NULL, &iEventUUID, &errcode);
4996                 bLoop = false;
4997                 break;
4998             }
4999         }
5000     }
5001     return ret;
5002 }
5003 
5004 
5005 
freechunkavailable(OsclAny *)5006 void PVRTSPEngineNode::freechunkavailable(OsclAny*)
5007 {
5008     ibBlockedOnFragGroups = false;
5009 }
5010 
DoErrorRecovery(PVRTSPEngineCommand & aCmd)5011 PVMFStatus PVRTSPEngineNode::DoErrorRecovery(PVRTSPEngineCommand &aCmd)
5012 {
5013     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::DoReleasePort() In"));
5014 
5015     //get error context
5016     PVRTSPErrorContext* errorContext = OSCL_STATIC_CAST(PVRTSPErrorContext*, aCmd.iParam1);
5017     if (errorContext == NULL)
5018     {
5019         return PVMFFailure;
5020     }
5021 
5022     PVMFStatus myRet = PVMFPending;
5023 
5024     {
5025         if (PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE > iState)
5026         {
5027             myRet = SendRtspDescribe(aCmd);
5028         }
5029         else if (PVRTSP_ENGINE_NODE_STATE_SETUP_DONE > iState)
5030         {
5031             myRet = SendRtspSetup(aCmd);
5032             if (myRet == PVMFSuccess)
5033             {//send OPTIONS and keep the connection alive
5034                 //and wait for new Start() request
5035                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE);
5036             }
5037         }
5038     }
5039 
5040     if ((PVMFSuccess != myRet) && (PVMFPending != myRet))
5041     {/*error during error handling
5042      1. decrease the recovery count counter
5043      2. reset the socket
5044      3. change the iState to restart again
5045         */
5046         if (iErrorRecoveryAttempt-- <= 0)
5047         {
5048             return PVMFFailure;
5049         }
5050         //TBD reset the socket
5051         ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_IDLE);
5052         RunIfNotReady();
5053     }
5054     else if (iState >= errorContext->iErrState)
5055     {
5056         return PVMFSuccess;
5057     }
5058 
5059     if (PVMFSuccess == myRet)
5060     {
5061         RunIfNotReady();
5062     }
5063 
5064     return PVMFPending;
5065 }
5066 
5067 
5068 //This routine is called repeatedly to drive the socket cleanup sequence.
5069 // Step 1: Cancel DNS & socket operations & wait on completion
5070 // Step 2: Shutdown sockets & wait on completion
5071 // Step 3: Delete sockets
5072 //
5073 // If "Immediate" is set we just delete sockets without shutdown sequence.
resetSocket(bool aImmediate)5074 PVMFStatus PVRTSPEngineNode::resetSocket(bool aImmediate)
5075 {
5076     //Make sure things aren't already cleaned up.
5077     if (!iDNS.IsBusy()
5078             && !iSendSocket.iSocket
5079             && !iRecvSocket.iSocket)
5080     {
5081         //Nothing to do!
5082         if (iLogger)
5083         {
5084             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Nothing to do!"));
5085         }
5086         return PVMFSuccess;
5087     }
5088 
5089     if (aImmediate)
5090     {
5091         //force immediate cleanup, for use in destructor where we can't wait
5092         //on any async ops.
5093 
5094         //see if we have one socket or two.
5095         bool oneSocket = (iSendSocket.iSocket == iRecvSocket.iSocket);
5096         if (iSendSocket.iSocket)
5097         {
5098             iSendSocket.iSocket->~OsclTCPSocket();
5099             iAlloc.deallocate(iSendSocket.iSocket);
5100             iSendSocket.iSocket = NULL;
5101         }
5102         if (iRecvSocket.iSocket)
5103         {
5104             //guard against duplicate destroy/free
5105             if (!oneSocket)
5106             {
5107                 iRecvSocket.iSocket->~OsclTCPSocket();
5108                 iAlloc.deallocate(iRecvSocket.iSocket);
5109             }
5110             iRecvSocket.iSocket = NULL;
5111         }
5112         return PVMFSuccess;
5113     }
5114 
5115     bool waitOnAsyncOp = false;
5116     while (!waitOnAsyncOp)
5117     {
5118         switch (iSocketCleanupState)
5119         {
5120             case ESocketCleanup_Idle:
5121                 //Start a new sequence.
5122                 iSocketCleanupState = ESocketCleanup_CancelCurrentOp;
5123                 break;
5124 
5125             case ESocketCleanup_CancelCurrentOp:
5126                 //Step 1: Cancel current operations
5127 
5128                 //Cancel ops on DNS
5129                 if (iDNS.iDns)
5130                 {
5131                     if (iDNS.iState.iPending
5132                             && !iDNS.iState.iCanceled)
5133                     {
5134                         iDNS.iDns->CancelGetHostByName();
5135                         iDNS.iState.iCanceled = true;
5136                         if (iLogger)
5137                         {
5138                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel GetHostByName"));
5139                         }
5140                     }
5141                 }
5142 
5143                 //Cancel ops on send socket.
5144                 if (iSendSocket.iSocket)
5145                 {
5146                     if (iSendSocket.iConnectState.iPending
5147                             && !iSendSocket.iConnectState.iCanceled)
5148                     {
5149                         iSendSocket.iSocket->CancelConnect();
5150                         iSendSocket.iConnectState.iCanceled = true;
5151                         if (iLogger)
5152                         {
5153                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Connect"));
5154                         }
5155                     }
5156                     if (iSendSocket.iSendState.iPending
5157                             && !iSendSocket.iSendState.iCanceled)
5158                     {
5159                         iSendSocket.iSocket->CancelSend();
5160                         iSendSocket.iSendState.iCanceled = true;
5161                         if (iLogger)
5162                         {
5163                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Send"));
5164                         }
5165                     }
5166                     if (iSendSocket.iRecvState.iPending
5167                             && !iSendSocket.iRecvState.iCanceled)
5168                     {
5169                         iSendSocket.iSocket->CancelRecv();
5170                         iSendSocket.iRecvState.iCanceled = true;
5171                         if (iLogger)
5172                         {
5173                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Recv"));
5174                         }
5175                     }
5176                     OSCL_ASSERT(!iSendSocket.iShutdownState.iPending);
5177                 }
5178 
5179                 //Cancel ops on recv socket only when it's
5180                 //a unique socket.
5181                 if (iRecvSocket.iSocket
5182                         && iRecvSocket.iSocket != iSendSocket.iSocket)
5183                 {
5184                     if (iRecvSocket.iConnectState.iPending
5185                             && !iRecvSocket.iConnectState.iCanceled)
5186                     {
5187                         iRecvSocket.iSocket->CancelConnect();
5188                         iRecvSocket.iConnectState.iCanceled = true;
5189                         if (iLogger)
5190                         {
5191                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Connect (recv sock)"));
5192                         }
5193                     }
5194                     if (iRecvSocket.iSendState.iPending
5195                             && !iRecvSocket.iSendState.iCanceled)
5196                     {
5197                         iRecvSocket.iSocket->CancelSend();
5198                         iRecvSocket.iSendState.iCanceled = true;
5199                         if (iLogger)
5200                         {
5201                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Send (recv sock)"));
5202                         }
5203                     }
5204                     if (iRecvSocket.iRecvState.iPending
5205                             && !iRecvSocket.iRecvState.iCanceled)
5206                     {
5207                         iRecvSocket.iSocket->CancelRecv();
5208                         iRecvSocket.iRecvState.iCanceled = true;
5209                         if (iLogger)
5210                         {
5211                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Cancel Recv (recv sock)"));
5212                         }
5213                     }
5214                     OSCL_ASSERT(!iRecvSocket.iShutdownState.iPending);
5215                 }
5216 
5217                 if (iDNS.IsBusy()
5218                         || iSendSocket.IsBusy()
5219                         || iRecvSocket.IsBusy())
5220                 {
5221                     waitOnAsyncOp = true;
5222                 }
5223 
5224                 //Either go to wait state or continue to Step 2.
5225                 if (waitOnAsyncOp)
5226                     iSocketCleanupState = ESocketCleanup_WaitOnCancel;
5227                 else
5228                     iSocketCleanupState = ESocketCleanup_Shutdown;
5229                 break;
5230 
5231             case ESocketCleanup_WaitOnCancel:
5232                 //Wait on cancel completion for all.
5233 
5234                 if (iDNS.IsBusy()
5235                         || iSendSocket.IsBusy()
5236                         || iRecvSocket.IsBusy())
5237                 {
5238                     waitOnAsyncOp = true;
5239                 }
5240 
5241                 if (!waitOnAsyncOp)
5242                     iSocketCleanupState = ESocketCleanup_Shutdown;
5243                 break;
5244 
5245             case ESocketCleanup_Shutdown:
5246                 //Step 2: shutdown both sockets
5247 
5248                 if (iDNS.iDns)
5249                 {
5250                     OSCL_ASSERT(!iDNS.IsBusy());
5251                 }
5252 
5253                 if (iSendSocket.iSocket)
5254                 {
5255                     OSCL_ASSERT(!iSendSocket.IsBusy());
5256 
5257                     if (iSendSocket.iSocket->Shutdown(EPVSocketBothShutdown, TIMEOUT_SHUTDOWN) == EPVSocketPending)
5258                     {
5259                         iSendSocket.iShutdownState.iPending = true;
5260                         waitOnAsyncOp = true;
5261                         if (iLogger)
5262                         {
5263                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown"));
5264                         }
5265                     }
5266                     //else shutdown failed, ignore & continue
5267                     else
5268                     {
5269                         if (iLogger)
5270                         {
5271                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown Failed"));
5272                         }
5273                     }
5274                 }
5275 
5276                 //shutown recv socket only when it's a unique socket.
5277                 if (iRecvSocket.iSocket
5278                         && iRecvSocket.iSocket != iSendSocket.iSocket)
5279                 {
5280                     OSCL_ASSERT(!iRecvSocket.IsBusy());
5281 
5282                     if (iRecvSocket.iSocket->Shutdown(EPVSocketBothShutdown, TIMEOUT_SHUTDOWN) == EPVSocketPending)
5283                     {
5284                         iRecvSocket.iShutdownState.iPending = true;
5285                         waitOnAsyncOp = true;
5286                         if (iLogger)
5287                         {
5288                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown (recv sock)"));
5289                         }
5290                     }
5291                     //else shutdown failed, ignore & continue
5292                     else
5293                     {
5294                         if (iLogger)
5295                         {
5296                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Shutdown Failed (recv sock)"));
5297                         }
5298                     }
5299                 }
5300 
5301                 //Either go to wait state or continue to Step 3.
5302                 if (waitOnAsyncOp)
5303                     iSocketCleanupState = ESocketCleanup_WaitOnShutdown;
5304                 else
5305                     iSocketCleanupState = ESocketCleanup_Delete;
5306                 break;
5307 
5308             case ESocketCleanup_WaitOnShutdown:
5309                 //Wait on shutdown completion for both sockets.
5310 
5311                 if (iSendSocket.IsBusy()
5312                         || iRecvSocket.IsBusy())
5313                 {
5314                     waitOnAsyncOp = true;
5315                 }
5316 
5317                 if (!waitOnAsyncOp)
5318                     iSocketCleanupState = ESocketCleanup_Delete;
5319                 break;
5320 
5321             case ESocketCleanup_Delete:
5322                 // Step 3: Delete sockets
5323 
5324                 // Note: we assume this calling context is not the socket callback, so
5325                 // it's safe to delete the OsclSocket object here.
5326 
5327             {
5328                 //see if we have one socket or two.
5329                 bool oneSocket = (iSendSocket.iSocket == iRecvSocket.iSocket);
5330                 if (iSendSocket.iSocket)
5331                 {
5332                     OSCL_ASSERT(!iSendSocket.IsBusy());
5333                     if (iLogger)
5334                     {
5335                         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Delete TCP"));
5336                     }
5337                     iSendSocket.iSocket->~OsclTCPSocket();
5338                     iAlloc.deallocate(iSendSocket.iSocket);
5339                     iSendSocket.iSocket = NULL;
5340                 }
5341                 if (iRecvSocket.iSocket)
5342                 {
5343                     OSCL_ASSERT(!iRecvSocket.IsBusy());
5344                     //guard against duplicate destroy/free
5345                     if (!oneSocket)
5346                     {
5347                         if (iLogger)
5348                         {
5349                             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Delete TCP (recv sock)"));
5350                         }
5351                         iRecvSocket.iSocket->~OsclTCPSocket();
5352                         iAlloc.deallocate(iRecvSocket.iSocket);
5353                     }
5354                     iRecvSocket.iSocket = NULL;
5355                 }
5356 
5357                 bNoSendPending = bNoRecvPending = false;
5358 
5359                 ChangeInternalState(PVRTSP_ENGINE_NODE_STATE_IDLE);
5360             }
5361             iSocketCleanupState = ESocketCleanup_Idle;
5362             if (iLogger)
5363             {
5364                 PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::resetSocket() Done!"));
5365             }
5366             return PVMFSuccess; //Done!
5367 
5368             default:
5369                 OSCL_ASSERT(0);
5370                 break;
5371         }
5372     }
5373 
5374     return (waitOnAsyncOp) ? PVMFPending : PVMFSuccess;
5375 }
5376 
SetSendPending(SocketContainer & aSock)5377 void PVRTSPEngineNode::SetSendPending(SocketContainer& aSock)
5378 {
5379     //Set "send pending" condition on a socket container.
5380     //update recv socket container only when we have a unique recv socket,
5381     //otherwise update send socket container.
5382     if (aSock.iSocket == iRecvSocket.iSocket
5383             && iRecvSocket.iSocket != iSendSocket.iSocket)
5384         iRecvSocket.iSendState.iPending = true;
5385     else
5386     {
5387         iSendSocket.iSendState.iPending = true;
5388         OSCL_ASSERT(aSock.iSocket == iSendSocket.iSocket);
5389     }
5390 }
5391 
SetRecvPending(SocketContainer & aSock)5392 void PVRTSPEngineNode::SetRecvPending(SocketContainer& aSock)
5393 {
5394     //Set "recv pending" condition on a socket container.
5395     //update recv socket container only when we have a unique recv socket,
5396     //otherwise update send socket container.
5397     if (aSock.iSocket == iRecvSocket.iSocket
5398             && iRecvSocket.iSocket != iSendSocket.iSocket)
5399         iRecvSocket.iRecvState.iPending = true;
5400     else
5401     {
5402         iSendSocket.iRecvState.iPending = true;
5403         OSCL_ASSERT(aSock.iSocket == iSendSocket.iSocket);
5404     }
5405 }
5406 
RunError(OsclLeaveCode aError)5407 OsclLeaveCode PVRTSPEngineNode::RunError(OsclLeaveCode aError)
5408 {
5409     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "PVRTSPEngineNode::RunError() aError=%d", aError));
5410 
5411 
5412     //return OsclErrNone;
5413     return aError;
5414 }
5415 
clearOutgoingMsgQueue()5416 void PVRTSPEngineNode::clearOutgoingMsgQueue()
5417 {
5418     while (!iOutgoingMsgQueue.empty())
5419     {
5420         //pop the outgoing msg queue and see the match
5421         RTSPOutgoingMessage* tmpOutgoingMsg = iOutgoingMsgQueue.top();
5422         iOutgoingMsgQueue.pop();
5423         if (tmpOutgoingMsg)
5424             OSCL_DELETE(tmpOutgoingMsg);
5425     }
5426 }
5427 
partialResetSessionInfo()5428 void PVRTSPEngineNode::partialResetSessionInfo()
5429 {
5430     iOutgoingSeq = 0;
5431     setupTrackIndex = 0;
5432     iSessionInfo.iSID = "";
5433 
5434     iSessionInfo.iReqPlayRange.format = RtspRangeType::INVALID_RANGE;
5435     iSessionInfo.bExternalSDP = false;
5436     iSessionInfo.pvServerIsSetFlag = false;
5437     iSessionInfo.roundTripDelay = 0;
5438     iSessionInfo.iSDPinfo.Unbind();
5439 }
5440 
ResetSessionInfo()5441 void PVRTSPEngineNode::ResetSessionInfo()
5442 {
5443     iOutgoingSeq = 0;
5444     setupTrackIndex = 0;
5445     iSessionInfo.iSID = "";
5446 
5447     iSessionInfo.iReqPlayRange.format = RtspRangeType::INVALID_RANGE;
5448     iSessionInfo.bExternalSDP = false;
5449     iSessionInfo.pvServerIsSetFlag = false;
5450     iSessionInfo.roundTripDelay = 0;
5451     iSessionInfo.iSDPinfo.Unbind();
5452 }
5453 
5454 //clear the internal event queue "iSocketEventQueue"
5455 //return false if any of the event indicate failure
clearEventQueue(void)5456 bool PVRTSPEngineNode::clearEventQueue(void)
5457 {
5458     bool myRet = true;
5459     while (!iSocketEventQueue.empty())
5460     {
5461         SocketEvent tmpSockEvent(iSocketEventQueue.front());
5462         iSocketEventQueue.erase(&iSocketEventQueue.front());
5463         PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::clearEventQueue() In iFxn=%d iSockEvent=%d iSockError=%d ", tmpSockEvent.iSockFxn, tmpSockEvent.iSockEvent, tmpSockEvent.iSockError));
5464 
5465         if (tmpSockEvent.iSockEvent != EPVSocketSuccess)
5466         {
5467             myRet = false;
5468             PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_ERR, (0, "PVRTSPEngineNode::clearEventQueue() Socket Error"));
5469         }
5470     }
5471 
5472     PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_INFO, (0, "PVRTSPEngineNode::clearEventQueue() Out myRet=%d ", myRet));
5473     return myRet;
5474 }
5475 
5476 ////////////////////////////////////////////////////////////////////////////////
5477 /// GetPostCorrelationObject Implementation
5478 ////////////////////////////////////////////////////////////////////////////////
5479 #define KGetPostCorrelationFile _STRLIT("get_post_correlation_number.dat")
5480 
create(OSCL_TCHAR * aFileName)5481 GetPostCorrelationObject* GetPostCorrelationObject::create(OSCL_TCHAR* aFileName)
5482 {
5483     GetPostCorrelationObject *object = OSCL_NEW(GetPostCorrelationObject, ());
5484     if (!object) return NULL;
5485     if (!object->construct(aFileName))
5486     {
5487         OSCL_DELETE(object);
5488         return NULL;
5489     }
5490     return object;
5491 }
5492 
construct(OSCL_TCHAR * aFileName)5493 bool GetPostCorrelationObject::construct(OSCL_TCHAR* aFileName)
5494 {
5495     iGetPostCorrelation = 1;
5496     iFileCreated = false;
5497     iFs.Connect();
5498 
5499     OSCL_TCHAR* aLocalFileName = aFileName;
5500     if (!aLocalFileName) aLocalFileName = (OSCL_TCHAR*)KGetPostCorrelationFile;
5501     if (iGetPostCorrelationFile.Open(aLocalFileName, Oscl_File::MODE_READ | Oscl_File::MODE_BINARY, iFs) == 0)
5502     {
5503         // get the current iGetPostCorrelation
5504         iGetPostCorrelationFile.Read(&iGetPostCorrelation, sizeof(iGetPostCorrelation), 1);
5505         iGetPostCorrelationFile.Close();
5506     }
5507 
5508     if (iGetPostCorrelationFile.Open(aLocalFileName, Oscl_File::MODE_READWRITE | Oscl_File::MODE_BINARY, iFs))
5509     {
5510         iFs.Close();
5511         return false;
5512     }
5513 
5514     iFileCreated = true;
5515     return true;
5516 }
5517 
~GetPostCorrelationObject()5518 GetPostCorrelationObject::~GetPostCorrelationObject()
5519 {
5520     if (iFileCreated) closeFile();
5521     iFileCreated = false;
5522 }
5523 
closeFile()5524 void GetPostCorrelationObject::closeFile()
5525 {
5526     writeToFile();
5527     iGetPostCorrelationFile.Close();
5528     iFs.Close();
5529 }
5530 
5531 
writeToFile()5532 bool GetPostCorrelationObject::writeToFile()
5533 {
5534     // always write at the beginning
5535     if (iGetPostCorrelationFile.Seek(0, Oscl_File::SEEKSET)) return false;
5536     if (iGetPostCorrelationFile.Write(&iGetPostCorrelation, sizeof(iGetPostCorrelation), 1) != 1)
5537     {
5538         return false;
5539     }
5540 
5541     // Flush the data to file
5542     iGetPostCorrelationFile.Flush();
5543     return true;
5544 }
5545 
update()5546 bool GetPostCorrelationObject::update()
5547 {
5548     if (!iFileCreated) return false;
5549 
5550     // increase iGetPostCorrelation by 1 within [1, 255]
5551     if (iGetPostCorrelation == 255) iGetPostCorrelation = 1;
5552     else ++iGetPostCorrelation;
5553 
5554     return writeToFile();
5555 }
5556 
5557 
5558 
5559 
5560 /**
5561  * Called by the command handler AO to do the Cancel All
5562  */
DoCancelAllCommands(PVRTSPEngineCommand & aCmd)5563 PVMFStatus PVRTSPEngineNode::DoCancelAllCommands(PVRTSPEngineCommand& aCmd)
5564 {
5565     /* cancel all queued commands */
5566     while (!iPendingCmdQueue.empty())
5567         CommandComplete(iPendingCmdQueue, iPendingCmdQueue[1], PVMFErrCancelled);
5568 
5569     if (iRunningCmdQueue.size() > 1)
5570     {
5571         MoveCmdToCancelQueue(aCmd);
5572         return PVMFPending;
5573     }
5574 
5575     return PVMFSuccess;
5576 }
5577 
MoveCmdToCancelQueue(PVRTSPEngineCommand & aCmd)5578 void PVRTSPEngineNode::MoveCmdToCancelQueue(PVRTSPEngineCommand& aCmd)
5579 {
5580     /*
5581      * note: the StoreL cannot fail since the queue is never more than 1 deep
5582      * and we reserved space.
5583      */
5584     iCancelCmdQueue.StoreL(aCmd);
5585     iRunningCmdQueue.Erase(&aCmd);
5586 }
5587 
5588 
AllocateMediaData(int32 & errCode)5589 OsclSharedPtr<PVMFMediaDataImpl> PVRTSPEngineNode::AllocateMediaData(int32& errCode)
5590 {
5591     OsclSharedPtr<PVMFMediaDataImpl> mediaDataImplOut;
5592     OSCL_TRY(errCode, mediaDataImplOut = ipFragGroupAllocator->allocate());
5593     return mediaDataImplOut;
5594 }
5595