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