1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166
|
/**********
This library is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2.1 of the License, or (at your
option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
This library is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
more details.
You should have received a copy of the GNU Lesser General Public License
along with this library; if not, write to the Free Software Foundation, Inc.,
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
**********/
// "liveMedia"
// Copyright (c) 1996-2004 Live Networks, Inc. All rights reserved.
// A RTSP server
// C++ header
#ifndef _RTSP_SERVER_HH
#define _RTSP_SERVER_HH
#ifndef _SERVER_MEDIA_SESSION_HH
#include "ServerMediaSession.hh"
#endif
#ifndef _NET_ADDRESS_HH
#include <NetAddress.hh>
#endif
#ifndef _DIGEST_AUTHENTICATION_HH
#include "DigestAuthentication.hh"
#endif
// A data structure used for optional user/password authentication:
class UserAuthenticationDatabase {
public:
UserAuthenticationDatabase(char const* realm = NULL,
Boolean passwordsAreMD5 = False);
// If "passwordsAreMD5" is True, then each password stored into, or removed from,
// the database is actually the value computed
// by md5(<username>:<realm>:<actual-password>)
virtual ~UserAuthenticationDatabase();
virtual void addUserRecord(char const* username, char const* password);
virtual void removeUserRecord(char const* username);
virtual char const* lookupPassword(char const* username);
// returns NULL if the user name was not present
char const* realm() { return fRealm; }
Boolean passwordsAreMD5() { return fPasswordsAreMD5; }
protected:
HashTable* fTable;
char* fRealm;
Boolean fPasswordsAreMD5;
};
class RTSPServer: public Medium {
public:
static RTSPServer* createNew(UsageEnvironment& env, Port ourPort = 554,
UserAuthenticationDatabase* authDatabase = NULL);
// if ourPort.num() == 0, we'll choose the port number
// Note: The caller is responsible for reclaiming "authDatabase"
static Boolean lookupByName(UsageEnvironment& env, char const* name,
RTSPServer*& resultServer);
void addServerMediaSession(ServerMediaSession* serverMediaSession);
void removeServerMediaSession(ServerMediaSession* serverMediaSession);
void removeServerMediaSession(char const* streamName);
char* rtspURL(ServerMediaSession const* serverMediaSession) const;
// returns a "rtsp://" URL that could be used to access the
// specified session (which must already have been added to
// us using "addServerMediaSession()".
// This string is dynamically allocated; caller should delete[]
protected:
RTSPServer(UsageEnvironment& env,
int ourSocket, Port ourPort,
UserAuthenticationDatabase* authDatabase);
// called only by createNew();
virtual ~RTSPServer();
static int setUpOurSocket(UsageEnvironment& env, Port& ourPort);
private: // redefined virtual functions
virtual Boolean isRTSPServer() const;
private:
static void incomingConnectionHandler(void*, int /*mask*/);
void incomingConnectionHandler1();
// The state of each individual session handled by a RTSP server:
class RTSPClientSession {
public:
RTSPClientSession(RTSPServer& ourServer, unsigned sessionId,
int clientSocket, struct sockaddr_in clientAddr);
virtual ~RTSPClientSession();
private:
UsageEnvironment& envir() { return fOurServer.envir(); }
void reclaimStreamStates();
static void incomingRequestHandler(void*, int /*mask*/);
void incomingRequestHandler1();
void handleCmd_bad(char const* cseq);
void handleCmd_notSupported(char const* cseq);
void handleCmd_notFound(char const* cseq);
void handleCmd_unsupportedTransport(char const* cseq);
void handleCmd_OPTIONS(char const* cseq);
void handleCmd_DESCRIBE(char const* cseq, char const* urlSuffix,
char const* fullRequestStr);
void handleCmd_SETUP(char const* cseq,
char const* urlPreSuffix, char const* urlSuffix,
char const* fullRequestStr);
void handleCmd_withinSession(char const* cmdName,
char const* urlPreSuffix, char const* urlSuffix,
char const* cseq, char const* fullRequestStr);
void handleCmd_TEARDOWN(ServerMediaSubsession* subsession,
char const* cseq);
void handleCmd_PLAY(ServerMediaSubsession* subsession,
char const* cseq, char const* fullRequestStr);
void handleCmd_PAUSE(ServerMediaSubsession* subsession,
char const* cseq);
void handleCmd_GET_PARAMETER(ServerMediaSubsession* subsession,
char const* cseq, char const* fullRequestStr);
Boolean authenticationOK(char const* cmdName, char const* cseq,
char const* fullRequestStr);
Boolean parseRequestString(char const *reqStr, unsigned reqStrSize,
char *resultCmdName,
unsigned resultCmdNameMaxSize,
char* resultURLPreSuffix,
unsigned resultURLPreSuffixMaxSize,
char* resultURLSuffix,
unsigned resultURLSuffixMaxSize,
char* resultCSeq,
unsigned resultCSeqMaxSize);
private:
RTSPServer& fOurServer;
unsigned fOurSessionId;
ServerMediaSession* fOurServerMediaSession;
int fClientSocket;
struct sockaddr_in fClientAddr;
unsigned char fBuffer[10000];
Boolean fSessionIsActive, fStreamAfterSETUP;
Authenticator fCurrentAuthenticator; // used if access control is needed
unsigned char fTCPStreamIdCount; // used for (optional) RTP/TCP
unsigned fNumStreamStates;
struct streamState {
ServerMediaSubsession* subsession;
void* streamToken;
} * fStreamStates;
};
private:
friend class RTSPClientSession;
int fServerSocket;
Port fServerPort;
UserAuthenticationDatabase* fAuthDB;
HashTable* fServerMediaSessions;
unsigned fSessionIdCounter;
};
#endif
|