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 unsigned sendPauseCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00101
00102
00103 unsigned sendPauseCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00104
00105
00106
00107 unsigned sendRecordCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00108
00109
00110 unsigned sendRecordCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00111
00112
00113
00114 unsigned sendTeardownCommand(MediaSession& session, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00115
00116
00117 unsigned sendTeardownCommand(MediaSubsession& subsession, responseHandler* responseHandler, Authenticator* authenticator = NULL);
00118
00119
00120
00121 unsigned sendSetParameterCommand(MediaSession& session, responseHandler* responseHandler,
00122 char const* parameterName, char const* parameterValue,
00123 Authenticator* authenticator = NULL);
00124
00125
00126
00127 unsigned sendGetParameterCommand(MediaSession& session, responseHandler* responseHandler, char const* parameterName,
00128 Authenticator* authenticator = NULL);
00129
00130
00131
00132 Boolean changeResponseHandler(unsigned cseq, responseHandler* newResponseHandler);
00133
00134
00135
00136
00137
00138 int socketNum() const { return fInputSocketNum; }
00139
00140 static Boolean lookupByName(UsageEnvironment& env,
00141 char const* sourceName,
00142 RTSPClient*& resultClient);
00143
00144 static Boolean parseRTSPURL(UsageEnvironment& env, char const* url,
00145 char*& username, char*& password, NetAddress& address, portNumBits& portNum, char const** urlSuffix = NULL);
00146
00147
00148
00149 void setUserAgentString(char const* userAgentName);
00150
00151
00152 unsigned sessionTimeoutParameter() const { return fSessionTimeoutParameter; }
00153
00154 char const* url() const { return fBaseURL; }
00155
00156 static unsigned responseBufferSize;
00157
00158 protected:
00159 RTSPClient(UsageEnvironment& env, char const* rtspURL,
00160 int verbosityLevel, char const* applicationName, portNumBits tunnelOverHTTPPortNum);
00161
00162 virtual ~RTSPClient();
00163
00164 void setBaseURL(char const* url);
00165
00166 private:
00167 virtual Boolean isRTSPClient() const;
00168
00169 public:
00170
00171 class RequestRecord {
00172 public:
00173 RequestRecord(unsigned cseq, char const* commandName, responseHandler* handler,
00174 MediaSession* session = NULL, MediaSubsession* subsession = NULL, u_int32_t booleanFlags = 0,
00175 double start = 0.0f, double end = -1.0f, float scale = 1.0f, char const* contentStr = NULL);
00176 virtual ~RequestRecord();
00177
00178 RequestRecord*& next() { return fNext; }
00179 unsigned& cseq() { return fCSeq; }
00180 char const* commandName() const { return fCommandName; }
00181 MediaSession* session() const { return fSession; }
00182 MediaSubsession* subsession() const { return fSubsession; }
00183 u_int32_t booleanFlags() const { return fBooleanFlags; }
00184 double start() const { return fStart; }
00185 double end() const { return fEnd; }
00186 float scale() const { return fScale; }
00187 char* contentStr() const { return fContentStr; }
00188 responseHandler*& handler() { return fHandler; }
00189
00190 private:
00191 RequestRecord* fNext;
00192 unsigned fCSeq;
00193 char const* fCommandName;
00194 MediaSession* fSession;
00195 MediaSubsession* fSubsession;
00196 u_int32_t fBooleanFlags;
00197 double fStart, fEnd;
00198 float fScale;
00199 char* fContentStr;
00200 responseHandler* fHandler;
00201 };
00202 private:
00203 class RequestQueue {
00204 public:
00205 RequestQueue();
00206 RequestQueue(RequestQueue& origQueue);
00207 virtual ~RequestQueue();
00208
00209 void enqueue(RequestRecord* request);
00210 RequestRecord* dequeue();
00211 void putAtHead(RequestRecord* request);
00212 RequestRecord* findByCSeq(unsigned cseq);
00213 Boolean isEmpty() const { return fHead == NULL; }
00214
00215 private:
00216 RequestRecord* fHead;
00217 RequestRecord* fTail;
00218 };
00219
00220 void reset();
00221 void resetTCPSockets();
00222 void resetResponseBuffer();
00223 int openConnection();
00224 int connectToServer(int socketNum, portNumBits remotePortNum);
00225 char* createAuthenticatorString(char const* cmd, char const* url);
00226 unsigned sendRequest(RequestRecord* request);
00227 void handleRequestError(RequestRecord* request);
00228 Boolean parseResponseCode(char const* line, unsigned& responseCode, char const*& responseString);
00229 void handleIncomingRequest();
00230 static Boolean checkForHeader(char const* line, char const* headerName, unsigned headerNameLength, char const*& headerParams);
00231 Boolean parseTransportParams(char const* paramsStr,
00232 char*& serverAddressStr, portNumBits& serverPortNum,
00233 unsigned char& rtpChannelId, unsigned char& rtcpChannelId);
00234 Boolean parseScaleParam(char const* paramStr, float& scale);
00235 Boolean parseRTPInfoParams(char const*& paramStr, u_int16_t& seqNum, u_int32_t& timestamp);
00236 Boolean handleSETUPResponse(MediaSubsession& subsession, char const* sessionParamsStr, char const* transportParamsStr,
00237 Boolean streamUsingTCP);
00238 Boolean handlePLAYResponse(MediaSession& session, MediaSubsession& subsession,
00239 char const* scaleParamsStr, char const* rangeParamsStr, char const* rtpInfoParamsStr);
00240 Boolean handleTEARDOWNResponse(MediaSession& session, MediaSubsession& subsession);
00241 Boolean handleGET_PARAMETERResponse(char const* parameterName, char*& resultValueString);
00242 Boolean handleAuthenticationFailure(char const* wwwAuthenticateParamsStr);
00243 Boolean resendCommand(RequestRecord* request);
00244 char const* sessionURL(MediaSession const& session) const;
00245 static void handleAlternativeRequestByte(void*, u_int8_t requestByte);
00246 void handleAlternativeRequestByte1(u_int8_t requestByte);
00247 void constructSubsessionURL(MediaSubsession const& subsession,
00248 char const*& prefix,
00249 char const*& separator,
00250 char const*& suffix);
00251
00252
00253 Boolean setupHTTPTunneling1();
00254 static void responseHandlerForHTTP_GET(RTSPClient* rtspClient, int responseCode, char* responseString);
00255 void responseHandlerForHTTP_GET1(int responseCode, char* responseString);
00256 Boolean setupHTTPTunneling2();
00257
00258
00259 static void connectionHandler(void*, int );
00260 void connectionHandler1();
00261
00262
00263 static void incomingDataHandler(void*, int );
00264 void incomingDataHandler1();
00265 void handleResponseBytes(int newBytesRead);
00266
00267 protected:
00268 int fVerbosityLevel;
00269
00270 private:
00271 portNumBits fTunnelOverHTTPPortNum;
00272 char* fUserAgentHeaderStr;
00273 unsigned fUserAgentHeaderStrLen;
00274 int fInputSocketNum, fOutputSocketNum;
00275 netAddressBits fServerAddress;
00276 unsigned fCSeq;
00277 char* fBaseURL;
00278 Authenticator fCurrentAuthenticator;
00279 unsigned char fTCPStreamIdCount;
00280 char* fLastSessionId;
00281 unsigned fSessionTimeoutParameter;
00282 char* fResponseBuffer;
00283 unsigned fResponseBytesAlreadySeen, fResponseBufferBytesLeft;
00284 RequestQueue fRequestsAwaitingConnection, fRequestsAwaitingHTTPTunneling, fRequestsAwaitingResponse;
00285
00286
00287 char fSessionCookie[33];
00288 unsigned fSessionCookieCounter;
00289 Boolean fHTTPTunnelingConnectionIsPending;
00290
00291 #ifdef RTSPCLIENT_SYNCHRONOUS_INTERFACE
00292
00293
00294 public:
00295 static RTSPClient* createNew(UsageEnvironment& env,
00296 int verbosityLevel = 0,
00297 char const* applicationName = NULL,
00298 portNumBits tunnelOverHTTPPortNum = 0);
00299 char* describeURL(char const* url, Authenticator* authenticator = NULL,
00300 Boolean allowKasennaProtocol = False, int timeout = -1);
00301 char* describeWithPassword(char const* url,
00302 char const* username, char const* password,
00303 Boolean allowKasennaProtocol = False,
00304 int timeout = -1);
00305 char* sendOptionsCmd(char const* url,
00306 char* username = NULL, char* password = NULL,
00307 Authenticator* authenticator = NULL,
00308 int timeout = -1);
00309 Boolean announceSDPDescription(char const* url,
00310 char const* sdpDescription,
00311 Authenticator* authenticator = NULL,
00312 int timeout = -1);
00313 Boolean announceWithPassword(char const* url, char const* sdpDescription,
00314 char const* username, char const* password, int timeout = -1);
00315 Boolean setupMediaSubsession(MediaSubsession& subsession,
00316 Boolean streamOutgoing = False,
00317 Boolean streamUsingTCP = False,
00318 Boolean forceMulticastOnUnspecified = False);
00319 Boolean playMediaSession(MediaSession& session,
00320 double start = 0.0f, double end = -1.0f,
00321 float scale = 1.0f);
00322 Boolean playMediaSubsession(MediaSubsession& subsession,
00323 double start = 0.0f, double end = -1.0f,
00324 float scale = 1.0f,
00325 Boolean hackForDSS = False);
00326 Boolean pauseMediaSession(MediaSession& session);
00327 Boolean pauseMediaSubsession(MediaSubsession& subsession);
00328 Boolean recordMediaSubsession(MediaSubsession& subsession);
00329 Boolean setMediaSessionParameter(MediaSession& session,
00330 char const* parameterName,
00331 char const* parameterValue);
00332 Boolean getMediaSessionParameter(MediaSession& session,
00333 char const* parameterName,
00334 char*& parameterValue);
00335 Boolean teardownMediaSession(MediaSession& session);
00336 Boolean teardownMediaSubsession(MediaSubsession& subsession);
00337
00338 static Boolean parseRTSPURLUsernamePassword(char const* url,
00339 char*& username, char*& password);
00340 private:
00341 static void responseHandlerForSyncInterface(RTSPClient* rtspClient,
00342 int responseCode, char* responseString);
00343 void responseHandlerForSyncInterface1(int responseCode, char* responseString);
00344 static void timeoutHandlerForSyncInterface(void* rtspClient);
00345 void timeoutHandlerForSyncInterface1();
00346 TaskToken fTimeoutTask;
00347 char fWatchVariableForSyncInterface;
00348 char* fResultString;
00349 int fResultCode;
00350 #endif
00351 };
00352
00353 #endif