00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _RTSP_SERVER_HH
00022 #define _RTSP_SERVER_HH
00023
00024 #ifndef _SERVER_MEDIA_SESSION_HH
00025 #include "ServerMediaSession.hh"
00026 #endif
00027 #ifndef _NET_ADDRESS_HH
00028 #include <NetAddress.hh>
00029 #endif
00030 #ifndef _DIGEST_AUTHENTICATION_HH
00031 #include "DigestAuthentication.hh"
00032 #endif
00033
00034
00035
00036 class UserAuthenticationDatabase {
00037 public:
00038 UserAuthenticationDatabase(char const* realm = NULL,
00039 Boolean passwordsAreMD5 = False);
00040
00041
00042
00043 virtual ~UserAuthenticationDatabase();
00044
00045 virtual void addUserRecord(char const* username, char const* password);
00046 virtual void removeUserRecord(char const* username);
00047
00048 virtual char const* lookupPassword(char const* username);
00049
00050
00051 char const* realm() { return fRealm; }
00052 Boolean passwordsAreMD5() { return fPasswordsAreMD5; }
00053
00054 protected:
00055 HashTable* fTable;
00056 char* fRealm;
00057 Boolean fPasswordsAreMD5;
00058 };
00059
00060 #define RTSP_BUFFER_SIZE 10000 // for incoming requests, and outgoing responses
00061
00062 class RTSPServer: public Medium {
00063 public:
00064 static RTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554,
00065 UserAuthenticationDatabase* authDatabase = NULL,
00066 unsigned reclamationTestSeconds = 65);
00067
00068
00069
00070
00071
00072
00073
00074 static Boolean lookupByName(UsageEnvironment& env, char const* name,
00075 RTSPServer*& resultServer);
00076
00077 void addServerMediaSession(ServerMediaSession* serverMediaSession);
00078 virtual ServerMediaSession* lookupServerMediaSession(char const* streamName);
00079 void removeServerMediaSession(ServerMediaSession* serverMediaSession);
00080 void removeServerMediaSession(char const* streamName);
00081
00082 char* rtspURL(ServerMediaSession const* serverMediaSession, int clientSocket = -1) const;
00083
00084
00085
00086
00087
00088
00089 char* rtspURLPrefix(int clientSocket = -1) const;
00090
00091
00092
00093
00094 protected:
00095 RTSPServer(UsageEnvironment& env,
00096 int ourSocket, Port ourPort,
00097 UserAuthenticationDatabase* authDatabase,
00098 unsigned reclamationTestSeconds);
00099
00100 virtual ~RTSPServer();
00101
00102 static int setUpOurSocket(UsageEnvironment& env, Port& ourPort);
00103 virtual Boolean specialClientAccessCheck(int clientSocket, struct sockaddr_in& clientAddr,
00104 char const* urlSuffix);
00105
00106
00107
00108
00109 private:
00110 virtual Boolean isRTSPServer() const;
00111
00112 private:
00113 static void incomingConnectionHandler(void*, int );
00114 void incomingConnectionHandler1();
00115
00116
00117 class RTSPClientSession {
00118 public:
00119 RTSPClientSession(RTSPServer& ourServer, unsigned sessionId,
00120 int clientSocket, struct sockaddr_in clientAddr);
00121 virtual ~RTSPClientSession();
00122 private:
00123 UsageEnvironment& envir() { return fOurServer.envir(); }
00124 void reclaimStreamStates();
00125 void resetRequestBuffer();
00126 static void incomingRequestHandler(void*, int );
00127 void incomingRequestHandler1();
00128 void handleCmd_bad(char const* cseq);
00129 void handleCmd_notSupported(char const* cseq);
00130 void handleCmd_notFound(char const* cseq);
00131 void handleCmd_unsupportedTransport(char const* cseq);
00132 void handleCmd_OPTIONS(char const* cseq);
00133 void handleCmd_DESCRIBE(char const* cseq, char const* urlSuffix,
00134 char const* fullRequestStr);
00135 void handleCmd_SETUP(char const* cseq,
00136 char const* urlPreSuffix, char const* urlSuffix,
00137 char const* fullRequestStr);
00138 void handleCmd_withinSession(char const* cmdName,
00139 char const* urlPreSuffix, char const* urlSuffix,
00140 char const* cseq, char const* fullRequestStr);
00141 void handleCmd_TEARDOWN(ServerMediaSubsession* subsession,
00142 char const* cseq);
00143 void handleCmd_PLAY(ServerMediaSubsession* subsession,
00144 char const* cseq, char const* fullRequestStr);
00145 void handleCmd_PAUSE(ServerMediaSubsession* subsession,
00146 char const* cseq);
00147 void handleCmd_GET_PARAMETER(ServerMediaSubsession* subsession,
00148 char const* cseq, char const* fullRequestStr);
00149 Boolean authenticationOK(char const* cmdName, char const* cseq,
00150 char const* urlSuffix,
00151 char const* fullRequestStr);
00152 void noteLiveness();
00153 Boolean isMulticast() const { return fIsMulticast; }
00154 static void noteClientLiveness(RTSPClientSession* clientSession);
00155 static void livenessTimeoutTask(RTSPClientSession* clientSession);
00156
00157 private:
00158 RTSPServer& fOurServer;
00159 unsigned fOurSessionId;
00160 ServerMediaSession* fOurServerMediaSession;
00161 int fClientSocket;
00162 struct sockaddr_in fClientAddr;
00163 TaskToken fLivenessCheckTask;
00164 unsigned char fRequestBuffer[RTSP_BUFFER_SIZE];
00165 unsigned fRequestBytesAlreadySeen, fRequestBufferBytesLeft;
00166 unsigned char* fLastCRLF;
00167 unsigned char fResponseBuffer[RTSP_BUFFER_SIZE];
00168 Boolean fIsMulticast, fSessionIsActive, fStreamAfterSETUP;
00169 Authenticator fCurrentAuthenticator;
00170 unsigned char fTCPStreamIdCount;
00171 unsigned fNumStreamStates;
00172 struct streamState {
00173 ServerMediaSubsession* subsession;
00174 void* streamToken;
00175 } * fStreamStates;
00176 };
00177
00178 private:
00179 friend class RTSPClientSession;
00180 int fServerSocket;
00181 Port fServerPort;
00182 UserAuthenticationDatabase* fAuthDB;
00183 unsigned fReclamationTestSeconds;
00184 HashTable* fServerMediaSessions;
00185 unsigned fSessionIdCounter;
00186 };
00187
00188 #endif