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