Darwin-Streaming-Server/Server.tproj/RTSPSessionInterface.h

224 lines
8.3 KiB
C
Raw Normal View History

/*
*
* @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__