224 lines
8.3 KiB
C
224 lines
8.3 KiB
C
|
/*
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_START@
|
||
|
*
|
||
|
* Copyright (c) 1999-2008 Apple Inc. All Rights Reserved.
|
||
|
*
|
||
|
* This file contains Original Code and/or Modifications of Original Code
|
||
|
* as defined in and that are subject to the Apple Public Source License
|
||
|
* Version 2.0 (the 'License'). You may not use this file except in
|
||
|
* compliance with the License. Please obtain a copy of the License at
|
||
|
* http://www.opensource.apple.com/apsl/ and read it before using this
|
||
|
* file.
|
||
|
*
|
||
|
* The Original Code and all software distributed under the License are
|
||
|
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
|
||
|
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
|
||
|
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
|
||
|
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
|
||
|
* Please see the License for the specific language governing rights and
|
||
|
* limitations under the License.
|
||
|
*
|
||
|
* @APPLE_LICENSE_HEADER_END@
|
||
|
*
|
||
|
*/
|
||
|
/*
|
||
|
File: RTSPSessionInterface.h
|
||
|
|
||
|
Contains: Presents an API for session-wide resources for modules to use.
|
||
|
Implements the RTSP Session dictionary for QTSS API.
|
||
|
|
||
|
|
||
|
*/
|
||
|
|
||
|
#ifndef __RTSPSESSIONINTERFACE_H__
|
||
|
#define __RTSPSESSIONINTERFACE_H__
|
||
|
|
||
|
#include "RTSPRequestStream.h"
|
||
|
#include "RTSPResponseStream.h"
|
||
|
#include "Task.h"
|
||
|
#include "QTSS.h"
|
||
|
#include "QTSSDictionary.h"
|
||
|
#include "atomic.h"
|
||
|
#include "RTSPSession3GPP.h"
|
||
|
|
||
|
class RTSPSessionInterface : public QTSSDictionary, public Task
|
||
|
{
|
||
|
public:
|
||
|
|
||
|
//Initialize must be called right off the bat to initialize dictionary resources
|
||
|
static void Initialize();
|
||
|
static void SetBase64Decoding(Bool16 newVal) { sDoBase64Decoding = newVal; }
|
||
|
|
||
|
RTSPSessionInterface();
|
||
|
virtual ~RTSPSessionInterface();
|
||
|
|
||
|
//Is this session alive? If this returns false, clean up and begone as
|
||
|
//fast as possible
|
||
|
Bool16 IsLiveSession() { return fSocket.IsConnected() && fLiveSession; }
|
||
|
|
||
|
// Allows clients to refresh the timeout
|
||
|
void RefreshTimeout() { fTimeoutTask.RefreshTimeout(); }
|
||
|
|
||
|
// In order to facilitate sending out of band data on the RTSP connection,
|
||
|
// other objects need to have direct pointer access to this object. But,
|
||
|
// because this object is a task object it can go away at any time. If # of
|
||
|
// object holders is > 0, the RTSPSession will NEVER go away. However,
|
||
|
// the object managing the session should be aware that if IsLiveSession returns
|
||
|
// false it may be wise to relinquish control of the session
|
||
|
void IncrementObjectHolderCount() { (void)atomic_add(&fObjectHolders, 1); }
|
||
|
void DecrementObjectHolderCount();
|
||
|
|
||
|
// If RTP data is interleaved into the RTSP connection, we need to associate
|
||
|
// 2 unique channel numbers with each RTP stream, one for RTP and one for RTCP.
|
||
|
// This function allocates 2 channel numbers, returns the lower one. The other one
|
||
|
// is implicitly 1 greater.
|
||
|
//
|
||
|
// Pass in the RTSP Session ID of the Client session to which these channel numbers will
|
||
|
// belong.
|
||
|
UInt8 GetTwoChannelNumbers(StrPtrLen* inRTSPSessionID);
|
||
|
|
||
|
//
|
||
|
// Given a channel number, returns the RTSP Session ID to which this channel number refers
|
||
|
StrPtrLen* GetSessionIDForChannelNum(UInt8 inChannelNum);
|
||
|
|
||
|
//Two main things are persistent through the course of a session, not
|
||
|
//associated with any one request. The RequestStream (which can be used for
|
||
|
//getting data from the client), and the socket. OOps, and the ResponseStream
|
||
|
RTSPRequestStream* GetInputStream() { return &fInputStream; }
|
||
|
RTSPResponseStream* GetOutputStream() { return &fOutputStream; }
|
||
|
TCPSocket* GetSocket() { return &fSocket; }
|
||
|
OSMutex* GetSessionMutex() { return &fSessionMutex; }
|
||
|
|
||
|
UInt32 GetSessionID() { return fSessionID; }
|
||
|
|
||
|
// Request Body Length
|
||
|
// This object can enforce a length of the request body to prevent callers
|
||
|
// of Read() from overrunning the request body and going into the next request.
|
||
|
// -1 is an unknown request body length. If the body length is unknown,
|
||
|
// this object will do no length enforcement.
|
||
|
void SetRequestBodyLength(SInt32 inLength) { fRequestBodyLen = inLength; }
|
||
|
SInt32 GetRemainingReqBodyLen() { return fRequestBodyLen; }
|
||
|
|
||
|
// QTSS STREAM FUNCTIONS
|
||
|
|
||
|
// Allows non-buffered writes to the client. These will flow control.
|
||
|
|
||
|
// THE FIRST ENTRY OF THE IOVEC MUST BE BLANK!!!
|
||
|
virtual QTSS_Error WriteV(iovec* inVec, UInt32 inNumVectors, UInt32 inTotalLength, UInt32* outLenWritten);
|
||
|
virtual QTSS_Error Write(void* inBuffer, UInt32 inLength, UInt32* outLenWritten, UInt32 inFlags);
|
||
|
virtual QTSS_Error Read(void* ioBuffer, UInt32 inLength, UInt32* outLenRead);
|
||
|
virtual QTSS_Error RequestEvent(QTSS_EventType inEventMask);
|
||
|
|
||
|
// performs RTP over RTSP
|
||
|
QTSS_Error InterleavedWrite(void* inBuffer, UInt32 inLen, UInt32* outLenWritten, unsigned char channel);
|
||
|
|
||
|
// OPTIONS request
|
||
|
void SaveOutputStream();
|
||
|
void RevertOutputStream();
|
||
|
void ResetOutputStream() { fOutputStream.Reset(); fOutputStream.ResetBytesWritten();}
|
||
|
void SendOptionsRequest();
|
||
|
Bool16 SentOptionsRequest() { return fSentOptionsRequest; }
|
||
|
SInt32 RoundTripTime() { return fRoundTripTime; }
|
||
|
|
||
|
enum
|
||
|
{
|
||
|
kMaxUserNameLen = 32,
|
||
|
kMaxUserPasswordLen = 32,
|
||
|
kMaxUserRealmLen = 64
|
||
|
};
|
||
|
|
||
|
enum // Quality of protection
|
||
|
{
|
||
|
kNoQop = 0, // No Quality of protection
|
||
|
kAuthQop = 1, // Authentication
|
||
|
kAuthIntQop = 2 // Authentication with Integrity
|
||
|
};
|
||
|
|
||
|
// DJM PROTOTYPE
|
||
|
enum
|
||
|
{
|
||
|
kMaxRandomDataSize = 256 * 1024,
|
||
|
};
|
||
|
|
||
|
protected:
|
||
|
enum
|
||
|
{
|
||
|
kFirstRTSPSessionID = 1, //UInt32
|
||
|
};
|
||
|
|
||
|
//Each RTSP session has a unique number that identifies it.
|
||
|
|
||
|
char fUserNameBuf[kMaxUserNameLen];
|
||
|
char fUserPasswordBuf[kMaxUserPasswordLen];
|
||
|
char fUserRealmBuf[kMaxUserRealmLen];
|
||
|
|
||
|
TimeoutTask fTimeoutTask;//allows the session to be timed out
|
||
|
|
||
|
RTSPRequestStream fInputStream;
|
||
|
RTSPResponseStream fOutputStream;
|
||
|
|
||
|
// Any RTP session sending interleaved data on this RTSP session must
|
||
|
// be prevented from writing while an RTSP request is in progress
|
||
|
OSMutex fSessionMutex;
|
||
|
|
||
|
// for coalescing small interleaved writes into a single TCP frame
|
||
|
enum
|
||
|
{
|
||
|
kTCPCoalesceBufferSize = 1450 //1450 is the max data space in an TCP segment over ent
|
||
|
, kTCPCoalesceDirectWriteSize = 0 // if > this # bytes bypass coalescing and make a direct write
|
||
|
, kInteleaveHeaderSize = 4 // '$ '+ 1 byte ch ID + 2 bytes length
|
||
|
};
|
||
|
char* fTCPCoalesceBuffer;
|
||
|
SInt32 fNumInCoalesceBuffer;
|
||
|
|
||
|
|
||
|
//+rt socket we get from "accept()"
|
||
|
TCPSocket fSocket;
|
||
|
TCPSocket* fOutputSocketP;
|
||
|
TCPSocket* fInputSocketP; // <-- usually same as fSocketP, unless we're HTTP Proxying
|
||
|
|
||
|
void SnarfInputSocket( RTSPSessionInterface* fromRTSPSession );
|
||
|
|
||
|
// What session type are we?
|
||
|
QTSS_RTSPSessionType fSessionType;
|
||
|
Bool16 fLiveSession;
|
||
|
unsigned int fObjectHolders;
|
||
|
UInt8 fCurChannelNum;
|
||
|
StrPtrLen* fChNumToSessIDMap;
|
||
|
|
||
|
QTSS_StreamRef fStreamRef;
|
||
|
|
||
|
UInt32 fSessionID;
|
||
|
UInt32 fLocalAddr;
|
||
|
UInt32 fRemoteAddr;
|
||
|
SInt32 fRequestBodyLen;
|
||
|
|
||
|
UInt16 fLocalPort;
|
||
|
UInt16 fRemotePort;
|
||
|
|
||
|
// For OPTIONS request
|
||
|
StrPtrLen fOldOutputStreamBuffer;
|
||
|
Bool16 fSentOptionsRequest;
|
||
|
SInt64 fOptionsRequestSendTime;
|
||
|
SInt32 fRoundTripTime;
|
||
|
Bool16 fRoundTripTimeCalculation;
|
||
|
|
||
|
RTSPSession3GPP fRTSPSession3GPP;
|
||
|
RTSPSession3GPP* fRTSPSession3GPPPtr;
|
||
|
|
||
|
static unsigned int sSessionIDCounter;
|
||
|
static Bool16 sDoBase64Decoding;
|
||
|
|
||
|
static UInt32 sOptionsRequestBody[kMaxRandomDataSize / sizeof(UInt32)];
|
||
|
|
||
|
//Dictionary support
|
||
|
|
||
|
// Param retrieval function
|
||
|
static void* SetupParams(QTSSDictionary* inSession, UInt32* outLen);
|
||
|
|
||
|
static QTSSAttrInfoDict::AttrInfo sAttributes[];
|
||
|
};
|
||
|
#endif // __RTSPSESSIONINTERFACE_H__
|
||
|
|