1/**********
2This library is free software; you can redistribute it and/or modify it under
3the terms of the GNU Lesser General Public License as published by the
4Free Software Foundation; either version 3 of the License, or (at your
5option) any later version. (See <http://www.gnu.org/copyleft/lesser.html>.)
6
7This library is distributed in the hope that it will be useful, but WITHOUT
8ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
9FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
10more details.
11
12You should have received a copy of the GNU Lesser General Public License
13along with this library; if not, write to the Free Software Foundation, Inc.,
1451 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
15**********/
16// "liveMedia"
17// Copyright (c) 1996-2020 Live Networks, Inc. All rights reserved.
18// A generic SIP client
19// C++ header
20
21#ifndef _SIP_CLIENT_HH
22#define _SIP_CLIENT_HH
23
24#ifndef _MEDIA_SESSION_HH
25#include "MediaSession.hh"
26#endif
27#ifndef _NET_ADDRESS_HH
28#include "NetAddress.hh"
29#endif
30#ifndef _DIGEST_AUTHENTICATION_HH
31#include "DigestAuthentication.hh"
32#endif
33
34// Possible states in the "INVITE" transition diagram (RFC 3261, Figure 5)
35enum inviteClientState { Calling, Proceeding, Completed, Terminated };
36
37class SIPClient: public Medium {
38public:
39 static SIPClient* createNew(UsageEnvironment& env,
40 unsigned char desiredAudioRTPPayloadFormat,
41 char const* mimeSubtype = NULL,
42 int verbosityLevel = 0,
43 char const* applicationName = NULL);
44
45 void setProxyServer(unsigned proxyServerAddress,
46 portNumBits proxyServerPortNum);
47
48 void setClientStartPortNum(portNumBits clientStartPortNum) {
49 fClientStartPortNum = clientStartPortNum;
50 }
51
52 char* invite(char const* url, Authenticator* authenticator = NULL);
53 // Issues a SIP "INVITE" command
54 // Returns the session SDP description if this command succeeds
55 char* inviteWithPassword(char const* url,
56 char const* username, char const* password);
57 // Uses "invite()" to do an "INVITE" - first
58 // without using "password", then (if we get an Unauthorized
59 // response) with an authentication response computed from "password"
60
61 Boolean sendACK(); // on current call
62 Boolean sendBYE(); // on current call
63
64 static Boolean parseSIPURL(UsageEnvironment& env, char const* url,
65 NetAddress& address, portNumBits& portNum);
66 // (ignores any "<username>[:<password>]@" in "url")
67 static Boolean parseSIPURLUsernamePassword(char const* url,
68 char*& username,
69 char*& password);
70 char const* getInviteSdpReply() const { return fInviteSDPDescriptionReturned; }
71
72 void setUserAgentString(char const* userAgentName);
73 // sets an alternative string to be used in SIP "User-Agent:" headers
74
75protected:
76 virtual ~SIPClient();
77
78private:
79 SIPClient(UsageEnvironment& env,
80 unsigned char desiredAudioRTPPayloadFormat,
81 char const* mimeSubtype,
82 int verbosityLevel,
83 char const* applicationName);
84 // called only by createNew();
85
86 void reset();
87
88 // Routines used to implement invite*():
89 char* invite1(Authenticator* authenticator);
90 Boolean processURL(char const* url);
91 Boolean sendINVITE();
92 static void inviteResponseHandler(void* clientData, int mask);
93 void doInviteStateMachine(unsigned responseCode);
94 void doInviteStateTerminated(unsigned responseCode);
95 TaskToken fTimerA, fTimerB, fTimerD;
96 static void timerAHandler(void* clientData);
97 static void timerBHandler(void* clientData);
98 static void timerDHandler(void* clientData);
99 unsigned const fT1; // in microseconds
100 unsigned fTimerALen; // in microseconds; initially fT1, then doubles
101 unsigned fTimerACount;
102
103 // Routines used to implement all commands:
104 char* createAuthenticatorString(Authenticator const* authenticator,
105 char const* cmd, char const* url);
106 Boolean sendRequest(char const* requestString, unsigned requestLength);
107 unsigned getResponseCode();
108 unsigned getResponse(char*& responseBuffer, unsigned responseBufferSize);
109 Boolean parseResponseCode(char const* line, unsigned& responseCode);
110
111private:
112 // Set for all calls:
113 unsigned char fDesiredAudioRTPPayloadFormat;
114 char* fMIMESubtype;
115 unsigned fMIMESubtypeSize;
116 int fVerbosityLevel;
117 unsigned fCSeq; // sequence number, used in consecutive requests
118 char const* fApplicationName;
119 unsigned fApplicationNameSize;
120 char const* fOurAddressStr;
121 unsigned fOurAddressStrSize;
122 portNumBits fOurPortNum;
123 Groupsock* fOurSocket;
124 char* fUserAgentHeaderStr;
125 unsigned fUserAgentHeaderStrLen;
126
127 // Set for each call:
128 char const* fURL;
129 unsigned fURLSize;
130 struct in_addr fServerAddress;
131 portNumBits fServerPortNum; // in host order
132 portNumBits fClientStartPortNum; // in host order
133 unsigned fCallId, fFromTag; // set by us
134 char const* fToTagStr; // set by the responder
135 unsigned fToTagStrSize;
136 Authenticator fValidAuthenticator;
137 char const* fUserName; // 'user' name used in "From:" & "Contact:" lines
138 unsigned fUserNameSize;
139
140 char* fInviteSDPDescription;
141 char* fInviteSDPDescriptionReturned;
142 char* fInviteCmd;
143 unsigned fInviteCmdSize;
144 Authenticator* fWorkingAuthenticator;
145 inviteClientState fInviteClientState;
146 char fEventLoopStopFlag;
147};
148
149#endif
150