blob: e220f2c20844a454f7ce6d6d4e1d80e67dac87f4 [file] [log] [blame]
/**********
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 3 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.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
**********/
// "liveMedia"
// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
// A generic SIP client
// C++ header
#ifndef _SIP_CLIENT_HH
#define _SIP_CLIENT_HH
#ifndef _MEDIA_SESSION_HH
#include "MediaSession.hh"
#endif
#ifndef _NET_ADDRESS_HH
#include "NetAddress.hh"
#endif
#ifndef _DIGEST_AUTHENTICATION_HH
#include "DigestAuthentication.hh"
#endif
// Possible states in the "INVITE" transition diagram (RFC 3261, Figure 5)
enum inviteClientState { Calling, Proceeding, Completed, Terminated };
class SIPClient: public Medium {
public:
static SIPClient* createNew(UsageEnvironment& env,
unsigned char desiredAudioRTPPayloadFormat,
char const* mimeSubtype = NULL,
int verbosityLevel = 0,
char const* applicationName = NULL);
void setProxyServer(unsigned proxyServerAddress,
portNumBits proxyServerPortNum);
void setClientStartPortNum(portNumBits clientStartPortNum) {
fClientStartPortNum = clientStartPortNum;
}
char* invite(char const* url, Authenticator* authenticator = NULL);
// Issues a SIP "INVITE" command
// Returns the session SDP description if this command succeeds
char* inviteWithPassword(char const* url,
char const* username, char const* password);
// Uses "invite()" to do an "INVITE" - first
// without using "password", then (if we get an Unauthorized
// response) with an authentication response computed from "password"
Boolean sendACK(); // on current call
Boolean sendBYE(); // on current call
static Boolean parseSIPURL(UsageEnvironment& env, char const* url,
NetAddress& address, portNumBits& portNum);
// (ignores any "<username>[:<password>]@" in "url")
static Boolean parseSIPURLUsernamePassword(char const* url,
char*& username,
char*& password);
char const* getInviteSdpReply() const { return fInviteSDPDescriptionReturned; }
void setUserAgentString(char const* userAgentName);
// sets an alternative string to be used in SIP "User-Agent:" headers
protected:
virtual ~SIPClient();
private:
SIPClient(UsageEnvironment& env,
unsigned char desiredAudioRTPPayloadFormat,
char const* mimeSubtype,
int verbosityLevel,
char const* applicationName);
// called only by createNew();
void reset();
// Routines used to implement invite*():
char* invite1(Authenticator* authenticator);
Boolean processURL(char const* url);
Boolean sendINVITE();
static void inviteResponseHandler(void* clientData, int mask);
void doInviteStateMachine(unsigned responseCode);
void doInviteStateTerminated(unsigned responseCode);
TaskToken fTimerA, fTimerB, fTimerD;
static void timerAHandler(void* clientData);
static void timerBHandler(void* clientData);
static void timerDHandler(void* clientData);
unsigned const fT1; // in microseconds
unsigned fTimerALen; // in microseconds; initially fT1, then doubles
unsigned fTimerACount;
// Routines used to implement all commands:
char* createAuthenticatorString(Authenticator const* authenticator,
char const* cmd, char const* url);
Boolean sendRequest(char const* requestString, unsigned requestLength);
unsigned getResponseCode();
unsigned getResponse(char*& responseBuffer, unsigned responseBufferSize);
Boolean parseResponseCode(char const* line, unsigned& responseCode);
private:
// Set for all calls:
unsigned char fDesiredAudioRTPPayloadFormat;
char* fMIMESubtype;
unsigned fMIMESubtypeSize;
int fVerbosityLevel;
unsigned fCSeq; // sequence number, used in consecutive requests
char const* fApplicationName;
unsigned fApplicationNameSize;
char const* fOurAddressStr;
unsigned fOurAddressStrSize;
portNumBits fOurPortNum;
Groupsock* fOurSocket;
char* fUserAgentHeaderStr;
unsigned fUserAgentHeaderStrLen;
// Set for each call:
char const* fURL;
unsigned fURLSize;
struct in_addr fServerAddress;
portNumBits fServerPortNum; // in host order
portNumBits fClientStartPortNum; // in host order
unsigned fCallId, fFromTag; // set by us
char const* fToTagStr; // set by the responder
unsigned fToTagStrSize;
Authenticator fValidAuthenticator;
char const* fUserName; // 'user' name used in "From:" & "Contact:" lines
unsigned fUserNameSize;
char* fInviteSDPDescription;
char* fInviteSDPDescriptionReturned;
char* fInviteCmd;
unsigned fInviteCmdSize;
Authenticator* fWorkingAuthenticator;
inviteClientState fInviteClientState;
char fEventLoopStopFlag;
};
#endif