sal.h 14.3 KB
Newer Older
1
/*
2
 * sal.h
3
 * Copyright (C) 2010-2018 Belledonne Communications SARL
4
 *
Ghislain MARY's avatar
Ghislain MARY committed
5 6 7 8
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
9 10 11 12 13 14 15
 *
 * This program 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 General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
Ghislain MARY's avatar
Ghislain MARY committed
16 17
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18
 */
19

20 21
#ifndef _L_SAL_H_
#define _L_SAL_H_
22

23 24 25
#include <list>
#include <vector>

26 27
#include "linphone/utils/general.h"

28 29 30
#include "c-wrapper/internal/c-sal.h"
#include "logger/logger.h"

31 32 33 34 35 36 37
LINPHONE_BEGIN_NAMESPACE

class SalOp;
class SalCallOp;
class SalMessageOp;
class SalSubscribeOp;
class SalPresenceOp;
38
class SalReferOp;
39

40
class Sal {
41
public:
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
	using OnCallReceivedCb = void (*) (SalCallOp *op);
	using OnCallRingingCb = void (*) (SalOp *op);
	using OnCallAcceptedCb = void (*) (SalOp *op);
	using OnCallAckReceivedCb = void (*) (SalOp *op, SalCustomHeader *ack);
	using OnCallAckBeingSentCb = void (*) (SalOp *op, SalCustomHeader *ack);
	using OnCallUpdatingCb = void (*) (SalOp *op, bool_t isUpdate); // Called when a reINVITE/UPDATE is received
	using OnCallTerminatedCb = void (*) (SalOp *op, const char *from);
	using OnCallFailureCb = void (*) (SalOp *op);
	using OnCallReleasedCb = void (*) (SalOp *op);
	using OnCallCancelDoneCb = void (*) (SalOp *op);
	using OnAuthRequestedLegacyCb = void (*) (SalOp *op, const char *realm, const char *username);
	using OnAuthRequestedCb = bool_t (*) (Sal *sal, SalAuthInfo *info);
	using OnAuthFailureCb = void (*) (SalOp *op, SalAuthInfo *info);
	using OnRegisterSuccessCb = void (*) (SalOp *op, bool_t registered);
	using OnRegisterFailureCb = void (*) (SalOp *op);
	using OnVfuRequestCb = void (*) (SalOp *op);
	using OnDtmfReceivedCb = void (*) (SalOp *op, char dtmf);
	using OnCallReferCb = void (*) (SalOp *op, const SalAddress *referTo);
	using OnReferCb = void (*) (SalOp *op, const SalAddress *referTo);
	using OnMessageReceivedCb = void (*) (SalOp *op, const SalMessage *msg);
	using OnMessageDeliveryUpdateCb = void (*) (SalOp *op, SalMessageDeliveryStatus status);
	using OnNotifyReferCb = void (*) (SalOp *op, SalReferStatus status);
	using OnSubscribeResponseCb = void (*) (SalOp *op, SalSubscribeStatus status, int willRetry);
	using OnNotifyCb = void (*) (SalSubscribeOp *op, SalSubscribeStatus status, const char *event, SalBodyHandler *body);
	using OnSubscribeReceivedCb = void (*) (SalSubscribeOp *op, const char *event, const SalBodyHandler *body);
	using OnIncomingSubscribeClosedCb = void (*) (SalOp *op);
	using OnParsePresenceRequestedCb = void (*) (SalOp *op, const char *contentType, const char *contentSubtype, const char *content, SalPresenceModel **result);
	using OnConvertPresenceToXMLRequestedCb = void (*) (SalOp *op, SalPresenceModel *presence, const char *contact, char **content);
	using OnNotifyPresenceCb = void (*) (SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg);
	using OnSubscribePresenceReceivedCb = void (*) (SalPresenceOp *op, const char *from);
	using OnSubscribePresenceClosedCb = void (*) (SalPresenceOp *op, const char *from);
	using OnPingReplyCb = void (*) (SalOp *op);
	using OnInfoReceivedCb = void (*) (SalOp *op, SalBodyHandler *body);
	using OnPublishResponseCb = void (*) (SalOp *op);
	using OnNotifyResponseCb = void (*) (SalOp *op);
	using OnExpireCb = void (*) (SalOp *op);
78

79 80 81 82 83 84 85 86 87 88 89 90
	struct Callbacks {
		OnCallReceivedCb call_received;
		OnCallReceivedCb call_rejected;
		OnCallRingingCb call_ringing;
		OnCallAcceptedCb call_accepted;
		OnCallAckReceivedCb call_ack_received;
		OnCallAckBeingSentCb call_ack_being_sent;
		OnCallUpdatingCb call_updating;
		OnCallTerminatedCb call_terminated;
		OnCallFailureCb call_failure;
		OnCallReleasedCb call_released;
		OnCallCancelDoneCb call_cancel_done;
91
		OnCallReferCb call_refer_received;
92 93 94 95 96
		OnAuthFailureCb auth_failure;
		OnRegisterSuccessCb register_success;
		OnRegisterFailureCb register_failure;
		OnVfuRequestCb vfu_request;
		OnDtmfReceivedCb dtmf_received;
97

98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115
		OnMessageReceivedCb message_received;
		OnMessageDeliveryUpdateCb message_delivery_update;
		OnNotifyReferCb notify_refer;
		OnSubscribeReceivedCb subscribe_received;
		OnIncomingSubscribeClosedCb incoming_subscribe_closed;
		OnSubscribeResponseCb subscribe_response;
		OnNotifyCb notify;
		OnSubscribePresenceReceivedCb subscribe_presence_received;
		OnSubscribePresenceClosedCb subscribe_presence_closed;
		OnParsePresenceRequestedCb parse_presence_requested;
		OnConvertPresenceToXMLRequestedCb convert_presence_to_xml_requested;
		OnNotifyPresenceCb notify_presence;
		OnPingReplyCb ping_reply;
		OnAuthRequestedCb auth_requested;
		OnInfoReceivedCb info_received;
		OnPublishResponseCb on_publish_response;
		OnExpireCb on_expire;
		OnNotifyResponseCb on_notify_response;
116
		OnReferCb refer_received; // For out of dialog refer
117
	};
118

119 120
	Sal(MSFactory *factory);
	~Sal();
121

122
	void setFactory (MSFactory *value) { mFactory = value; }
123

124 125
	void setUserPointer (void *value) { mUserPointer = value; }
	void *getUserPointer () const { return mUserPointer; }
126

127
	void setCallbacks (const Callbacks *cbs);
128

129
	void *getStackImpl() const { return mStack; }
130

131
	int iterate () { belle_sip_stack_sleep(mStack, 0); return 0; }
132

133 134
	void setSendError (int value) { belle_sip_stack_set_send_error(mStack, value); }
	void setRecvError (int value) { belle_sip_provider_set_recv_error(mProvider, value); }
135 136


137 138 139
	// ---------------------------------------------------------------------------
	// SIP parameters
	// ---------------------------------------------------------------------------
140 141 142 143
	void setSupportedTags (const std::string &tags);
	const std::string &getSupportedTags () const;
	void addSupportedTag (const std::string &tag);
	void removeSupportedTag (const std::string &tag);
144

145 146
	void setUserAgent (const std::string &value);
	const std::string &getUserAgent () const;
147
	void appendStackStringToUserAgent ();
148

149 150 151 152
	bool isContentEncodingAvailable (const std::string &contentEncoding) const;
	bool isContentTypeSupported (const std::string &contentType) const;
	void addContentTypeSupport (const std::string &contentType);
	void removeContentTypeSupport (const std::string &contentType);
153

154
	void setDefaultSdpHandling (SalOpSDPHandling sdpHandlingMethod);
155

156
	void setUuid (const std::string &value) { mUuid = value; }
Ghislain MARY's avatar
Ghislain MARY committed
157 158
	std::string createUuid ();
	static std::string generateUuid ();
159

160 161
	void enableNatHelper (bool value);
	bool natHelperEnabled () const { return mNatHelperEnabled; }
162

163 164
	bool pendingTransactionCheckingEnabled () const { return mPendingTransactionChecking; }
	void enablePendingTransactionChecking (bool value) { mPendingTransactionChecking = value; }
165

166 167
	void setRefresherRetryAfter (int value) { mRefresherRetryAfter = value; }
	int getRefresherRetryAfter () const { return mRefresherRetryAfter; }
168

169
	void enableSipUpdateMethod (bool value) { mEnableSipUpdate = value; }
170
	void useSessionTimers (int expires) { mSessionExpires = expires; }
171 172 173 174 175 176
	void useDates (bool value) { mUseDates = value; }
	void useOneMatchingCodecPolicy (bool value) { mOneMatchingCodec = value; }
	void useRport (bool value);
	void enableAutoContacts (bool value) { mAutoContacts = value; }
	void enableTestFeatures (bool value) { mEnableTestFeatures = value; }
	void useNoInitialRoute (bool value) { mNoInitialRoute = value; }
177
	void enableUnconditionalAnswer (int value) { belle_sip_provider_enable_unconditional_answer(mProvider, value); }
178
	void enableReconnectToPrimaryAsap (bool value) { belle_sip_stack_enable_reconnect_to_primary_asap(mStack, value); }
179

180
	const std::list<SalOp *> &getPendingAuths () const { return mPendingAuths; }
181

182
	void setContactLinphoneSpecs (const std::string &value) { mLinphoneSpecs = value; }
183 184


185 186 187
	// ---------------------------------------------------------------------------
	// Network parameters
	// ---------------------------------------------------------------------------
188
	int setListenPort (const std::string &addr, int port, SalTransport tr, bool isTunneled);
189
	int getListeningPort (SalTransport tr);
Ghislain MARY's avatar
Ghislain MARY committed
190
	bool isTransportAvailable (SalTransport tr);
191

192 193
	void setTransportTimeout (int value) { belle_sip_stack_set_transport_timeout(mStack, value); }
	int getTransportTimeout () const { return belle_sip_stack_get_transport_timeout(mStack); }
194

195 196
	void setKeepAlivePeriod (unsigned int value);
	unsigned int getKeepAlivePeriod () const { return mKeepAlive; }
197
	void useTcpTlsKeepAlive (bool value) { mUseTcpTlsKeepAlive = value; }
198

199
	void setDscp (int dscp) { belle_sip_stack_set_default_dscp(mStack, dscp); }
200

201
	int setTunnel (void *tunnelClient);
202

203 204
	void setHttpProxyHost (const std::string &value);
	const std::string &getHttpProxyHost () const;
205

206 207
	void setHttpProxyPort (int value) { belle_sip_stack_set_http_proxy_port(mStack, value); }
	int getHttpProxyPort () const { return belle_sip_stack_get_http_proxy_port(mStack); }
208

Ghislain MARY's avatar
Ghislain MARY committed
209 210
	void unlistenPorts ();
	void resetTransports ();
211 212


213 214 215 216
	// ---------------------------------------------------------------------------
	// TLS parameters
	// ---------------------------------------------------------------------------
	void setSslConfig (void *sslConfig);
217 218 219
	void setRootCa (const std::string &value);
	void setRootCaData (const std::string &value);
	const std::string &getRootCa () const { return mRootCa; }
220

221 222
	void verifyServerCertificates (bool value);
	void verifyServerCn (bool value);
223
	void setTlsPostcheckCallback(int (*cb)(void *, const bctbx_x509_certificate_t *), void *data);
224

225 226 227 228 229
	// ---------------------------------------------------------------------------
	// DNS resolution
	// ---------------------------------------------------------------------------
	void setDnsTimeout (int value) { belle_sip_stack_set_dns_timeout(mStack, value); }
	int getDnsTimeout () const { return belle_sip_stack_get_dns_timeout(mStack); }
230

231
	void setDnsServers (const bctbx_list_t *servers);
232

233
	void enableDnsSearch (bool value) { belle_sip_stack_enable_dns_search(mStack, (unsigned char)value); }
234
	bool dnsSearchEnabled () const { return !!belle_sip_stack_dns_search_enabled(mStack); }
235

236
	void enableDnsSrv (bool value) { belle_sip_stack_enable_dns_srv(mStack, (unsigned char)value); }
237
	bool dnsSrvEnabled () const { return !!belle_sip_stack_dns_srv_enabled(mStack); }
238

239 240
	void setDnsUserHostsFile (const std::string &value);
	const std::string &getDnsUserHostsFile () const;
241

242 243
	belle_sip_resolver_context_t *resolveA (const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data);
	belle_sip_resolver_context_t *resolve (const std::string &service, const std::string &transport, const std::string &name, int port, int family, belle_sip_resolver_callback_t cb, void *data); 
244 245


246 247 248
	// ---------------------------------------------------------------------------
	// Timers
	// ---------------------------------------------------------------------------
249
	belle_sip_source_t *createTimer (belle_sip_source_func_t func, void *data, unsigned int timeoutValueMs, const std::string &timerName);
250
	void cancelTimer (belle_sip_source_t *timer);
251

252 253
	//utils
	static int findCryptoIndexFromTag (const SalSrtpCryptoAlgo crypto[], unsigned char tag);
254

255
private:
256 257 258 259 260 261
	struct SalUuid {
		unsigned int timeLow;
		unsigned short timeMid;
		unsigned short timeHiAndVersion;
		unsigned char clockSeqHiAndReserved;
		unsigned char clockSeqLow;
262 263
		unsigned char node[6];
	};
264

265
	void setTlsProperties ();
266
	int addListenPort (SalAddress *addr, bool isTunneled);
267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287
	void makeSupportedHeader ();
	void addPendingAuth (SalOp *op);
	void removePendingAuth (SalOp *op);
	belle_sip_response_t *createResponseFromRequest (belle_sip_request_t *req, int code);

	static void unimplementedStub() { lWarning() << "Unimplemented SAL callback"; }
	static void removeListeningPoint (belle_sip_listening_point_t *lp,belle_sip_provider_t *prov) {
		belle_sip_provider_remove_listening_point(prov, lp);
	}

	// Internal callbacks
	static void processDialogTerminatedCb (void *userCtx, const belle_sip_dialog_terminated_event_t *event);
	static void processIoErrorCb (void *userCtx, const belle_sip_io_error_event_t *event);
	static void processRequestEventCb (void *userCtx, const belle_sip_request_event_t *event);
	static void processResponseEventCb (void *userCtx, const belle_sip_response_event_t *event);
	static void processTimeoutCb (void *userCtx, const belle_sip_timeout_event_t *event);
	static void processTransactionTerminatedCb (void *userCtx, const belle_sip_transaction_terminated_event_t *event);
	static void processAuthRequestedCb (void *userCtx, belle_sip_auth_event_t *event);

	MSFactory *mFactory = nullptr;
	Callbacks mCallbacks = { 0 };
288
	std::list<SalOp *> mPendingAuths;
289 290
	belle_sip_stack_t *mStack = nullptr;
	belle_sip_provider_t *mProvider = nullptr;
291
	belle_sip_header_user_agent_t *mUserAgentHeader = nullptr;
292 293 294 295 296
	belle_sip_listener_t *mListener = nullptr;
	void *mTunnelClient = nullptr;
	void *mUserPointer = nullptr; // User pointer
	int mSessionExpires = 0;
	unsigned int mKeepAlive = 0;
297 298 299
	std::string mRootCa;
	std::string mRootCaData;
	std::string mUuid;
300
	int mRefresherRetryAfter = 60000; // Retry after value for refresher
301 302
	std::vector<std::string> mSupportedTags;
	belle_sip_header_t *mSupportedHeader = nullptr;
303 304 305 306 307 308 309 310 311 312
	bool mOneMatchingCodec = false;
	bool mUseTcpTlsKeepAlive = false;
	bool mNatHelperEnabled = false;
	bool mTlsVerify = true;
	bool mTlsVerifyCn = true;
	bool mUseDates = false;
	bool mAutoContacts = true;
	bool mEnableTestFeatures = false;
	bool mNoInitialRoute = false;
	bool mEnableSipUpdate = true;
313
	SalOpSDPHandling mDefaultSdpHandling = SalOpSDPNormal;
314
	bool mPendingTransactionChecking = true; // For testing purposes
315
	void *mSslConfig = nullptr;
316 317
	std::vector<std::string> mSupportedContentTypes;
	std::string mLinphoneSpecs;
318 319
	belle_tls_crypto_config_postcheck_callback_t mTlsPostcheckCb;
	void *mTlsPostcheckCbData;
320 321 322 323 324 325

	// Cache values
	mutable std::string mDnsUserHostsFile;
	mutable std::string mHttpProxyHost;
	mutable std::string mSupported;
	mutable std::string mUserAgent;
326

327 328 329 330 331 332 333
	friend class SalOp;
	friend class SalCallOp;
	friend class SalRegisterOp;
	friend class SalMessageOp;
	friend class SalPresenceOp;
	friend class SalSubscribeOp;
	friend class SalPublishOp;
334
	friend class SalReferOp;
335 336
};

Ghislain MARY's avatar
Ghislain MARY committed
337
int toSipCode (SalReason reason);
338 339 340

LINPHONE_END_NAMESPACE

341
#endif // ifndef _L_SAL_H_
342