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 PVRTSP_CLIENT_ENGINE_NODE_H 19 #define PVRTSP_CLIENT_ENGINE_NODE_H 20 21 22 #ifndef OSCL_BASE_H_INCLUDED 23 #include "oscl_base.h" 24 #endif 25 26 #ifndef OSCL_UTF8CONV_H 27 #include "oscl_utf8conv.h" 28 #endif 29 30 #ifndef OSCL_ERROR_CODES_H_INCLUDED 31 #include "oscl_error_codes.h" 32 #endif 33 34 #ifndef OSCL_SCHEDULER_AO_H_INCLUDED 35 #include "oscl_scheduler_ao.h" 36 #endif 37 38 #ifndef OSCL_SOCKET_TYPES_H_INCLUDED 39 #include "oscl_socket_types.h" 40 #endif 41 42 #ifndef OSCL_SOCKET_H_INCLUDED 43 #include "oscl_socket.h" 44 #endif 45 46 #ifndef OSCL_DNS_H_INCLUDED 47 #include "oscl_dns.h" 48 #endif 49 50 #ifndef OSCL_STRING_CONTAINERS_H_INCLUDED 51 #include "oscl_string_containers.h" 52 #endif 53 54 #ifndef PVMF_MEDIA_CLOCK_H_INCLUDED 55 #include "pvmf_media_clock.h" 56 #endif 57 58 #ifndef OSCL_TIMER_H_INCLUDED 59 #include "oscl_timer.h" 60 #endif 61 62 #ifndef PVMF_FORMAT_TYPE_H_INCLUDED 63 #include "pvmf_format_type.h" 64 #endif 65 66 #ifndef PVMF_NODE_INTERFACE_H_INCLUDED 67 #include "pvmf_node_interface.h" 68 #endif 69 70 #ifndef PVMF_NODE_UTILS_H_INCLUDED 71 #include "pvmf_node_utils.h" 72 #endif 73 74 #ifndef OSCL_PRIQUEUE_H_INCLUDED 75 #include "oscl_priqueue.h" 76 #endif 77 78 #ifndef PVMF_SIMPLE_MEDIA_BUFFER_H_INCLUDED 79 #include "pvmf_simple_media_buffer.h" 80 #endif 81 82 #ifndef OSCL_MEM_MEMPOOL_H_INCLUDED 83 #include "oscl_mem_mempool.h" 84 #endif 85 86 #ifndef PVLOGGER_H_INCLUDED 87 #include "pvlogger.h" 88 #endif 89 90 #ifndef PVRTSP_ENGINE_NODE_EXTENSION_INTERFACE_H_INCLUDED 91 #include "pvrtspenginenodeextensioninterface.h" 92 #endif 93 94 #ifndef RTSP_PAR_COM_MESSAGE_DS_H_ 95 #include "rtsp_par_com_message.h" 96 #endif 97 98 #ifndef RTSP_PARSER_H_ 99 #include "rtsp_parser.h" 100 #endif 101 102 #ifndef SDP_PARSER_H 103 #include "sdp_parser.h" 104 #endif 105 106 #ifndef PVMF_RTSP_PORT_H_INCLUDED 107 #include "pvrtsp_client_engine_port.h" 108 #endif 109 110 #ifndef OSCL_FILEIO_H_INCLUDED 111 #include "oscl_file_io.h" 112 #endif 113 114 #ifndef PVMF_STREAMING_REAL_INTERFACES_INCLUDED 115 #include "pvmf_streaming_real_interfaces.h" 116 #endif 117 118 #ifndef PAYLOAD_PARSER_H_INCLUDED 119 #include "payload_parser.h" 120 #endif 121 122 #ifndef PVMF_SM_CONFIG_H_INCLUDED 123 #include "pvmf_sm_config.h" 124 #endif 125 126 //Default vector reserve size 127 #define PVMF_RTSP_ENGINE_NODE_COMMAND_VECTOR_RESERVE 10 128 129 //Starting value for command IDs 130 #define PVMF_RTSP_ENGINE_NODE_COMMAND_ID_START 6000 131 132 #define MAX_TOTAL_TRACKS 4 /* maximum number of channels per session */ 133 134 //The RTSP state enumeration 135 typedef enum 136 { 137 STATE_INIT, 138 STATE_READY, 139 STATE_PLAYING, 140 //STATE_RECORDING 141 } SessionState; 142 143 typedef struct _DataChannelInfo 144 { 145 uint8 *hexSID; 146 147 bool ssrc_is_set; 148 uint32 ssrc; 149 150 bool seqbase_is_set; 151 uint32 seq; 152 153 bool rtptime_is_set; 154 uint32 rtptime; 155 156 int32 offset; 157 uint32 timescale; 158 uint32 rtcp_interval; 159 } DataChannelInfo; 160 161 //memory allocator type for this node. 162 typedef OsclMemAllocator PVRTSPEngineNodeAllocator; 163 164 class SessionInfo 165 { 166 public: 167 //bool sdpFlag; //Used to make sure that we read into the mediainfo array after it has been assigned 168 //SDP_ERROR_CODE sdpErrorCode; //Saves the value returned from the sdp parser 169 170 OSCL_HeapString<PVRTSPEngineNodeAllocator> iSessionURL; 171 OSCL_HeapString<PVRTSPEngineNodeAllocator> iContentBaseURL;//Per session control URL from content base field 172 173 OSCL_HeapString<PVRTSPEngineNodeAllocator> iServerName; //could be either DNS or ip address 174 175 OSCL_HeapString<PVRTSPEngineNodeAllocator> iProxyName; //could be either DNS or ip address 176 uint32 iProxyPort; 177 178 OsclNetworkAddress iSrvAdd; 179 180 bool bExternalSDP; //true if got SDP through external(NOT DESCRIBE) methods 181 182 RtspRangeType iReqPlayRange; 183 RtspRangeType iActPlayRange; 184 185 OsclRefCounterMemFrag pSDPBuf; 186 187 OsclSharedPtr<SDPInfo> iSDPinfo; 188 //SDP_Parser *iSDPparser; //Pointer to the SDP_Parser class object 189 Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> iSelectedStream; 190 191 //Form the track to channel association table. This table is used while 192 //interacting with the media buffer. This table is needed to convert from an index 193 //based on the number of tracks in the SDP to an index into the number of tracks 194 //actually selected. For eg, the SDP might have 5 media tracks, but the number of tracks 195 //that get selected could be 2. If the first track that gets selected corresponds to the third 196 //track in the SDP list, then the mapping would be 2 -> 0. Similarly, if the second track that 197 //gets selected is the fifth in the SDP list, the mapping would be 4 -> 1. 198 //All indices begin from 0. 199 /* 200 for(int ii = 0; ii < numberOfChannels; ii++) 201 { 202 int sdp_track_id = pSessionInfo->trackSelectionList->getTrackIndex(ii); 203 pSessionInfo->channel_tbl[sdp_track_id] = ii; 204 } 205 */ 206 int number_of_channels; //Used for interaction with the media buffer class 207 int channel_tbl[MAX_TOTAL_TRACKS]; //Index from SDP track IDs to tracks actually selected 208 209 OSCL_HeapString<PVRTSPEngineNodeAllocator> iSID; //alphanumeric session ID 210 211 //OsclMemoryFragment pImgBuf; 212 213 bool serverReplyFlag; //Used for communication between the PVStream modules (network module and the task scheduler) 214 bool getStateFlag; //Used to ensure that the PE's main loop has been called 215 bool pvServerIsSetFlag; //Used to indicate if we are streaming from PVServer or not 216 bool tSIDIsSetFlag; //Used to send session id from second SETUP request 217 uint32 iServerVersionNumber; // Version number of PVSS 218 int32 prerollDuration; //Saves the jitter buffer size 219 220 int32 fwp_counter; //Id of the first returned firewall packet 221 int32 rtt; //Saves the round trip time for firewall exchange 222 uint32 roundTripDelay; //Saves the round trip delay for a DESCRIBE request 223 uint64 clientServerDelay; //Saves the client server delay during a DESCRIBE request 224 225 bool pipeLineFlag; //Used to indicate a pipe lined request 226 227 OSCL_HeapString<PVRTSPEngineNodeAllocator> iUserAgent; 228 OSCL_HeapString<PVRTSPEngineNodeAllocator> iUserNetwork; 229 OSCL_HeapString<PVRTSPEngineNodeAllocator> iDeviceInfo; 230 231 OSCL_HeapString<PVRTSPEngineNodeAllocator> iUserID; 232 OSCL_HeapString<PVRTSPEngineNodeAllocator> iAuthentication; 233 OSCL_HeapString<PVRTSPEngineNodeAllocator> iExpiration; 234 OSCL_HeapString<PVRTSPEngineNodeAllocator> iApplicationSpecificString; 235 OSCL_HeapString<PVRTSPEngineNodeAllocator> iVerification; 236 OSCL_HeapString<PVRTSPEngineNodeAllocator> iSignature; 237 238 enum PVRTSPStreamingType iStreamingType; 239 240 bool iSessionCompleted; UpdateSessionCompletionStatus(bool aSessionCompleted)241 void UpdateSessionCompletionStatus(bool aSessionCompleted) 242 { 243 iSessionCompleted = aSessionCompleted; 244 } 245 246 public: SessionInfo()247 SessionInfo(): 248 iProxyPort(0), 249 bExternalSDP(false), 250 pvServerIsSetFlag(false), 251 iServerVersionNumber(0), 252 roundTripDelay(0), 253 iSessionCompleted(false) 254 { 255 iUserAgent += _STRLIT_CHAR("PVPlayer "); 256 iReqPlayRange.format = RtspRangeType::INVALID_RANGE; 257 }; 258 259 } ; 260 261 class RTSPNodeMemDestructDealloc : public OsclDestructDealloc 262 { 263 public: destruct_and_dealloc(OsclAny * ptr)264 virtual void destruct_and_dealloc(OsclAny *ptr) 265 { 266 OSCL_FREE(ptr); 267 } 268 }; 269 270 typedef PVMFGenericNodeCommand<PVRTSPEngineNodeAllocator> PVRTSPEngineCommandBase; 271 272 enum TPVMFRtspNodeCommand //TPVMFGenericNodeCommand 273 { 274 PVMF_RTSP_NODE_ERROR_RECOVERY = PVMF_GENERIC_NODE_COMMAND_LAST + 1 275 , PVMF_RTSP_NODE_CANCELALLRESET 276 }; 277 class PVRTSPEngineCommand: public PVRTSPEngineCommandBase 278 { 279 public: 280 Construct(PVMFSessionId s,int32 cmd,int32 arg1,int32 arg2,int32 & arg3,const OsclAny * aContext)281 void Construct(PVMFSessionId s, int32 cmd, int32 arg1, int32 arg2, int32& arg3, \ 282 const OsclAny*aContext) 283 { 284 PVRTSPEngineCommandBase::Construct(s, cmd, aContext); 285 iParam1 = (OsclAny*)arg1; 286 iParam2 = (OsclAny*)arg2; 287 iParam3 = (OsclAny*) & arg3; 288 } Parse(int32 & arg1,int32 & arg2,int32 * & arg3)289 void Parse(int32&arg1, int32&arg2, int32*&arg3) 290 { 291 arg1 = (int32)iParam1; 292 arg2 = (int32)iParam2; 293 arg3 = (int32*)iParam3; 294 } hipri()295 virtual bool hipri() 296 { 297 if (iCmd == PVMF_RTSP_NODE_ERROR_RECOVERY) 298 return true; 299 300 return PVRTSPEngineCommandBase::hipri(); 301 } 302 303 /* 304 PVMFSessionId iCmdSid; 305 int32 iCmdId; 306 TPVMFGenericNodeCommand iCmdType; 307 OsclAny* iContext; 308 PVMFPortInterface* iPort; 309 OsclAny* iData1; 310 OsclAny* iData2; 311 OsclAny* iData3; 312 */ 313 private: 314 //PVRTSPEngineCommand(const PVRTSPEngineCommand& aCmd); 315 }; 316 317 //Command queue type 318 typedef PVMFNodeCommandQueue<PVRTSPEngineCommand, PVRTSPEngineNodeAllocator> PVRTSPEngineNodeCmdQ; 319 320 class PVRTSPGenericMessageCompareLess 321 { 322 public: 323 /** 324 * The algorithm used in OsclPriorityQueue needs a compare function 325 * that returns true when A's priority is less than B's 326 * @return true if A's priority is less than B's, else false 327 */ compare(RTSPGenericMessage * a,RTSPGenericMessage * b)328 int compare(RTSPGenericMessage* a, RTSPGenericMessage* b) const 329 { 330 return (PVRTSPGenericMessageCompareLess::GetPriority(*a) > PVRTSPGenericMessageCompareLess::GetPriority(*b)); 331 } 332 333 /** 334 * Returns the priority of each command 335 * @return A 0-based priority number. A lower number indicates lower priority. 336 */ GetPriority(RTSPGenericMessage & aCmd)337 static int GetPriority(RTSPGenericMessage &aCmd) 338 {//for cseq numbers, the low numbers come first. so higher priority 339 return aCmd.cseq; 340 } 341 }; 342 343 class GetPostCorrelationObject 344 { 345 public: 346 // factory method 347 static GetPostCorrelationObject *create(OSCL_TCHAR* aFileName = NULL); 348 // destructor 349 ~GetPostCorrelationObject(); 350 351 // get post correlation value get()352 uint8 get() const 353 { 354 return iGetPostCorrelation; 355 } 356 // increase get post correlation value by 1 within [1, 255] 357 bool update(); 358 359 private: 360 // constructor GetPostCorrelationObject()361 GetPostCorrelationObject() 362 { 363 ; 364 } 365 bool construct(OSCL_TCHAR* aFileName); 366 void closeFile(); 367 bool writeToFile(); 368 369 private: 370 uint8 iGetPostCorrelation; 371 bool iFileCreated; // check for the file creation 372 373 // File IO stuff 374 Oscl_FileServer iFs; 375 Oscl_File iGetPostCorrelationFile; 376 }; 377 378 class PVRTSPEngineNode 379 : public PVInterface, 380 public PVMFNodeInterface, 381 public OsclTimerObject, 382 public OsclSocketObserver, 383 public OsclDNSObserver, 384 public OsclTimerObserver, 385 public OsclMemPoolFixedChunkAllocatorObserver 386 { 387 public: 388 OSCL_IMPORT_REF PVRTSPEngineNode(int32 aPriority); 389 OSCL_IMPORT_REF virtual ~PVRTSPEngineNode(); 390 391 //************ begin PVMFNodeInterface 392 393 OSCL_IMPORT_REF virtual PVMFStatus ThreadLogon(); 394 OSCL_IMPORT_REF virtual PVMFStatus ThreadLogoff(); 395 396 /** 397 GetCapability can be invoked only when after a node is initialized 398 **/ 399 OSCL_IMPORT_REF virtual PVMFStatus GetCapability(PVMFNodeCapability& aNodeCapability); 400 401 /** 402 * Returns a list of ports currently available in the node that meet the filter criteria 403 * We can add fancier iterators and filters as needed. 404 * For now we return all the available ports. If no ports are present, NULL is returned 405 **/ 406 OSCL_IMPORT_REF virtual PVMFPortIter* GetPorts(const PVMFPortFilter* aFilter = NULL); 407 408 /** 409 * This API is to allow for extensibility of the PVMF Node interface. 410 * It allows a caller to ask for all UUIDs associated with a particular MIME type. 411 * If interfaces of the requested MIME type are found within the system, they are added 412 * to the UUIDs array. 413 * 414 * Also added to the UUIDs array will be all interfaces which have the requested MIME 415 * type as a base MIME type. This functionality can be turned off. 416 * 417 * @param aMimeType The MIME type of the desired interfaces 418 * @param aUuids A vector to hold the discovered UUIDs 419 * @param aExactUuidsOnly Turns on/off the retrival of UUIDs with aMimeType as a base type 420 * @param aContext Optional opaque data to be passed back to user with the command response 421 * @returns A unique command id for asynchronous completion 422 */ 423 OSCL_IMPORT_REF virtual PVMFCommandId QueryUUID(PVMFSessionId aSession 424 , const PvmfMimeString& aMimeType 425 , Oscl_Vector<PVUuid, PVRTSPEngineNodeAllocator>& aUuids 426 , bool aExactUuidsOnly = false 427 , const OsclAny* aContext = NULL); 428 429 /** 430 * This API is to allow for extensibility of the PVMF Node interface. 431 * It allows a caller to ask for an instance of a particular interface object to be returned. 432 * The mechanism is analogous to the COM IUnknown method. The interfaces are identified with 433 * an interface ID that is a UUID as in DCE and a pointer to the interface object is 434 * returned if it is supported. Otherwise the returned pointer is NULL. 435 * 436 * @param aUuid The UUID of the desired interface 437 * @param aInterfacePtr The output pointer to the desired interface 438 * @param aContext Optional opaque data to be passed back to user with the command response 439 * @returns A unique command id for asynchronous completion 440 */ 441 OSCL_IMPORT_REF virtual PVMFCommandId QueryInterface(PVMFSessionId aSession 442 , const PVUuid& aUuid 443 , PVInterface*& aInterfacePtr 444 , const OsclAny* aContext = NULL); 445 446 /** 447 * Requests the node to return a port meeting certain criteria for format types and buffering 448 * capabilities. The node may return a reference to an already created unused port or it may dynamically 449 * create one if it has the capability to do so. Since there might be some port specific initializations 450 * that might need to be done for ports created on demand, it will be most flexible to have this as an 451 * asynchronous API. 452 * A reference to the port interface is returned with the the command completion. It is passed as an auto ptr 453 * carrying opaque data that needs to be cast to PVMFPortInterface* 454 * @exception PVMFErrNotSupported leaves if this is not supported. 455 **/ 456 OSCL_IMPORT_REF virtual PVMFCommandId RequestPort(PVMFSessionId aSession 457 , int32 aPortTag 458 , const PvmfMimeString* aPortConfig = NULL 459 , const OsclAny* aContext = NULL); 460 461 /** 462 * Releases a port back to the owning node. 463 * @exception PVMFErrArgument leaves if this node is not the owner. 464 **/ 465 OSCL_IMPORT_REF virtual PVMFCommandId ReleasePort(PVMFSessionId aSession 466 , PVMFPortInterface& aPort 467 , const OsclAny* aContext = NULL); 468 469 //Describe, 470 OSCL_IMPORT_REF virtual PVMFCommandId Init(PVMFSessionId aSession 471 , const OsclAny* aContext = NULL); 472 473 OSCL_IMPORT_REF virtual PVMFCommandId Prepare(PVMFSessionId aSession, 474 const OsclAny* aContext = NULL); 475 476 //Setup, Firewall pkts exchange, Play 477 /** 478 * Causes the node to start servicing all connected ports. 479 **/ 480 OSCL_IMPORT_REF virtual PVMFCommandId Start(PVMFSessionId aSession 481 , const OsclAny* aContext = NULL); 482 483 //Pause 484 /** 485 * Causes the node to pause servicing all connected ports without 486 * discarding un-processed data. 487 **/ 488 OSCL_IMPORT_REF virtual PVMFCommandId Pause(PVMFSessionId aSession 489 , const OsclAny* aContext = NULL); 490 491 //Teardown 492 OSCL_IMPORT_REF virtual PVMFCommandId Stop(PVMFSessionId aSession 493 , const OsclAny* aContext = NULL); 494 495 /** 496 * Resets the node. The node should relinquish all resources that is has acquired as part of the 497 * initialization process and should be ready to be deleted when this completes. 498 **/ 499 OSCL_IMPORT_REF virtual PVMFCommandId Reset(PVMFSessionId aSession 500 , const OsclAny* aContext = NULL); 501 502 /** 503 * Causes the node to stop servicing all connected ports as 504 * soon as current data is processed. 505 **/ 506 OSCL_IMPORT_REF virtual PVMFCommandId Flush(PVMFSessionId aSession 507 , const OsclAny* aContext = NULL); 508 509 510 /** 511 * Cancel all pending requests. The current request being processed, if any, will also be aborted. 512 * 513 * @param aContextData Optional opaque data that will be passed back to the user with the command response 514 * @returns A unique command id for asynchronous completion 515 */ 516 OSCL_IMPORT_REF virtual PVMFCommandId CancelAllCommands(PVMFSessionId aSession 517 , const OsclAny* aContextData = NULL); 518 519 /** 520 * Cancels pending command with the specified ID. 521 * 522 * @param aCmdId Command Id of the command to be cancelled 523 * @param aContextData Optional opaque data that will be passed back to the user with the command response 524 * @returns A unique command id for asynchronous completion 525 */ 526 OSCL_IMPORT_REF virtual PVMFCommandId CancelCommand(PVMFSessionId aSession 527 , PVMFCommandId aCmdId 528 , const OsclAny* aContextData = NULL); 529 530 /** 531 * Ports call this API to report activity to the node. 532 * 533 * @param aActivity Information regarding the activity. 534 */ 535 OSCL_IMPORT_REF void HandlePortActivity(const PVMFPortActivity& aActivity); 536 537 //************ end PVMFNodeInterface 538 539 //************ begin PVRTSPEngineNodeExtensionInterface 540 OSCL_IMPORT_REF virtual void addRef(); 541 OSCL_IMPORT_REF virtual void removeRef(void); 542 OSCL_IMPORT_REF virtual bool queryInterface(const PVUuid& uuid, PVInterface*& iface); 543 544 OSCL_IMPORT_REF virtual PVMFStatus SetStreamingType(PVRTSPStreamingType aType = PVRTSP_3GPP_UDP); 545 546 OSCL_IMPORT_REF virtual PVMFStatus SetSessionURL(OSCL_wString& aURL); 547 548 OSCL_IMPORT_REF virtual PVMFStatus SetRtspProxy(OSCL_String& aRtspProxyName, uint32 aRtspProxyPort); 549 OSCL_IMPORT_REF virtual PVMFStatus GetRtspProxy(OSCL_String& aRtspProxyName, uint32& aRtspProxyPort); 550 551 OSCL_IMPORT_REF virtual PVMFStatus GetSDP(OsclRefCounterMemFrag& aSDPBuf); 552 OSCL_IMPORT_REF virtual PVMFStatus SetSDPInfo(OsclSharedPtr<SDPInfo>& aSDPinfo, Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> &aSelectedStream); 553 OSCL_IMPORT_REF virtual PVMFStatus GetServerInfo(PVRTSPEngineNodeServerInfo& aServerInfo); 554 OSCL_IMPORT_REF virtual PVMFStatus GetStreamInfo(Oscl_Vector<StreamInfo, PVRTSPEngineNodeAllocator> &aSelectedStream); 555 556 OSCL_IMPORT_REF virtual PVMFStatus GetUserAgent(OSCL_wString& aUserAgent); 557 558 OSCL_IMPORT_REF virtual PVMFStatus SetClientParameters(OSCL_wString& aUserAgent, 559 OSCL_wString& aUserNetwork, 560 OSCL_wString& aDeviceInfo); 561 562 OSCL_IMPORT_REF virtual bool IsRdtTransport(); 563 OSCL_IMPORT_REF virtual void SetPortRdtStreamId(PVMFPortInterface* pPort, 564 int iRdtStreamId); 565 566 OSCL_IMPORT_REF virtual void SetRealChallengeCalculator(IRealChallengeGen* pChallengeCalc); 567 OSCL_IMPORT_REF virtual void SetRdtParser(IPayloadParser* pRdtParser); 568 569 OSCL_IMPORT_REF virtual PVMFStatus SetAuthenticationParameters(OSCL_wString& aUserID, 570 OSCL_wString& aAuthentication, 571 OSCL_wString& aExpiration, 572 OSCL_wString& aApplicationSpecificString, 573 OSCL_wString& aVerification, 574 OSCL_wString& aSignature); 575 576 OSCL_IMPORT_REF virtual PVMFStatus SetRequestPlayRange(const RtspRangeType& aRange); 577 OSCL_IMPORT_REF virtual PVMFStatus GetActualPlayRange(RtspRangeType& aRange); 578 579 OSCL_IMPORT_REF virtual PVMFStatus SetKeepAliveMethod_timeout(int32 aTimeout = 0); 580 OSCL_IMPORT_REF virtual PVMFStatus SetKeepAliveMethod_use_SET_PARAMETER(bool aUseSetParameter = false); 581 OSCL_IMPORT_REF virtual PVMFStatus SetKeepAliveMethod_keep_alive_in_play(bool aKeepAliveInPlay = false); 582 583 OSCL_IMPORT_REF virtual PVMFStatus GetKeepAliveMethod(int32 &aTimeout, bool &aUseSetParameter, bool &aKeepAliveInPlay); 584 585 586 OSCL_IMPORT_REF virtual PVMFStatus GetRTSPTimeOut(int32 &aTimeout); 587 OSCL_IMPORT_REF virtual PVMFStatus SetRTSPTimeOut(int32 aTimeout); 588 589 //************ end PVRTSPEngineNodeExtensionInterface 590 591 //************ begin OsclTimerObserver 592 OSCL_IMPORT_REF virtual void TimeoutOccurred(int32 timerID, int32 timeoutInfo); 593 594 //************ begin OsclSocketObserver 595 OSCL_IMPORT_REF virtual void HandleSocketEvent(int32 aId, TPVSocketFxn aFxn, TPVSocketEvent aEvent, int32 aError); 596 //************ end OsclSocketObserver 597 598 //************ begin OsclDNSObserver 599 OSCL_IMPORT_REF virtual void HandleDNSEvent(int32 aId, TPVDNSFxn aFxn, TPVDNSEvent aEvent, int32 aError); 600 //************ end OsclDNSObserver 601 602 //************ begin OsclMemPoolFixedChunkAllocatorObserver 603 void freechunkavailable(OsclAny*); 604 //************ end OsclMemPoolFixedChunkAllocatorObserver 605 UpdateSessionCompletionStatus(bool aSessionCompleted)606 void UpdateSessionCompletionStatus(bool aSessionCompleted) 607 { 608 iSessionInfo.iSessionCompleted = aSessionCompleted; 609 } 610 IsSessionCompleted()611 bool IsSessionCompleted() const 612 { 613 return iSessionInfo.iSessionCompleted; 614 } 615 616 typedef struct _SocketEvent 617 { 618 int32 iSockId; 619 TPVSocketFxn iSockFxn; 620 TPVSocketEvent iSockEvent; 621 int32 iSockError; 622 } SocketEvent; 623 624 enum PVRTSPEngineState 625 { 626 //for async request 627 PVRTSP_ENGINE_NODE_STATE_IDLE, 628 PVRTSP_ENGINE_NODE_STATE_DNS_RESOLVING, 629 630 PVRTSP_ENGINE_NODE_STATE_CONNECT, 631 PVRTSP_ENGINE_NODE_STATE_CONNECTING, 632 633 PVRTSP_ENGINE_NODE_STATE_HTTP_CLOAKING_SETUP, 634 635 PVRTSP_ENGINE_NODE_STATE_SEND_OPTIONS, 636 PVRTSP_ENGINE_NODE_STATE_SEND_DESCRIBE, 637 PVRTSP_ENGINE_NODE_STATE_OPTIONS_WAITING, 638 PVRTSP_ENGINE_NODE_STATE_DESCRIBE_WAITING, 639 640 PVRTSP_ENGINE_NODE_STATE_DESCRIBE_DONE, 641 PVRTSP_ENGINE_NODE_STATE_PROCESS_REST_SETUP, 642 643 PVRTSP_ENGINE_NODE_STATE_SETUP_DONE, 644 PVRTSP_ENGINE_NODE_STATE_WAIT_PLAY, 645 646 PVRTSP_ENGINE_NODE_STATE_PLAY_DONE, 647 PVRTSP_ENGINE_NODE_STATE_WAIT_PAUSE, 648 PVRTSP_ENGINE_NODE_STATE_PAUSE_DONE, 649 650 PVRTSP_ENGINE_NODE_STATE_WAIT_STOP, 651 652 PVRTSP_ENGINE_NODE_STATE_WAIT_CALLBACK, 653 654 PVRTSP_ENGINE_NODE_STATE_INVALID 655 } iState; 656 657 private: 658 OsclSharedPtr<PVMFMediaDataImpl> AllocateMediaData(int32& errCode); 659 Oscl_Vector<SocketEvent, PVRTSPEngineNodeAllocator> iSocketEventQueue; 660 661 PVRTSPEngineNodeAllocator iAlloc; 662 663 PVMFCommandId iCurrentCmdId; 664 665 OsclSocketServ *iSockServ; 666 667 //note: this class is for internal use only, but must be public to avoid ADS v1.2 compile error. 668 public: 669 //To keep track of current socket op 670 class SocketState 671 { 672 public: SocketState()673 SocketState() 674 : iPending(false) 675 , iCanceled(false) 676 {} 677 bool iPending; 678 bool iCanceled; Reset()679 void Reset() 680 { 681 iPending = iCanceled = false; 682 } 683 }; 684 685 private: 686 687 //Container for a TCP socket that can connect, send, & recv. 688 class SocketContainer 689 { 690 public: SocketContainer()691 SocketContainer(): iSocket(NULL) 692 {} 693 OsclTCPSocket* iSocket; 694 SocketState iConnectState; 695 SocketState iSendState; 696 SocketState iRecvState; 697 SocketState iShutdownState; Reset(OsclTCPSocket * aSock)698 void Reset(OsclTCPSocket* aSock) 699 { 700 iSocket = aSock; 701 iConnectState.Reset(); 702 iSendState.Reset(); 703 iRecvState.Reset(); 704 iShutdownState.Reset(); 705 } IsBusy()706 bool IsBusy() 707 { 708 return iSocket 709 && (iConnectState.iPending 710 || iSendState.iPending 711 || iRecvState.iPending 712 || iShutdownState.iPending); 713 } 714 }; 715 class DnsContainer 716 { 717 public: DnsContainer()718 DnsContainer(): iDns(NULL) 719 {} 720 OsclDNS* iDns; 721 SocketState iState; IsBusy()722 bool IsBusy() 723 { 724 return (iDns 725 && iState.iPending); 726 } 727 }; 728 void SetSendPending(SocketContainer&); 729 void SetRecvPending(SocketContainer&); 730 731 SocketContainer iSendSocket, iRecvSocket; 732 DnsContainer iDNS; 733 734 //To keep track of socket reset sequence. 735 enum TSocketCleanupState 736 { 737 ESocketCleanup_Idle 738 , ESocketCleanup_CancelCurrentOp 739 , ESocketCleanup_WaitOnCancel 740 , ESocketCleanup_Shutdown 741 , ESocketCleanup_WaitOnShutdown 742 , ESocketCleanup_Delete 743 }; 744 TSocketCleanupState iSocketCleanupState; 745 746 //only for http cloaking, string to store the text to send until send completes 747 OSCL_HeapString<PVRTSPEngineNodeAllocator> iRecvChannelMsg, iSendChannelMsg; 748 749 RTSPParser *iRTSPParser; 750 RTSPParser::ParserState iRTSPParserState; 751 RTSPIncomingMessage iIncomingMsg; 752 uint32 iOutgoingSeq; 753 754 bool bNoRecvPending;//an Recv() is pending on RTSP socket 755 bool bNoSendPending;//a Send() is pending on RTSP socket 756 757 PVMFPortInterface* iTheBusyPort; 758 //OsclMemoryFragment entityBody; //Used to register with RTSP parser 759 //OsclMemoryFragment embeddedDataMemory; //Used to save embedded binary data 760 761 SessionInfo iSessionInfo; 762 763 PVLogger* iLogger; 764 765 //uint8 iBufEmbedded[2048]; 766 //RTSPEntityBody iEmbeddedData; 767 PVMFSharedMediaDataPtr iEmbeddedDataPtr; 768 // Reference counter for extension 769 uint32 iExtensionRefCount; 770 uint32 iNumRedirectTrials; 771 772 //socket server will callback even if Cancel() is called 773 //most likely this is the case for OsclDNS as well 774 //But this is NOT the case for OsclTimer 775 uint32 iNumHostCallback, iNumConnectCallback, iNumSendCallback, iNumRecvCallback; 776 int BASE_REQUEST_ID; 777 static const int REQ_SEND_SOCKET_ID; 778 static const int REQ_RECV_SOCKET_ID; 779 int REQ_TIMER_WATCHDOG_ID, REQ_TIMER_KEEPALIVE_ID; 780 int REQ_DNS_LOOKUP_ID; 781 782 783 const int DEFAULT_RTSP_PORT, DEFAULT_HTTP_PORT; 784 785 //these three are in milliseconds 786 const int TIMEOUT_CONNECT_AND_DNS_LOOKUP, TIMEOUT_SEND, TIMEOUT_RECV; 787 const int TIMEOUT_SHUTDOWN; 788 789 //these two are in seconds 790 int TIMEOUT_WATCHDOG; 791 const int TIMEOUT_WATCHDOG_TEARDOWN; 792 int TIMEOUT_KEEPALIVE; 793 const int RECOMMENDED_RTP_BLOCK_SIZE; 794 795 int setupTrackIndex; 796 bool bRepositioning; 797 798 class PVRTSPErrorContext 799 { 800 public: 801 SocketEvent iErrSockEvent; 802 PVRTSPEngineState iErrState; 803 }; 804 805 806 //temp string compose buffer for internal use RTSP_MAX_FULL_REQUEST_SIZE 807 OsclMemoryFragment iRTSPEngTmpBuf; 808 OsclMemoryFragment iEntityMemFrag; 809 //OsclRefCounterMemFrag iEntityMemFrag; 810 811 // Queue of commands for cancel 812 PVRTSPEngineNodeCmdQ iCancelCmdQueue; 813 // Queue of commands user requested 814 PVRTSPEngineNodeCmdQ iPendingCmdQueue; 815 816 //Queue for cmds which are running. 817 //normally this node will not start processing one command 818 //until the prior one is finished. However, a hi priority 819 //command such as Cancel must be able to interrupt a command 820 //in progress. 821 PVRTSPEngineNodeCmdQ iRunningCmdQueue; 822 PVMFPortVector<PVMFRTSPPort, PVRTSPEngineNodeAllocator> iPortVector; 823 /** 824 * Queue holding port activity. Only incoming and outgoing msg activity are 825 * put on the queue. For each port, there should only be at most one activity 826 * of each type on the queue. 827 */ 828 Oscl_Vector<PVMFPortActivity, PVRTSPEngineNodeAllocator> iPortActivityQueue; 829 PVMFNodeCapability iCapability; 830 831 //OsclPriorityQueue<PVRTSPEngineCommand,PVRTSPEngineNodeAllocator,Oscl_Vector<PVRTSPEngineCommand,PVRTSPEngineNodeAllocator>,PVRTSPEngineCommandCompareLess> iPendingCmdQueue; 832 // Oscl_Vector<PVRTSPEngineAsyncEvent, PVRTSPEngineNodeAllocator> iPendingEvents; 833 834 // OsclPriorityQueue<RTSPIncomingMessage,PVRTSPEngineNodeAllocator,Oscl_Vector<RTSPIncomingMessage,PVRTSPEngineNodeAllocator>,PVRTSPGenericMessageCompareLess> iIncomingMsgQueue; 835 OsclPriorityQueue<RTSPOutgoingMessage*, PVRTSPEngineNodeAllocator, Oscl_Vector<RTSPOutgoingMessage*, PVRTSPEngineNodeAllocator>, PVRTSPGenericMessageCompareLess> iOutgoingMsgQueue; 836 RTSPOutgoingMessage* iSrvResponse; 837 bool bSrvRespPending; 838 839 OsclTimer<PVRTSPEngineNodeAllocator> *iWatchdogTimer; 840 841 int32 iCurrentErrorCode; 842 PVUuid iEventUUID; 843 844 bool bKeepAliveInPlay; 845 RTSPMethod iKeepAliveMethod; 846 847 bool bAddXStrHeader; 848 849 OsclMemPoolResizableAllocator *iMediaDataResizableAlloc; 850 PVMFSimpleMediaBufferCombinedAlloc *iMediaDataImplAlloc; 851 852 /* Round trip delay calculation */ 853 PVMFTimebase_Tickcount iRoundTripClockTimeBase; 854 855 int32 iErrorRecoveryAttempt; 856 857 //uint8 iGetPostCorrelation; 858 GetPostCorrelationObject *iGetPostCorrelationObject; 859 private: 860 PVRTSPEngineNode(); 861 PVRTSPEngineNode& operator = (const PVRTSPEngineNode&); 862 PVRTSPEngineNode(const PVRTSPEngineNode&); 863 864 //OsclActiveObject 865 virtual void Run(); 866 virtual OsclLeaveCode RunError(OsclLeaveCode aError); 867 868 PVMFStatus sendSocketOutgoingMsg(SocketContainer &aSock, RTSPOutgoingMessage &aMsg); 869 PVMFStatus sendSocketOutgoingMsg(SocketContainer &aSock, const uint8* aSendBuf, uint32 aSendLen); 870 871 void ChangeExternalState(TPVMFNodeInterfaceState aNewState); 872 873 // Handle command and data events 874 PVMFCommandId AddCmdToQueue(PVRTSPEngineCommand& aCmd); 875 876 bool ProcessCommand(PVRTSPEngineCommand& aCmd); 877 bool rtspParserLoop(void); 878 879 PVMFStatus DispatchCommand(PVRTSPEngineCommand& aCmd); 880 void MoveCmdToCancelQueue(PVRTSPEngineCommand& aCmd); 881 882 PVMFStatus DoInitNode(PVRTSPEngineCommand &aCmd); 883 PVMFStatus DoPrepareNode(PVRTSPEngineCommand &aCmd); 884 PVMFStatus DoStartNode(PVRTSPEngineCommand &aCmd); 885 PVMFStatus DoPauseNode(PVRTSPEngineCommand &aCmd); 886 PVMFStatus DoStopNode(PVRTSPEngineCommand &aCmd); 887 PVMFStatus DoResetNode(PVRTSPEngineCommand &aCmd); 888 PVMFStatus DoQueryUuid(PVRTSPEngineCommand &aCmd); 889 PVMFStatus DoQueryInterface(PVRTSPEngineCommand &aCmd); 890 PVMFStatus DoCancelCommand(PVRTSPEngineCommand &aCmd); 891 PVMFStatus DoCancelAllCommands(PVRTSPEngineCommand &aCmd); 892 PVMFStatus DoFlush(PVRTSPEngineCommand &aCmd); 893 894 PVMFStatus DoErrorRecovery(PVRTSPEngineCommand &aCmd); 895 896 PVMFStatus DoRequestPort(PVRTSPEngineCommand &aCmd, PVMFRTSPPort* &aPort); 897 PVMFStatus DoAddPort(int32 id, bool isMedia, int32 tag, PVMFRTSPPort* &aPort); 898 PVMFStatus DoReleasePort(PVRTSPEngineCommand &aCmd); 899 900 bool FlushPending(); 901 bool ProcessPortActivity(); 902 void QueuePortActivity(const PVMFPortActivity &aActivity); 903 PVMFStatus ProcessOutgoingMsg(PVMFPortInterface* aPort); 904 905 PVMFStatus SendRtspDescribe(PVRTSPEngineCommand &aCmd); 906 PVMFStatus SendRtspSetup(PVRTSPEngineCommand &aCmd); 907 PVMFStatus SendRtspPlay(PVRTSPEngineCommand &aCmd); 908 PVMFStatus SendRtspPause(PVRTSPEngineCommand &aCmd); 909 PVMFStatus SendRtspTeardown(PVRTSPEngineCommand &aCmd); 910 911 void CommandComplete(PVRTSPEngineNodeCmdQ&, 912 PVRTSPEngineCommand&, 913 PVMFStatus, OsclAny* aData = NULL, 914 PVUuid* aEventUUID = NULL, 915 int32* aEventCode = NULL); 916 917 bool parseURL(const OSCL_wString& aURL); 918 bool parseURL(const char* aURL); 919 920 921 void ChangeInternalState(PVRTSPEngineState aNewTask); 922 PVMFStatus composeOptionsRequest(RTSPOutgoingMessage&); 923 PVMFStatus composeDescribeRequest(RTSPOutgoingMessage&); 924 PVMFStatus composeSetupRequest(RTSPOutgoingMessage &iMsg, StreamInfo &aSelected); 925 PVMFStatus composePlayRequest(RTSPOutgoingMessage &iMsg); 926 PVMFStatus composeStopRequest(RTSPOutgoingMessage &iMsg); 927 PVMFStatus composePauseRequest(RTSPOutgoingMessage &iMsg); 928 PVMFStatus composeKeepAliveRequest(RTSPOutgoingMessage &aMsg); 929 930 PVMFStatus composeGetRequest(RTSPOutgoingMessage &iMsg); 931 PVMFStatus composePostRequest(RTSPOutgoingMessage &iMsg); 932 933 PVMFStatus processIncomingMessage(RTSPIncomingMessage &iIncomingMsg); 934 PVMFStatus processServerRequest(RTSPIncomingMessage &aMsg); 935 PVMFStatus processEntityBody(RTSPIncomingMessage &aMsg, OsclMemoryFragment &aEntityMemFrag); 936 937 PVMFStatus processCommonResponse(RTSPIncomingMessage &aMsg); 938 939 //should merge togather and move to jitter buffer 940 PVMFStatus composeSessionURL(RTSPOutgoingMessage &aMsg); 941 PVMFStatus composeMediaURL(int aTrackID, StrPtrLen &aMediaURI); 942 943 //PVMFStatus processSDP(OsclMemoryFragment &aSDPBuf, SDPInfo &aSDPinfo); 944 945 void ReportErrorEvent(PVMFEventType aEventType, 946 OsclAny* aEventData = NULL, 947 PVUuid* aEventUUID = NULL, 948 int32* aEventCode = NULL); 949 void ReportInfoEvent(PVMFEventType aEventType, 950 OsclAny* aEventData = NULL, 951 PVUuid* aEventUUID = NULL, 952 int32* aEventCode = NULL); 953 954 void MapRTSPCodeToEventCode(RTSPStatusCode aStatusCode, 955 int32& aEventCode); 956 //allocate aReqBufSize memory for iEmbeddedData 957 bool PrepareEmbeddedDataMemory(uint32 aReqBufSize, OsclMemoryFragment &); 958 bool DispatchEmbeddedData(uint32 aChannelID); 959 // private members added for real support 960 bool ibIsRealRDT; 961 962 // realchallenge1 string returned by OPTIONS request 963 OSCL_HeapString<OsclMemAllocator> iRealChallenge1; 964 965 // realchallenge2 string to be sent in SETUP request 966 OSCL_HeapString<OsclMemAllocator> iRealChallenge2; 967 968 IRealChallengeGen* ipRealChallengeGen; 969 IPayloadParser* ipRdtParser; 970 971 // allocator for outgoing media frag groups 972 PVMFMediaFragGroupCombinedAlloc<OsclMemAllocator>* ipFragGroupAllocator; 973 OsclMemPoolFixedChunkAllocator* ipFragGroupMemPool; 974 975 ///// 976 977 978 bool DispatchEmbeddedRdtData(); 979 bool ibBlockedOnFragGroups; 980 //bool simpleHttpParser(const uint8 *aBuf, int32 &aLen, bool &aIsStatus200); 981 982 PVMFStatus resetSocket(bool aImmediate = false); 983 void clearOutgoingMsgQueue(void); 984 void partialResetSessionInfo(void); 985 986 bool clearEventQueue(void); 987 988 void ResetSessionInfo(void); 989 PVRTSPEngineNodeExtensionInterface* iExtensionInterface; 990 }; 991 992 #endif //PVRTSP_CLIENT_ENGINE_NODE_H 993