sal.h 33.2 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/*
linphone
Copyright (C) 2010  Simon MORLAT (simon.morlat@free.fr)

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.

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
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
*/

20
/**
21
 This header files defines the Signaling Abstraction Layer.
22
 The purpose of this layer is too allow experiment different call signaling
23
24
25
26
27
28
 protocols and implementations under linphone, for example SIP, JINGLE...
**/

#ifndef sal_h
#define sal_h

29
30
31
32
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

jehan's avatar
jehan committed
33
#include "mediastreamer2/mediastream.h"
34
#include "ortp/rtpsession.h"
35
#include "belle-sip/belle-sip.h"
36

jehan's avatar
jehan committed
37
38
#ifndef LINPHONE_PUBLIC
	#define LINPHONE_PUBLIC MS2_PUBLIC
39
40
#endif

Simon Morlat's avatar
Simon Morlat committed
41
42
43
44
45
/*Dirty hack, keep in sync with mediastreamer2/include/mediastream.h */
#ifndef PAYLOAD_TYPE_FLAG_CAN_RECV
#define PAYLOAD_TYPE_FLAG_CAN_RECV	PAYLOAD_TYPE_USER_FLAG_1
#define PAYLOAD_TYPE_FLAG_CAN_SEND	PAYLOAD_TYPE_USER_FLAG_2
#endif
46
47
48
49
50
51
52
53
struct Sal;

typedef struct Sal Sal;

struct SalOp;

typedef struct SalOp SalOp;

54
55
56
57
struct SalAddress;

typedef struct SalAddress SalAddress;

58
59
60
61
struct SalCustomHeader;

typedef struct SalCustomHeader SalCustomHeader;

62
63
64
65
struct SalCustomSdpAttribute;

typedef struct SalCustomSdpAttribute SalCustomSdpAttribute;

66
67
struct addrinfo;

68
69
70
71
typedef enum {
	SalTransportUDP, /*UDP*/
	SalTransportTCP, /*TCP*/
	SalTransportTLS, /*TLS*/
72
	SalTransportDTLS, /*DTLS*/
73
74
}SalTransport;

jehan's avatar
jehan committed
75
76
77
78
79
80
81
82
#define SAL_MEDIA_DESCRIPTION_UNCHANGED						0x00
#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED				(1)
#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED					(1<<1)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED			(1<<2)
#define SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED			(1<<3)
#define SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED				(1<<4)
#define SAL_MEDIA_DESCRIPTION_NETWORK_XXXCAST_CHANGED		(1<<5) /* use to notify when switching from multicast to unicast*/
#define SAL_MEDIA_DESCRIPTION_FORCE_STREAM_RECONSTRUCTION	(1<<6) /* use force graph reconstruction*/
83
#define SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED			(1<<7)
jehan's avatar
jehan committed
84
85


86

87
88
const char* sal_transport_to_string(SalTransport transport);
SalTransport sal_transport_parse(const char*);
89
90
91
/* Address manipulation API*/
SalAddress * sal_address_new(const char *uri);
SalAddress * sal_address_clone(const SalAddress *addr);
92
93
SalAddress * sal_address_ref(SalAddress *addr);
void sal_address_unref(SalAddress *addr);
94
95
const char *sal_address_get_scheme(const SalAddress *addr);
const char *sal_address_get_display_name(const SalAddress* addr);
jehan's avatar
jehan committed
96
const char *sal_address_get_display_name_unquoted(const SalAddress *addr);
97
98
const char *sal_address_get_username(const SalAddress *addr);
const char *sal_address_get_domain(const SalAddress *addr);
99
int sal_address_get_port(const SalAddress *addr);
100
bool_t sal_address_is_secure(const SalAddress *addr);
101
void sal_address_set_secure(SalAddress *addr, bool_t enabled);
102

103
SalTransport sal_address_get_transport(const SalAddress* addr);
104
const char* sal_address_get_transport_name(const SalAddress* addr);
jehan's avatar
jehan committed
105

106
107
108
void sal_address_set_display_name(SalAddress *addr, const char *display_name);
void sal_address_set_username(SalAddress *addr, const char *username);
void sal_address_set_domain(SalAddress *addr, const char *host);
109
void sal_address_set_port(SalAddress *uri, int port);
110
111
112
113
void sal_address_clean(SalAddress *addr);
char *sal_address_as_string(const SalAddress *u);
char *sal_address_as_string_uri_only(const SalAddress *u);
void sal_address_destroy(SalAddress *u);
114
115
void sal_address_set_param(SalAddress *u,const char* name,const char* value);
void sal_address_set_transport(SalAddress* addr,SalTransport transport);
116
void sal_address_set_transport_name(SalAddress* addr,const char* transport);
117
118
void sal_address_set_params(SalAddress *addr, const char *params);
void sal_address_set_uri_params(SalAddress *addr, const char *params);
119
bool_t sal_address_is_ipv6(const SalAddress *addr);
120
bool_t sal_address_is_sip(const SalAddress *addr);
121
122
123
void sal_address_set_password(SalAddress *addr, const char *passwd);
const char *sal_address_get_password(const SalAddress *addr);
void sal_address_set_header(SalAddress *addr, const char *header_name, const char *header_value);
Simon Morlat's avatar
Simon Morlat committed
124

125
LINPHONE_PUBLIC Sal * sal_init(void);
Ghislain MARY's avatar
Ghislain MARY committed
126
LINPHONE_PUBLIC void sal_uninit(Sal* sal);
Simon Morlat's avatar
Simon Morlat committed
127
128
void sal_set_user_pointer(Sal *sal, void *user_data);
void *sal_get_user_pointer(const Sal *sal);
129
130
131


typedef enum {
132
133
	SalAudio,
	SalVideo,
134
	SalText,
135
	SalOther
136
} SalStreamType;
jehan's avatar
jehan committed
137
const char* sal_stream_type_to_string(SalStreamType type);
138

Simon Morlat's avatar
Simon Morlat committed
139
typedef enum{
140
	SalProtoRtpAvp,
141
	SalProtoRtpSavp,
142
143
	SalProtoRtpAvpf,
	SalProtoRtpSavpf,
johan's avatar
johan committed
144
145
	SalProtoUdpTlsRtpSavp,
	SalProtoUdpTlsRtpSavpf,
146
	SalProtoOther
Simon Morlat's avatar
Simon Morlat committed
147
}SalMediaProto;
jehan's avatar
jehan committed
148
const char* sal_media_proto_to_string(SalMediaProto type);
Simon Morlat's avatar
Simon Morlat committed
149

Simon Morlat's avatar
Simon Morlat committed
150
151
152
153
154
155
typedef enum{
	SalStreamSendRecv,
	SalStreamSendOnly,
	SalStreamRecvOnly,
	SalStreamInactive
}SalStreamDir;
jehan's avatar
jehan committed
156
const char* sal_stream_dir_to_string(SalStreamDir type);
Simon Morlat's avatar
Simon Morlat committed
157

jehan's avatar
jehan committed
158

159
160
#define SAL_ENDPOINT_CANDIDATE_MAX 2

161
162
163
164
165
166
167
168
169
170
171
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN 64
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_FOUNDATION_LEN 32
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_TYPE_LEN 6

typedef struct SalIceCandidate {
	char addr[SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN];
	char raddr[SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN];
	char foundation[SAL_MEDIA_DESCRIPTION_MAX_ICE_FOUNDATION_LEN];
	char type[SAL_MEDIA_DESCRIPTION_MAX_ICE_TYPE_LEN];
	unsigned int componentID;
	unsigned int priority;
172
	int port;
173
174
	int rport;
} SalIceCandidate;
175

176
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES 20
177
178
179
180
181
182
183

typedef struct SalIceRemoteCandidate {
	char addr[SAL_MEDIA_DESCRIPTION_MAX_ICE_ADDR_LEN];
	int port;
} SalIceRemoteCandidate;

#define SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES 2
184

185
186
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN 256
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256
187

188
/*sufficient for 256bit keys encoded in base 64*/
189
#define SAL_SRTP_KEY_SIZE 128
190

191
192
typedef struct SalSrtpCryptoAlgo {
	unsigned int tag;
jehan's avatar
jehan committed
193
	MSCryptoSuite algo;
194
	char master_key[SAL_SRTP_KEY_SIZE];
195
196
197
198
} SalSrtpCryptoAlgo;

#define SAL_CRYPTO_ALGO_MAX 4

johan's avatar
johan committed
199
200
201
202
203
204
205
typedef enum {
	SalDtlsRoleInvalid,
	SalDtlsRoleIsServer,
	SalDtlsRoleIsClient,
	SalDtlsRoleUnset
} SalDtlsRole;

jehan's avatar
jehan committed
206
typedef enum {
207
208
209
	SalMulticastInactive=0,
	SalMulticastSender,
	SalMulticastReceiver,
jehan's avatar
jehan committed
210
211
212
	SalMulticastSenderReceiver
} SalMulticastRole;

213
214
215
216
217
typedef enum {
	SalOpSDPNormal = 0, /** No special handling for SDP */
	SalOpSDPSimulateError, /** Will simulate an SDP parsing error */
	SalOpSDPSimulateRemove /** Will simulate no SDP in the op */
} SalOpSDPHandling;
jehan's avatar
jehan committed
218

219
typedef struct SalStreamDescription{
220
	char name[16]; /*unique name of stream, in order to ease offer/answer model algorithm*/
Simon Morlat's avatar
Simon Morlat committed
221
	SalMediaProto proto;
222
	SalStreamType type;
223
	char typeother[32];
224
	char proto_other[32];
225
226
	char rtp_addr[64];
	char rtcp_addr[64];
227
	unsigned int rtp_ssrc;
228
	char rtcp_cname[256];
229
230
	int rtp_port;
	int rtcp_port;
231
232
	MSList *payloads; /*<list of PayloadType */
	MSList *already_assigned_payloads; /*<list of PayloadType offered in the past, used for correct allocation of payload type numbers*/
233
234
	int bandwidth;
	int ptime;
Simon Morlat's avatar
Simon Morlat committed
235
	SalStreamDir dir;
236
	SalSrtpCryptoAlgo crypto[SAL_CRYPTO_ALGO_MAX];
237
	unsigned int crypto_local_tag;
238
	int max_rate;
239
	OrtpRtcpFbConfiguration rtcp_fb;
240
	OrtpRtcpXrConfiguration rtcp_xr;
241
	SalCustomSdpAttribute *custom_sdp_attributes;
242
243
244
245
246
	SalIceCandidate ice_candidates[SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES];
	SalIceRemoteCandidate ice_remote_candidates[SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES];
	char ice_ufrag[SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN];
	char ice_pwd[SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN];
	bool_t ice_mismatch;
247
	bool_t ice_completed;
248
249
	bool_t rtcp_mux;
	bool_t pad[1];
johan's avatar
johan committed
250
251
	char dtls_fingerprint[256];
	SalDtlsRole dtls_role;
jehan's avatar
jehan committed
252
253
	int ttl; /*for multicast -1 to disable*/
	SalMulticastRole multicast_role;
254
255
} SalStreamDescription;

256
257
258
259
const char *sal_stream_description_get_type_as_string(const SalStreamDescription *desc);
const char *sal_stream_description_get_proto_as_string(const SalStreamDescription *desc);

#define SAL_MEDIA_DESCRIPTION_MAX_STREAMS 8
Simon Morlat's avatar
Simon Morlat committed
260

261
typedef struct SalMediaDescription{
262
	int refcount;
263
	char name[64];
264
265
	char addr[64];
	char username[64];
266
	int nb_streams;
267
	int bandwidth;
268
269
	unsigned int session_ver;
	unsigned int session_id;
270
	SalStreamDir dir;
Simon Morlat's avatar
Simon Morlat committed
271
	SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
272
	SalCustomSdpAttribute *custom_sdp_attributes;
273
	OrtpRtcpXrConfiguration rtcp_xr;
274
275
276
277
	char ice_ufrag[SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN];
	char ice_pwd[SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN];
	bool_t ice_lite;
	bool_t ice_completed;
278
	bool_t pad[2];
279
280
} SalMediaDescription;

281
282
283
284
285
typedef struct SalMessage{
	const char *from;
	const char *text;
	const char *url;
	const char *message_id;
286
	const char *content_type;
287
	time_t time;
288
289
}SalMessage;

290
291
292
293
294
typedef struct SalIsComposing {
	const char *from;
	const char *text;
} SalIsComposing;

295
296
#define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5

297
SalMediaDescription *sal_media_description_new(void);
298
SalMediaDescription * sal_media_description_ref(SalMediaDescription *md);
299
void sal_media_description_unref(SalMediaDescription *md);
Simon Morlat's avatar
Simon Morlat committed
300
bool_t sal_media_description_empty(const SalMediaDescription *md);
301
int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
302
char * sal_media_description_print_differences(int result);
Simon Morlat's avatar
Simon Morlat committed
303
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
304
LINPHONE_PUBLIC SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type);
305
306
307
308
unsigned int sal_media_description_nb_active_streams_of_type(SalMediaDescription *md, SalStreamType type);
SalStreamDescription * sal_media_description_get_active_stream_of_type(SalMediaDescription *md, SalStreamType type, unsigned int idx);
SalStreamDescription * sal_media_description_find_secure_stream_of_type(SalMediaDescription *md, SalStreamType type);
SalStreamDescription * sal_media_description_find_best_stream(SalMediaDescription *md, SalStreamType type);
Simon Morlat's avatar
Simon Morlat committed
309
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir);
310
311
312
bool_t sal_stream_description_active(const SalStreamDescription *sd);
bool_t sal_stream_description_has_avpf(const SalStreamDescription *sd);
bool_t sal_stream_description_has_srtp(const SalStreamDescription *sd);
johan's avatar
johan committed
313
bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd);
314
315
bool_t sal_media_description_has_avpf(const SalMediaDescription *md);
bool_t sal_media_description_has_srtp(const SalMediaDescription *md);
johan's avatar
johan committed
316
bool_t sal_media_description_has_dtls(const SalMediaDescription *md);
317
int sal_media_description_get_nb_active_streams(const SalMediaDescription *md);
Simon Morlat's avatar
Simon Morlat committed
318

319

Simon Morlat's avatar
Simon Morlat committed
320
321
322
/*this structure must be at the first byte of the SalOp structure defined by implementors*/
typedef struct SalOpBase{
	Sal *root;
323
	char *route; /*or request-uri for REGISTER*/
324
	MSList* route_addresses; /*list of SalAddress* */
jehan's avatar
jehan committed
325
	SalAddress* contact_address;
Simon Morlat's avatar
Simon Morlat committed
326
	char *from;
jehan's avatar
jehan committed
327
	SalAddress* from_address;
Simon Morlat's avatar
Simon Morlat committed
328
	char *to;
jehan's avatar
jehan committed
329
	SalAddress* to_address;
330
	char *origin;
jehan's avatar
jehan committed
331
	SalAddress* origin_address;
332
	char *remote_ua;
333
334
	SalAddress* remote_contact_address;
	char *remote_contact;
Simon Morlat's avatar
Simon Morlat committed
335
336
	SalMediaDescription *local_media;
	SalMediaDescription *remote_media;
Simon Morlat's avatar
Simon Morlat committed
337
	void *user_pointer;
jehan's avatar
jehan committed
338
	const char* call_id;
339
	char* realm;
jehan's avatar
jehan committed
340
	SalAddress* service_route; /*as defined by rfc3608, might be a list*/
Simon Morlat's avatar
Simon Morlat committed
341
342
	SalCustomHeader *sent_custom_headers;
	SalCustomHeader *recv_custom_headers;
Simon Morlat's avatar
Simon Morlat committed
343
344
} SalOpBase;

345

346
typedef enum SalReason{
347
	SalReasonNone, /*no error, please leave first so that it takes 0 value*/
348
349
350
351
	SalReasonDeclined,
	SalReasonBusy,
	SalReasonRedirect,
	SalReasonTemporarilyUnavailable,
352
	SalReasonRequestTimeout,
353
354
	SalReasonNotFound,
	SalReasonDoNotDisturb,
355
	SalReasonUnsupportedContent,
356
	SalReasonForbidden,
357
	SalReasonUnknown,
358
	SalReasonServiceUnavailable,
jehan's avatar
jehan committed
359
	SalReasonRequestPending,
360
	SalReasonUnauthorized,
361
	SalReasonNotAcceptable,
362
363
364
365
366
367
	SalReasonNoMatch, /*equivalent to 481 Transaction/Call leg does not exist*/
	SalReasonMovedPermanently,
	SalReasonGone,
	SalReasonAddressIncomplete,
	SalReasonNotImplemented,
	SalReasonBadGateway,
368
	SalReasonServerTimeout,
369
370
	SalReasonIOError,
	SalReasonInternalError
371
372
}SalReason;

jehan's avatar
jehan committed
373
374
const char* sal_reason_to_string(const SalReason reason);

375
376
377
378
379
380
381
382
typedef struct SalErrorInfo{
	SalReason reason;
	char *status_string;
	int protocol_code;
	char *warnings;
	char *full_string; /*concatenation of status_string + warnings*/
}SalErrorInfo;

383
384
385
386
387
388
389
390
391
392
393
typedef enum SalPresenceStatus{
	SalPresenceOffline,
	SalPresenceOnline,
	SalPresenceBusy,
	SalPresenceBerightback,
	SalPresenceAway,
	SalPresenceOnthephone,
	SalPresenceOuttolunch,
	SalPresenceDonotdisturb,
	SalPresenceMoved,
	SalPresenceAltService,
394
	SalPresenceOnVacation
395
396
}SalPresenceStatus;

397
398
399
struct _SalPresenceModel;
typedef struct _SalPresenceModel SalPresenceModel;

jehan's avatar
jehan committed
400
401
const char* sal_presence_status_to_string(const SalPresenceStatus status);

402
403
404
405
406
407
408
typedef enum SalReferStatus{
	SalReferTrying,
	SalReferSuccess,
	SalReferFailed
}SalReferStatus;

typedef enum SalSubscribeStatus{
409
410
	SalSubscribeNone,
	SalSubscribePending,
411
412
	SalSubscribeActive,
	SalSubscribeTerminated
413
}SalSubscribeStatus;
414

415
416
417
418
419
typedef enum SalTextDeliveryStatus{
	SalTextDeliveryInProgress,
	SalTextDeliveryDone,
	SalTextDeliveryFailed
}SalTextDeliveryStatus;
420

421
422
423
/**
 * auth event mode
 * */
jehan's avatar
jehan committed
424
typedef enum SalAuthMode { /*this enum must be same as belle_sip_auth_mode_t*/
425
426
427
428
429
430
431
432
433
434
435
436
	SalAuthModeHttpDigest, /** Digest authentication requested*/
	SalAuthModeTls /** Client certificate requested*/
}SalAuthMode;

struct _SalCertificatesChain;
typedef struct _SalCertificatesChain SalCertificatesChain;
struct _SalSigningKey;
typedef struct _SalSigningKey SalSigningKey;

/**
 * Format of certificate buffer
 * */
jehan's avatar
jehan committed
437
typedef enum SalCertificateRawFormat {/*this enum must be same as belle_sip_certificate_raw_format_t*/
438
439
440
441
442
443
	SAL_CERTIFICATE_RAW_FORMAT_PEM, /** PEM format*/
	SAL_CERTIFICATE_RAW_FORMAT_DER /** ASN.1 raw format*/
}SalCertificateRawFormat;



jehan's avatar
jehan committed
444
445
446
447
448
typedef struct SalAuthInfo{
	char *username;
	char *userid;
	char *password;
	char *realm;
449
	char *domain;
jehan's avatar
jehan committed
450
	char *ha1;
451
452
453
	SalAuthMode mode;
	SalSigningKey *key;
	SalCertificatesChain *certificates;
jehan's avatar
jehan committed
454
455
}SalAuthInfo;

Simon Morlat's avatar
Simon Morlat committed
456
457
458
459
460
typedef struct SalBody{
	const char *type;
	const char *subtype;
	const void *data;
	size_t size;
461
	const char *encoding;
Simon Morlat's avatar
Simon Morlat committed
462
463
}SalBody;

464
465
466
typedef void (*SalOnCallReceived)(SalOp *op);
typedef void (*SalOnCallRinging)(SalOp *op);
typedef void (*SalOnCallAccepted)(SalOp *op);
467
typedef void (*SalOnCallAck)(SalOp *op);
468
typedef void (*SalOnCallUpdating)(SalOp *op, bool_t is_update);/*< Called when a reINVITE/UPDATE is received*/
Simon Morlat's avatar
Simon Morlat committed
469
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
470
typedef void (*SalOnCallFailure)(SalOp *op);
471
typedef void (*SalOnCallReleased)(SalOp *salop);
jehan's avatar
jehan committed
472
typedef void (*SalOnAuthRequestedLegacy)(SalOp *op, const char *realm, const char *username);
jehan's avatar
jehan committed
473
typedef bool_t (*SalOnAuthRequested)(Sal *sal,SalAuthInfo* info);
jehan's avatar
jehan committed
474
typedef void (*SalOnAuthFailure)(SalOp *op, SalAuthInfo* info);
475
typedef void (*SalOnRegisterSuccess)(SalOp *op, bool_t registered);
476
typedef void (*SalOnRegisterFailure)(SalOp *op);
477
478
479
typedef void (*SalOnVfuRequest)(SalOp *op);
typedef void (*SalOnDtmfReceived)(SalOp *op, char dtmf);
typedef void (*SalOnRefer)(Sal *sal, SalOp *op, const char *referto);
480
typedef void (*SalOnTextReceived)(SalOp *op, const SalMessage *msg);
481
typedef void (*SalOnTextDeliveryUpdate)(SalOp *op, SalTextDeliveryStatus);
482
typedef void (*SalOnIsComposingReceived)(SalOp *op, const SalIsComposing *is_composing);
483
typedef void (*SalOnNotifyRefer)(SalOp *op, SalReferStatus state);
484
typedef void (*SalOnSubscribeResponse)(SalOp *op, SalSubscribeStatus status);
485
486
487
typedef void (*SalOnNotify)(SalOp *op, SalSubscribeStatus status, const char *event, const SalBody *body);
typedef void (*SalOnSubscribeReceived)(SalOp *salop, const char *event, const SalBody *body);
typedef void (*SalOnSubscribeClosed)(SalOp *salop);
488
typedef void (*SalOnParsePresenceRequested)(SalOp *salop, const char *content_type, const char *content_subtype, const char *content, SalPresenceModel **result);
489
typedef void (*SalOnConvertPresenceToXMLRequested)(SalOp *salop, SalPresenceModel *presence, const char *contact, char **content);
490
typedef void (*SalOnNotifyPresence)(SalOp *op, SalSubscribeStatus ss, SalPresenceModel *model, const char *msg);
491
492
typedef void (*SalOnSubscribePresenceReceived)(SalOp *salop, const char *from);
typedef void (*SalOnSubscribePresenceClosed)(SalOp *salop, const char *from);
493
typedef void (*SalOnPingReply)(SalOp *salop);
Simon Morlat's avatar
Simon Morlat committed
494
typedef void (*SalOnInfoReceived)(SalOp *salop, const SalBody *body);
495
typedef void (*SalOnPublishResponse)(SalOp *salop);
496
typedef void (*SalOnExpire)(SalOp *salop);
jehan's avatar
jehan committed
497
498
499
/*allows sal implementation to access auth info if available, return TRUE if found*/


500

Simon Morlat's avatar
Simon Morlat committed
501
502
503
504
typedef struct SalCallbacks{
	SalOnCallReceived call_received;
	SalOnCallRinging call_ringing;
	SalOnCallAccepted call_accepted;
505
	SalOnCallAck call_ack;
506
	SalOnCallUpdating call_updating;
Simon Morlat's avatar
Simon Morlat committed
507
508
	SalOnCallTerminated call_terminated;
	SalOnCallFailure call_failure;
509
	SalOnCallReleased call_released;
jehan's avatar
jehan committed
510
	SalOnAuthFailure auth_failure;
511
512
513
514
515
516
	SalOnRegisterSuccess register_success;
	SalOnRegisterFailure register_failure;
	SalOnVfuRequest vfu_request;
	SalOnDtmfReceived dtmf_received;
	SalOnRefer refer_received;
	SalOnTextReceived text_received;
517
	SalOnTextDeliveryUpdate text_delivery_update;
518
	SalOnIsComposingReceived is_composing_received;
519
	SalOnNotifyRefer notify_refer;
Simon Morlat's avatar
Simon Morlat committed
520
	SalOnSubscribeReceived subscribe_received;
521
	SalOnSubscribeClosed subscribe_closed;
522
523
524
525
	SalOnSubscribeResponse subscribe_response;
	SalOnNotify notify;
	SalOnSubscribePresenceReceived subscribe_presence_received;
	SalOnSubscribePresenceClosed subscribe_presence_closed;
526
	SalOnParsePresenceRequested parse_presence_requested;
527
	SalOnConvertPresenceToXMLRequested convert_presence_to_xml_requested;
528
	SalOnNotifyPresence notify_presence;
529
	SalOnPingReply ping_reply;
jehan's avatar
jehan committed
530
	SalOnAuthRequested auth_requested;
Simon Morlat's avatar
Simon Morlat committed
531
	SalOnInfoReceived info_received;
532
533
	SalOnPublishResponse on_publish_response;
	SalOnExpire on_expire;
Simon Morlat's avatar
Simon Morlat committed
534
535
}SalCallbacks;

jehan's avatar
jehan committed
536

537

538
SalAuthInfo* sal_auth_info_new(void);
jehan's avatar
jehan committed
539
SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info);
540
void sal_auth_info_delete(SalAuthInfo* auth_info);
541
LINPHONE_PUBLIC int sal_auth_compute_ha1(const char* userid,const char* realm,const char* password, char ha1[33]);
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
SalAuthMode sal_auth_info_get_mode(const SalAuthInfo* auth_info);
SalSigningKey *sal_auth_info_get_signing_key(const SalAuthInfo* auth_info);
SalCertificatesChain *sal_auth_info_get_certificates_chain(const SalAuthInfo* auth_info);
void sal_auth_info_set_mode(SalAuthInfo* auth_info, SalAuthMode mode);

/** Parse a file containing either a certificate chain order in PEM format or a single DER cert
 * @param auth_info structure where to store the result of parsing
 * @param path path to certificate chain file
 * @param format either PEM or DER
 */
void sal_certificates_chain_parse_file(SalAuthInfo* auth_info, const char* path, SalCertificateRawFormat format);

/**
 * Parse a file containing either a private or public rsa key
 * @param auth_info structure where to store the result of parsing
 * @param passwd password (optionnal)
 */
void sal_signing_key_parse_file(SalAuthInfo* auth_info, const char* path, const char *passwd);

johan's avatar
johan committed
561
562
563
564
565
566
567
568
569
570
/**
 * Parse a directory for files containing certificate with the given subject CNAME
 * @param[out]	certificate_pem				the address of a string to store the certificate in PEM format. To be freed by caller
 * @param[out]	key_pem						the address of a string to store the key in PEM format. To be freed by caller
 * @param[in]	path						directory to parse
 * @param[in]	subject						subject CNAME
 * @param[in]	format 						either PEM or DER
 * @param[in]	generate_certificate		if true, if matching certificate and key can't be found, generate it and store it into the given dir, filename will be subject.pem
 * @param[in]	generate_dtls_fingerprint	if true and we have a certificate, generate the dtls fingerprint as described in rfc4572
 */
Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
571
void sal_certificates_chain_parse_directory(char **certificate_pem, char **key_pem, char **fingerprint, const char* path, const char *subject, SalCertificateRawFormat format, bool_t generate_certificate, bool_t generate_dtls_fingerprint);
johan's avatar
johan committed
572

573
574
575
576
void sal_certificates_chain_delete(SalCertificatesChain *chain);
void sal_signing_key_delete(SalSigningKey *key);


jehan's avatar
jehan committed
577

Simon Morlat's avatar
Simon Morlat committed
578
void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs);
579
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_tunneled);
580
int sal_get_listening_port(Sal *ctx, SalTransport tr);
581
int sal_unlisten_ports(Sal *ctx);
Ghislain MARY's avatar
Ghislain MARY committed
582
LINPHONE_PUBLIC int sal_transport_available(Sal *ctx, SalTransport t);
583
void sal_set_dscp(Sal *ctx, int dscp);
584
585
586
587
void sal_set_supported_tags(Sal *ctx, const char* tags);
void sal_add_supported_tag(Sal *ctx, const char* tag);
void sal_remove_supported_tag(Sal *ctx, const char* tag);
const char *sal_get_supported_tags(Sal *ctx);
588
int sal_reset_transports(Sal *ctx);
589
ortp_socket_t sal_get_socket(Sal *ctx);
590
void sal_set_user_agent(Sal *ctx, const char *user_agent);
591
const char* sal_get_user_agent(Sal *ctx);
592
void sal_append_stack_string_to_user_agent(Sal *ctx);
593
594
/*keepalive period in ms*/
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
595
void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled);
596
int sal_set_tunnel(Sal *ctx, void *tunnelclient);
597
598
599
/*Default value is true*/
void sal_enable_sip_update_method(Sal *ctx,bool_t value);

jehan's avatar
jehan committed
600
601
602
603
604
/**
 * returns keepalive period in ms
 * 0 desactiaved
 * */
unsigned int sal_get_keepalive_period(Sal *ctx);
605
void sal_use_session_timers(Sal *ctx, int expires);
606
void sal_use_dates(Sal *ctx, bool_t enabled);
Simon Morlat's avatar
Simon Morlat committed
607
void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec);
608
void sal_use_rport(Sal *ctx, bool_t use_rports);
609
void sal_enable_auto_contacts(Sal *ctx, bool_t enabled);
610
void sal_set_root_ca(Sal* ctx, const char* rootCa);
611
const char *sal_get_root_ca(Sal* ctx);
612
void sal_verify_server_certificates(Sal *ctx, bool_t verify);
613
void sal_verify_server_cn(Sal *ctx, bool_t verify);
614
615
void sal_set_uuid(Sal*ctx, const char *uuid);
int sal_create_uuid(Sal*ctx, char *uuid, size_t len);
616
LINPHONE_PUBLIC void sal_enable_test_features(Sal*ctx, bool_t enabled);
617
void sal_use_no_initial_route(Sal *ctx, bool_t enabled);
618

Simon Morlat's avatar
Simon Morlat committed
619
int sal_iterate(Sal *sal);
620
MSList * sal_get_pending_auths(Sal *sal);
Simon Morlat's avatar
Simon Morlat committed
621
622
623
624
625

/*create an operation */
SalOp * sal_op_new(Sal *sal);

/*generic SalOp API, working for all operations */
626
Sal *sal_op_get_sal(const SalOp *op);
jehan's avatar
jehan committed
627
void sal_op_set_contact_address(SalOp *op, const SalAddress* address);
Simon Morlat's avatar
Simon Morlat committed
628
void sal_op_set_route(SalOp *op, const char *route);
jehan's avatar
jehan committed
629
void sal_op_set_route_address(SalOp *op, const SalAddress* address);
630
void sal_op_add_route_address(SalOp *op, const SalAddress* address);
631
void sal_op_set_realm(SalOp *op, const char *realm);
Simon Morlat's avatar
Simon Morlat committed
632
void sal_op_set_from(SalOp *op, const char *from);
jehan's avatar
jehan committed
633
void sal_op_set_from_address(SalOp *op, const SalAddress *from);
Simon Morlat's avatar
Simon Morlat committed
634
void sal_op_set_to(SalOp *op, const char *to);
jehan's avatar
jehan committed
635
void sal_op_set_to_address(SalOp *op, const SalAddress *to);
636
SalOp *sal_op_ref(SalOp* h);
637
void sal_op_stop_refreshing(SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
638
void sal_op_release(SalOp *h);
639
640
641
/*same as release, but does not stop refresher if any*/
void* sal_op_unref(SalOp* op);

642
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info);
jehan's avatar
jehan committed
643
void sal_op_cancel_authentication(SalOp *h);
Simon Morlat's avatar
Simon Morlat committed
644
void sal_op_set_user_pointer(SalOp *h, void *up);
645
SalAuthInfo * sal_op_get_auth_requested(SalOp *h);
646
const char *sal_op_get_from(const SalOp *op);
jehan's avatar
jehan committed
647
const SalAddress *sal_op_get_from_address(const SalOp *op);
648
const char *sal_op_get_to(const SalOp *op);
jehan's avatar
jehan committed
649
const SalAddress *sal_op_get_to_address(const SalOp *op);
jehan's avatar
jehan committed
650
const SalAddress *sal_op_get_contact_address(const SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
651
const char *sal_op_get_route(const SalOp *op);
652
const MSList* sal_op_get_route_addresses(const SalOp *op);
653
const char *sal_op_get_proxy(const SalOp *op);
654
const char *sal_op_get_remote_contact(const SalOp *op);
655
const SalAddress* sal_op_get_remote_contact_address(const SalOp *op);
656
657
/*for incoming requests, returns the origin of the packet as a sip uri*/
const char *sal_op_get_network_origin(const SalOp *op);
jehan's avatar
jehan committed
658
const SalAddress *sal_op_get_network_origin_address(const SalOp *op);
659
660
/*returns far-end "User-Agent" string */
const char *sal_op_get_remote_ua(const SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
661
void *sal_op_get_user_pointer(const SalOp *op);
jehan's avatar
jehan committed
662
const char* sal_op_get_call_id(const SalOp *op);
663
char* sal_op_get_dialog_id(const SalOp *op);
664
bool_t sal_op_is_forked_of(const SalOp *op1, const SalOp *op2);
665

jehan's avatar
jehan committed
666
667
668
const SalAddress* sal_op_get_service_route(const SalOp *op);
void sal_op_set_service_route(SalOp *op,const SalAddress* service_route);

669
void sal_op_set_manual_refresher_mode(SalOp *op, bool_t enabled);
670
bool_t sal_op_is_ipv6(SalOp *op);
671
672
/*returns TRUE if there is no pending request that may block a future one */
bool_t sal_op_is_idle(SalOp *op);
673

674
675
676
677
678
const SalErrorInfo *sal_error_info_none(void);
const SalErrorInfo *sal_op_get_error_info(const SalOp *op);
void sal_error_info_reset(SalErrorInfo *ei);
void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning);

Simon Morlat's avatar
Simon Morlat committed
679
680
681
/*Call API*/
int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
int sal_call(SalOp *h, const char *from, const char *to);
682
int sal_call_notify_ringing(SalOp *h, bool_t early_media);
683
/*accept an incoming call or, during a call accept a reINVITE*/
684
int sal_call_accept(SalOp*h);
685
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
686
int sal_call_update(SalOp *h, const char *subject, bool_t no_user_consent);
687
SalMediaDescription * sal_call_get_remote_media_description(SalOp *h);
Simon Morlat's avatar
Simon Morlat committed
688
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
689
690
691
692
693
int sal_call_refer(SalOp *h, const char *refer_to);
int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h);
int sal_call_accept_refer(SalOp *h);
/*informs this call is consecutive to an incoming refer */
int sal_call_set_referer(SalOp *h, SalOp *refered_call);
694
695
/* returns the SalOp of a call that should be replaced by h, if any */
SalOp *sal_call_get_replaces(SalOp *h);
Simon Morlat's avatar
Simon Morlat committed
696
int sal_call_send_dtmf(SalOp *h, char dtmf);
697
int sal_call_terminate(SalOp *h);
698
bool_t sal_call_autoanswer_asked(SalOp *op);
699
void sal_call_send_vfu_request(SalOp *h);
700
int sal_call_is_offerer(const SalOp *h);
701
int sal_call_notify_refer_state(SalOp *h, SalOp *newcall);
702
/* Call test API */
703
704
705
706
707
708
709
710
711
712
713


/**
 * @brief Invoking this on the SAL will modify every subsequent SalOp to have a special handling for SDP.
 * @details This is especially useful while testing, to simulate some specific behaviors, like missing SDP or an error in parsing.
 *
 * @warning Don't forget to reset the handling method to SalOpSDPNormal afterwards.
 *
 * @param h the Sal instance
 * @param handling_method Could be SalOpSDPNormal, SalOpSDPSimulateError, SalOpSDPSimulateRemoval (\ref SalOpSDPHandling)
 */
714
LINPHONE_PUBLIC void sal_default_set_sdp_handling(Sal* h, SalOpSDPHandling handling_method) ;
715
/* Second version: for a specific call*/
716
LINPHONE_PUBLIC void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) ;
717

Simon Morlat's avatar
Simon Morlat committed
718
/*Registration*/
719
int sal_register(SalOp *op, const char *proxy, const char *from, int expires,SalAddress* old_contact);
720
/*refresh a register, -1 mean use the last known value*/
721
int sal_register_refresh(SalOp *op, int expires);
722
int sal_unregister(SalOp *h);
723

Simon Morlat's avatar
Simon Morlat committed
724
/*Messaging */
Simon Morlat's avatar
Simon Morlat committed
725
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
726
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg, const char *peer_uri);
Simon Morlat's avatar
Simon Morlat committed
727
int sal_message_reply(SalOp *op, SalReason reason);
Simon Morlat's avatar
Simon Morlat committed
728
729

/*presence Subscribe/notify*/
Simon Morlat's avatar
Simon Morlat committed
730
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires);
731
int sal_notify_presence(SalOp *op, SalPresenceModel *presence);
732
int sal_notify_presence_close(SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
733

734
/*presence publish */
735
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence);
736

737
738
739
740

/*ping: main purpose is to obtain its own contact address behind firewalls*/
int sal_ping(SalOp *op, const char *from, const char *to);

Simon Morlat's avatar
Simon Morlat committed
741
742
743
/*info messages*/
int sal_send_info(SalOp *op, const char *from, const char *to, const SalBody *body);

744
745
746
747
748
749
750
751
/*generic subscribe/notify/publish api*/
int sal_subscribe(SalOp *op, const char *from, const char *to, const char *eventname, int expires, const SalBody *body);
int sal_unsubscribe(SalOp *op);
int sal_subscribe_accept(SalOp *op);
int sal_subscribe_decline(SalOp *op, SalReason reason);
int sal_notify(SalOp *op, const SalBody *body);
int sal_notify_close(SalOp *op);
int sal_publish(SalOp *op, const char *from, const char *to, const char*event_name, int expires, const SalBody *body);
Simon Morlat's avatar
Simon Morlat committed
752

jehan's avatar
jehan committed
753
754
/*privacy, must be in sync with LinphonePrivacyMask*/
typedef enum _SalPrivacy {
Simon Morlat's avatar
Simon Morlat committed
755
	SalPrivacyNone=0x0,
jehan's avatar
jehan committed
756
757
758
759
	SalPrivacyUser=0x1,
	SalPrivacyHeader=0x2,
	SalPrivacySession=0x4,
	SalPrivacyId=0x8,
Simon Morlat's avatar
Simon Morlat committed
760
761
	SalPrivacyCritical=0x10,
	SalPrivacyDefault=0x8000
jehan's avatar
jehan committed
762
763
764
765
766
767
768
769
} SalPrivacy;
typedef  unsigned int SalPrivacyMask;

const char* sal_privacy_to_string(SalPrivacy  privacy);
void sal_op_set_privacy(SalOp* op,SalPrivacy privacy);
SalPrivacy sal_op_get_privacy(const SalOp* op);


770

771
772
#define payload_type_set_number(pt,n)		(pt)->user_data=(void*)((intptr_t)n);
#define payload_type_get_number(pt)		((int)(intptr_t)(pt)->user_data)
773

774
775
776
/*misc*/
void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen);

777
778
typedef void (*SalResolverCallback)(void *data, const char *name, struct addrinfo *ai_list);

Simon Morlat's avatar
Simon Morlat committed
779
780
781
782
typedef struct SalResolverContext SalResolverContext;

SalResolverContext * sal_resolve_a(Sal* sal, const char *name, int port, int family, SalResolverCallback cb, void *data);
//void sal_resolve_cancel(Sal *sal, SalResolverContext *ctx);
783
784
785
786

SalCustomHeader *sal_custom_header_append(SalCustomHeader *ch, const char *name, const char *value);
const char *sal_custom_header_find(const SalCustomHeader *ch, const char *name);
void sal_custom_header_free(SalCustomHeader *ch);
Simon Morlat's avatar
Simon Morlat committed
787
SalCustomHeader *sal_custom_header_clone(const SalCustomHeader *ch);
Simon Morlat's avatar
Simon Morlat committed
788
789
790
791

const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op);

void sal_op_set_sent_custom_header(SalOp *op, SalCustomHeader* ch);
792

793
794
795
796
797
798

SalCustomSdpAttribute * sal_custom_sdp_attribute_append(SalCustomSdpAttribute *csa, const char *name, const char *value);
const char * sal_custom_sdp_attribute_find(const SalCustomSdpAttribute *csa, const char *name);
void sal_custom_sdp_attribute_free(SalCustomSdpAttribute *csa);
SalCustomSdpAttribute * sal_custom_sdp_attribute_clone(const SalCustomSdpAttribute *csa);

799
/** deprecated. use sal_set_log_level instead **/
800
void sal_enable_log(void);
801
/** deprecated. use sal_set_log_level instead **/
802
void sal_disable_log(void);
803
void sal_set_log_level(OrtpLogLevel level);
Simon Morlat's avatar
Simon Morlat committed
804
805
806

/*internal API */
void __sal_op_init(SalOp *b, Sal *sal);
807
void __sal_op_set_network_origin(SalOp *op, const char *origin /*a sip uri*/);
jehan's avatar
jehan committed
808
void __sal_op_set_network_origin_address(SalOp *op, SalAddress *origin);
809
void __sal_op_set_remote_contact(SalOp *op, const char *ct);
Simon Morlat's avatar
Simon Morlat committed
810
811
void __sal_op_free(SalOp *b);

812
813
/*test api*/
/*0 for no error*/
814
LINPHONE_PUBLIC	void sal_set_send_error(Sal *sal,int value);
jehan's avatar
jehan committed
815
/*1 for no error*/
816
LINPHONE_PUBLIC	void sal_set_recv_error(Sal *sal,int value);
817
818
819
820

/*always answer 480 if value=true*/
LINPHONE_PUBLIC	void sal_enable_unconditional_answer(Sal *sal,int value);

821
822
823
824
825
LINPHONE_PUBLIC bool_t sal_pending_trans_checking_enabled(const Sal *sal) ;
LINPHONE_PUBLIC int sal_enable_pending_trans_checking(Sal *sal, bool_t value) ;



jehan's avatar
jehan committed
826
827
828
/*refresher retry after value in ms*/
LINPHONE_PUBLIC	void sal_set_refresher_retry_after(Sal *sal,int value);
LINPHONE_PUBLIC	int sal_get_refresher_retry_after(const Sal *sal);
jehan's avatar
jehan committed
829
830
831
/*enable contact fixing*/
void sal_nat_helper_enable(Sal *sal,bool_t enable);
bool_t sal_nat_helper_enabled(Sal *sal);
jehan's avatar
jehan committed
832

Sylvain Berfini's avatar
Sylvain Berfini committed
833
LINPHONE_PUBLIC	void sal_set_dns_timeout(Sal* sal,int timeout);
834
LINPHONE_PUBLIC int sal_get_dns_timeout(const Sal* sal);
835
836
LINPHONE_PUBLIC	void sal_set_transport_timeout(Sal* sal,int timeout);
LINPHONE_PUBLIC int sal_get_transport_timeout(const Sal* sal);
837
838
LINPHONE_PUBLIC void sal_enable_dns_srv(Sal *sal, bool_t enable);
LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal);
839
840
LINPHONE_PUBLIC void sal_set_dns_user_hosts_file(Sal *sal, const char *hosts_file);
LINPHONE_PUBLIC const char *sal_get_dns_user_hosts_file(const Sal *sal);
841
unsigned int sal_get_random(void);
842
LINPHONE_PUBLIC char *sal_get_random_token(int size);
843
unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
844
845