00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef _RTSP_CLIENT_HH
00022 #define _RTSP_CLIENT_HH
00023
00024 #ifndef _MEDIA_SESSION_HH
00025 #include "MediaSession.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 class RTSPClient: public Medium {
00035 public:
00036 static RTSPClient* createNew(UsageEnvironment& env, char const* rtspURL,
00037 int verbosityLevel = 0,
00038 char const* applicationName = NULL,
00039 portNumBits tunnelOverHTTPPortNum = 0);
00040
00041
00042
00043
00044 typedef void (responseHandler)(RTSPClient* rtspClient,
00045 int resultCode, char* resultString);
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 unsigned sendDescribeCommand(responseHandler* responseHandler, Authenticator* authenticator = NULL);
00063
00064
00065
00066
00067
00068
00069
00070 unsigned sendOptionsCommand(responseHandler* responseHandler, Authenticator* authenticator = NULL);
00071
00072
00073
00074 unsigned sendAnnounceCommand(char const* sdpDescription, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00075
00076
00077
00078
00079 unsigned sendSetupCommand(MediaSubsession& subsession, responseHandler* responseHandler,
00080 Boolean streamOutgoing = False,
00081 Boolean streamUsingTCP = False,
00082 Boolean forceMulticastOnUnspecified = False,
00083 Authenticator* authenticator = NULL);
00084
00085
00086
00087 unsigned sendPlayCommand(MediaSession& session, responseHandler* responseHandler,
00088 double start = 0.0f, double end = -1.0f, float scale = 1.0f,
00089 Authenticator* authenticator = NULL);
00090
00091
00092
00093 unsigned sendPlayCommand(MediaSubsession& subsession, responseHandler* responseHandler,
00094 double start = 0.0f, double end = -1.0f, float scale = 1.0f,
00095 Authenticator* authenticator = NULL);
00096
00097
00098
00099
00100
00101
00102
00103 unsigned sendPlayCommand(MediaSession& session, responseHandler* responseHandler,
00104 char const* absStartTime, char const* absEndTime = NULL, float scale = 1.0f,
00105 Authenticator* authenticator = NULL);
00106 unsigned sendPlayCommand(MediaSubsession& subsession, responseHandler* responseHandler,
00107 char const* absStartTime, char const* absEndTime = NULL, float scale = 1.0f,
00108 Authenticator* authenticator = NULL);
00109
00110 unsigned sendPauseCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00111
00112
00113 unsigned sendPauseCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00114
00115
00116
00117 unsigned sendRecordCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00118
00119
00120 unsigned sendRecordCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00121
00122
00123
00124 unsigned sendTeardownCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00125
00126
00127 unsigned sendTeardownCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00128
00129
00130
00131 unsigned sendSetParameterCommand(MediaSession& session, responseHandler* responseHandler,
00132 char const* parameterName, char const* parameterValue,
00133 Authenticator* authenticator = NULL);
00134
00135
00136
00137 unsigned sendGetParameterCommand(MediaSession& session, responseHandler* responseHandler, char const* parameterName,
00138 Authenticator* authenticator = NULL);
00139
00140
00141
00142 Boolean changeResponseHandler(unsigned cseq, responseHandler* newResponseHandler);
00143
00144
00145
00146
00147
00148 int socketNum() const { return fInputSocketNum; }
00149
00150 static Boolean lookupByName(UsageEnvironment& env,
00151 char const* sourceName,
00152 RTSPClient*& resultClient);
00153
00154 static Boolean parseRTSPURL(UsageEnvironment& env, char const* url,
00155 char*& username, char*& password, NetAddress& address, portNumBits& portNum, char const** urlSuffix = NULL);
00156
00157
00158
00159 void setUserAgentString(char const* userAgentName);
00160
00161
00162 unsigned sessionTimeoutParameter() const { return fSessionTimeoutParameter; }
00163
00164 char const* url() const { return fBaseURL; }
00165
00166 static unsigned responseBufferSize;
00167
00168 public:
00169
00170 class RequestRecord {
00171 public:
00172 RequestRecord(unsigned cseq, char const* commandName, responseHandler* handler,
00173 MediaSession* session = NULL, MediaSubsession* subsession = NULL, u_int32_t booleanFlags = 0,
00174 double start = 0.0f, double end = -1.0f, float scale = 1.0f, char const* contentStr = NULL);
00175 RequestRecord(unsigned cseq, responseHandler* handler,
00176 char const* absStartTime, char const* absEndTime = NULL, float scale = 1.0f,
00177 MediaSession* session = NULL, MediaSubsession* subsession = NULL);
00178
00179 virtual ~RequestRecord();
00180
00181 RequestRecord*& next() { return fNext; }
00182 unsigned& cseq() { return fCSeq; }
00183 char const* commandName() const { return fCommandName; }
00184 MediaSession* session() const { return fSession; }
00185 MediaSubsession* subsession() const { return fSubsession; }
00186 u_int32_t booleanFlags() const { return fBooleanFlags; }
00187 double start() const { return fStart; }
00188 double end() const { return fEnd; }
00189 char const* absStartTime() const { return fAbsStartTime; }
00190 char const* absEndTime() const { return fAbsEndTime; }
00191 float scale() const { return fScale; }
00192 char* contentStr() const { return fContentStr; }
00193 responseHandler*& handler() { return fHandler; }
00194
00195 private:
00196 RequestRecord* fNext;
00197 unsigned fCSeq;
00198 char const* fCommandName;
00199 MediaSession* fSession;
00200 MediaSubsession* fSubsession;
00201 u_int32_t fBooleanFlags;
00202 double fStart, fEnd;
00203 char *fAbsStartTime, *fAbsEndTime;
00204 float fScale;
00205 char* fContentStr;
00206 responseHandler* fHandler;
00207 };
00208
00209 protected:
00210 RTSPClient(UsageEnvironment& env, char const* rtspURL,
00211 int verbosityLevel, char const* applicationName, portNumBits tunnelOverHTTPPortNum);
00212
00213 virtual ~RTSPClient();
00214
00215 void reset();
00216 void setBaseURL(char const* url);
00217 virtual unsigned sendRequest(RequestRecord* request);
00218
00219 private:
00220 virtual Boolean isRTSPClient() const;
00221
00222 private:
00223 class RequestQueue {
00224 public:
00225 RequestQueue();
00226 RequestQueue(RequestQueue& origQueue);
00227 virtual ~RequestQueue();
00228
00229 void enqueue(RequestRecord* request);
00230 RequestRecord* dequeue();
00231 void putAtHead(RequestRecord* request);
00232 RequestRecord* findByCSeq(unsigned cseq);
00233 Boolean isEmpty() const { return fHead == NULL; }
00234
00235 private:
00236 RequestRecord* fHead;
00237 RequestRecord* fTail;
00238 };
00239
00240 void resetTCPSockets();
00241 void resetResponseBuffer();
00242 int openConnection();
00243 int connectToServer(int socketNum, portNumBits remotePortNum);
00244 char* createAuthenticatorString(char const* cmd, char const* url);
00245 void handleRequestError(RequestRecord* request);
00246 Boolean parseResponseCode(char const* line, unsigned& responseCode, char const*& responseString);
00247 void handleIncomingRequest();
00248 static Boolean checkForHeader(char const* line, char const* headerName, unsigned headerNameLength, char const*& headerParams);
00249 Boolean parseTransportParams(char const* paramsStr,
00250 char*& serverAddressStr, portNumBits& serverPortNum,
00251 unsigned char& rtpChannelId, unsigned char& rtcpChannelId);
00252 Boolean parseScaleParam(char const* paramStr, float& scale);
00253 Boolean parseRTPInfoParams(char const*& paramStr, u_int16_t& seqNum, u_int32_t& timestamp);
00254 Boolean handleSETUPResponse(MediaSubsession& subsession, char const* sessionParamsStr, char const* transportParamsStr,
00255 Boolean streamUsingTCP);
00256 Boolean handlePLAYResponse(MediaSession& session, MediaSubsession& subsession,
00257 char const* scaleParamsStr, char const* rangeParamsStr, char const* rtpInfoParamsStr);
00258 Boolean handleTEARDOWNResponse(MediaSession& session, MediaSubsession& subsession);
00259 Boolean handleGET_PARAMETERResponse(char const* parameterName, char*& resultValueString);
00260 Boolean handleAuthenticationFailure(char const* wwwAuthenticateParamsStr);
00261 Boolean resendCommand(RequestRecord* request);
00262 char const* sessionURL(MediaSession const& session) const;
00263 static void handleAlternativeRequestByte(void*, u_int8_t requestByte);
00264 void handleAlternativeRequestByte1(u_int8_t requestByte);
00265 void constructSubsessionURL(MediaSubsession const& subsession,
00266 char const*& prefix,
00267 char const*& separator,
00268 char const*& suffix);
00269
00270
00271 Boolean setupHTTPTunneling1();
00272 static void responseHandlerForHTTP_GET(RTSPClient* rtspClient, int responseCode, char* responseString);
00273 void responseHandlerForHTTP_GET1(int responseCode, char* responseString);
00274 Boolean setupHTTPTunneling2();
00275
00276
00277 static void connectionHandler(void*, int );
00278 void connectionHandler1();
00279
00280
00281 static void incomingDataHandler(void*, int );
00282 void incomingDataHandler1();
00283 void handleResponseBytes(int newBytesRead);
00284
00285 protected:
00286 int fVerbosityLevel;
00287 unsigned fCSeq;
00288 Authenticator fCurrentAuthenticator;
00289
00290 private:
00291 portNumBits fTunnelOverHTTPPortNum;
00292 char* fUserAgentHeaderStr;
00293 unsigned fUserAgentHeaderStrLen;
00294 int fInputSocketNum, fOutputSocketNum;
00295 netAddressBits fServerAddress;
00296 char* fBaseURL;
00297 unsigned char fTCPStreamIdCount;
00298 char* fLastSessionId;
00299 unsigned fSessionTimeoutParameter;
00300 char* fResponseBuffer;
00301 unsigned fResponseBytesAlreadySeen, fResponseBufferBytesLeft;
00302 RequestQueue fRequestsAwaitingConnection, fRequestsAwaitingHTTPTunneling, fRequestsAwaitingResponse;
00303
00304
00305 char fSessionCookie[33];
00306 unsigned fSessionCookieCounter;
00307 Boolean fHTTPTunnelingConnectionIsPending;
00308
00309 #ifdef RTSPCLIENT_SYNCHRONOUS_INTERFACE
00310
00311
00312 public:
00313 static RTSPClient* createNew(UsageEnvironment& env,
00314 int verbosityLevel = 0,
00315 char const* applicationName = NULL,
00316 portNumBits tunnelOverHTTPPortNum = 0);
00317 char* describeURL(char const* url, Authenticator* authenticator = NULL,
00318 Boolean allowKasennaProtocol = False, int timeout = -1);
00319 char* describeWithPassword(char const* url,
00320 char const* username, char const* password,
00321 Boolean allowKasennaProtocol = False,
00322 int timeout = -1);
00323 char* sendOptionsCmd(char const* url,
00324 char* username = NULL, char* password = NULL,
00325 Authenticator* authenticator = NULL,
00326 int timeout = -1);
00327 Boolean announceSDPDescription(char const* url,
00328 char const* sdpDescription,
00329 Authenticator* authenticator = NULL,
00330 int timeout = -1);
00331 Boolean announceWithPassword(char const* url, char const* sdpDescription,
00332 char const* username, char const* password, int timeout = -1);
00333 Boolean setupMediaSubsession(MediaSubsession& subsession,
00334 Boolean streamOutgoing = False,
00335 Boolean streamUsingTCP = False,
00336 Boolean forceMulticastOnUnspecified = False);
00337 Boolean playMediaSession(MediaSession& session,
00338 double start = 0.0f, double end = -1.0f,
00339 float scale = 1.0f);
00340 Boolean playMediaSubsession(MediaSubsession& subsession,
00341 double start = 0.0f, double end = -1.0f,
00342 float scale = 1.0f,
00343 Boolean hackForDSS = False);
00344 Boolean pauseMediaSession(MediaSession& session);
00345 Boolean pauseMediaSubsession(MediaSubsession& subsession);
00346 Boolean recordMediaSubsession(MediaSubsession& subsession);
00347 Boolean setMediaSessionParameter(MediaSession& session,
00348 char const* parameterName,
00349 char const* parameterValue);
00350 Boolean getMediaSessionParameter(MediaSession& session,
00351 char const* parameterName,
00352 char*& parameterValue);
00353 Boolean teardownMediaSession(MediaSession& session);
00354 Boolean teardownMediaSubsession(MediaSubsession& subsession);
00355
00356 static Boolean parseRTSPURLUsernamePassword(char const* url,
00357 char*& username, char*& password);
00358 private:
00359 static void responseHandlerForSyncInterface(RTSPClient* rtspClient,
00360 int responseCode, char* responseString);
00361 void responseHandlerForSyncInterface1(int responseCode, char* responseString);
00362 static void timeoutHandlerForSyncInterface(void* rtspClient);
00363 void timeoutHandlerForSyncInterface1();
00364 TaskToken fTimeoutTask;
00365 char fWatchVariableForSyncInterface;
00366 char* fResultString;
00367 int fResultCode;
00368 #endif
00369 };
00370
00371 #endif