sal.h 34.1 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 SalBodyHandler;

typedef struct SalBodyHandler SalBodyHandler;

62
63
64
65
struct SalCustomHeader;

typedef struct SalCustomHeader SalCustomHeader;

66
67
68
69
struct SalCustomSdpAttribute;

typedef struct SalCustomSdpAttribute SalCustomSdpAttribute;

70
71
struct addrinfo;

72
73
74
75
typedef enum {
	SalTransportUDP, /*UDP*/
	SalTransportTCP, /*TCP*/
	SalTransportTLS, /*TLS*/
76
	SalTransportDTLS, /*DTLS*/
77
78
}SalTransport;

jehan's avatar
jehan committed
79
80
81
82
83
84
85
86
#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*/
87
#define SAL_MEDIA_DESCRIPTION_ICE_RESTART_DETECTED			(1<<7)
jehan's avatar
jehan committed
88
89


90

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

107
SalTransport sal_address_get_transport(const SalAddress* addr);
108
const char* sal_address_get_transport_name(const SalAddress* addr);
jehan's avatar
jehan committed
109

110
111
112
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);
113
void sal_address_set_port(SalAddress *uri, int port);
114
115
116
117
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);
118
119
void sal_address_set_param(SalAddress *u,const char* name,const char* value);
void sal_address_set_transport(SalAddress* addr,SalTransport transport);
120
void sal_address_set_transport_name(SalAddress* addr,const char* transport);
121
122
void sal_address_set_params(SalAddress *addr, const char *params);
void sal_address_set_uri_params(SalAddress *addr, const char *params);
123
bool_t sal_address_is_ipv6(const SalAddress *addr);
124
bool_t sal_address_is_sip(const SalAddress *addr);
125
126
127
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
128

129
LINPHONE_PUBLIC Sal * sal_init(void);
Ghislain MARY's avatar
Ghislain MARY committed
130
LINPHONE_PUBLIC void sal_uninit(Sal* sal);
Simon Morlat's avatar
Simon Morlat committed
131
132
void sal_set_user_pointer(Sal *sal, void *user_data);
void *sal_get_user_pointer(const Sal *sal);
133
134
135


typedef enum {
136
137
	SalAudio,
	SalVideo,
138
	SalText,
139
	SalOther
140
} SalStreamType;
jehan's avatar
jehan committed
141
const char* sal_stream_type_to_string(SalStreamType type);
142

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

Simon Morlat's avatar
Simon Morlat committed
154
155
156
157
158
159
typedef enum{
	SalStreamSendRecv,
	SalStreamSendOnly,
	SalStreamRecvOnly,
	SalStreamInactive
}SalStreamDir;
jehan's avatar
jehan committed
160
const char* sal_stream_dir_to_string(SalStreamDir type);
Simon Morlat's avatar
Simon Morlat committed
161

jehan's avatar
jehan committed
162

163
164
#define SAL_ENDPOINT_CANDIDATE_MAX 2

165
166
167
168
169
170
171
172
173
174
175
#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;
176
	int port;
177
178
	int rport;
} SalIceCandidate;
179

180
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES 20
181
182
183
184
185
186
187

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

#define SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES 2
188

189
190
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN 256
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256
191

192
/*sufficient for 256bit keys encoded in base 64*/
193
#define SAL_SRTP_KEY_SIZE 128
194

195
196
typedef struct SalSrtpCryptoAlgo {
	unsigned int tag;
jehan's avatar
jehan committed
197
	MSCryptoSuite algo;
198
	char master_key[SAL_SRTP_KEY_SIZE];
199
200
201
202
} SalSrtpCryptoAlgo;

#define SAL_CRYPTO_ALGO_MAX 4

johan's avatar
johan committed
203
204
205
206
207
208
209
typedef enum {
	SalDtlsRoleInvalid,
	SalDtlsRoleIsServer,
	SalDtlsRoleIsClient,
	SalDtlsRoleUnset
} SalDtlsRole;

jehan's avatar
jehan committed
210
typedef enum {
211
212
213
	SalMulticastInactive=0,
	SalMulticastSender,
	SalMulticastReceiver,
jehan's avatar
jehan committed
214
215
216
	SalMulticastSenderReceiver
} SalMulticastRole;

217
218
219
220
221
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
222

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

260
261
262
263
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
264

265
typedef struct SalMediaDescription{
266
	int refcount;
267
	char name[64];
268
269
	char addr[64];
	char username[64];
270
	int nb_streams;
271
	int bandwidth;
272
273
	unsigned int session_ver;
	unsigned int session_id;
274
	SalStreamDir dir;
Simon Morlat's avatar
Simon Morlat committed
275
	SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
276
	SalCustomSdpAttribute *custom_sdp_attributes;
277
	OrtpRtcpXrConfiguration rtcp_xr;
278
279
280
281
	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;
282
	bool_t pad[2];
283
284
} SalMediaDescription;

285
286
287
288
289
typedef struct SalMessage{
	const char *from;
	const char *text;
	const char *url;
	const char *message_id;
290
	const char *content_type;
291
	time_t time;
292
293
}SalMessage;

294
295
296
297
298
typedef struct SalIsComposing {
	const char *from;
	const char *text;
} SalIsComposing;

299
300
#define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5

301
SalMediaDescription *sal_media_description_new(void);
302
SalMediaDescription * sal_media_description_ref(SalMediaDescription *md);
303
void sal_media_description_unref(SalMediaDescription *md);
Simon Morlat's avatar
Simon Morlat committed
304
bool_t sal_media_description_empty(const SalMediaDescription *md);
305
int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
306
char * sal_media_description_print_differences(int result);
Simon Morlat's avatar
Simon Morlat committed
307
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
308
LINPHONE_PUBLIC SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type);
309
310
311
312
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
313
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir);
314
315
316
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
317
bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd);
318
319
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
320
bool_t sal_media_description_has_dtls(const SalMediaDescription *md);
321
int sal_media_description_get_nb_active_streams(const SalMediaDescription *md);
Simon Morlat's avatar
Simon Morlat committed
322

323

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

349

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

jehan's avatar
jehan committed
377
378
const char* sal_reason_to_string(const SalReason reason);

379
380
381
382
383
384
385
386
typedef struct SalErrorInfo{
	SalReason reason;
	char *status_string;
	int protocol_code;
	char *warnings;
	char *full_string; /*concatenation of status_string + warnings*/
}SalErrorInfo;

387
388
389
390
391
392
393
394
395
396
397
typedef enum SalPresenceStatus{
	SalPresenceOffline,
	SalPresenceOnline,
	SalPresenceBusy,
	SalPresenceBerightback,
	SalPresenceAway,
	SalPresenceOnthephone,
	SalPresenceOuttolunch,
	SalPresenceDonotdisturb,
	SalPresenceMoved,
	SalPresenceAltService,
398
	SalPresenceOnVacation
399
400
}SalPresenceStatus;

401
402
403
struct _SalPresenceModel;
typedef struct _SalPresenceModel SalPresenceModel;

jehan's avatar
jehan committed
404
405
const char* sal_presence_status_to_string(const SalPresenceStatus status);

406
407
408
409
410
411
412
typedef enum SalReferStatus{
	SalReferTrying,
	SalReferSuccess,
	SalReferFailed
}SalReferStatus;

typedef enum SalSubscribeStatus{
413
414
	SalSubscribeNone,
	SalSubscribePending,
415
416
	SalSubscribeActive,
	SalSubscribeTerminated
417
}SalSubscribeStatus;
418

419
420
421
422
423
typedef enum SalTextDeliveryStatus{
	SalTextDeliveryInProgress,
	SalTextDeliveryDone,
	SalTextDeliveryFailed
}SalTextDeliveryStatus;
424

425
426
427
/**
 * auth event mode
 * */
jehan's avatar
jehan committed
428
typedef enum SalAuthMode { /*this enum must be same as belle_sip_auth_mode_t*/
429
430
431
432
433
434
435
436
437
438
439
440
	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
441
typedef enum SalCertificateRawFormat {/*this enum must be same as belle_sip_certificate_raw_format_t*/
442
443
444
445
446
447
	SAL_CERTIFICATE_RAW_FORMAT_PEM, /** PEM format*/
	SAL_CERTIFICATE_RAW_FORMAT_DER /** ASN.1 raw format*/
}SalCertificateRawFormat;



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

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


496

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

jehan's avatar
jehan committed
532

533

534
SalAuthInfo* sal_auth_info_new(void);
jehan's avatar
jehan committed
535
SalAuthInfo* sal_auth_info_clone(const SalAuthInfo* auth_info);
536
void sal_auth_info_delete(SalAuthInfo* auth_info);
537
LINPHONE_PUBLIC int sal_auth_compute_ha1(const char* userid,const char* realm,const char* password, char ha1[33]);
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
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
557
558
559
560
561
562
563
564
565
566
/**
 * 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
567
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
568

569
570
571
572
void sal_certificates_chain_delete(SalCertificatesChain *chain);
void sal_signing_key_delete(SalSigningKey *key);


jehan's avatar
jehan committed
573

Simon Morlat's avatar
Simon Morlat committed
574
void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs);
575
int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_tunneled);
576
int sal_get_listening_port(Sal *ctx, SalTransport tr);
577
int sal_unlisten_ports(Sal *ctx);
Ghislain MARY's avatar
Ghislain MARY committed
578
LINPHONE_PUBLIC int sal_transport_available(Sal *ctx, SalTransport t);
579
void sal_set_dscp(Sal *ctx, int dscp);
580
581
582
583
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);
584
int sal_reset_transports(Sal *ctx);
585
ortp_socket_t sal_get_socket(Sal *ctx);
586
void sal_set_user_agent(Sal *ctx, const char *user_agent);
587
const char* sal_get_user_agent(Sal *ctx);
588
void sal_append_stack_string_to_user_agent(Sal *ctx);
589
590
/*keepalive period in ms*/
void sal_set_keepalive_period(Sal *ctx,unsigned int value);
591
void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled);
592
int sal_set_tunnel(Sal *ctx, void *tunnelclient);
593
594
595
/*Default value is true*/
void sal_enable_sip_update_method(Sal *ctx,bool_t value);

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

Simon Morlat's avatar
Simon Morlat committed
615
int sal_iterate(Sal *sal);
616
MSList * sal_get_pending_auths(Sal *sal);
Simon Morlat's avatar
Simon Morlat committed
617
618
619
620
621

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

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

638
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info);
jehan's avatar
jehan committed
639
void sal_op_cancel_authentication(SalOp *h);
Simon Morlat's avatar
Simon Morlat committed
640
void sal_op_set_user_pointer(SalOp *h, void *up);
641
SalAuthInfo * sal_op_get_auth_requested(SalOp *h);
642
const char *sal_op_get_from(const SalOp *op);
jehan's avatar
jehan committed
643
const SalAddress *sal_op_get_from_address(const SalOp *op);
644
const char *sal_op_get_to(const SalOp *op);
jehan's avatar
jehan committed
645
const SalAddress *sal_op_get_to_address(const SalOp *op);
jehan's avatar
jehan committed
646
const SalAddress *sal_op_get_contact_address(const SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
647
const char *sal_op_get_route(const SalOp *op);
648
const MSList* sal_op_get_route_addresses(const SalOp *op);
649
const char *sal_op_get_proxy(const SalOp *op);
650
const char *sal_op_get_remote_contact(const SalOp *op);
651
const SalAddress* sal_op_get_remote_contact_address(const SalOp *op);
652
653
/*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
654
const SalAddress *sal_op_get_network_origin_address(const SalOp *op);
655
656
/*returns far-end "User-Agent" string */
const char *sal_op_get_remote_ua(const SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
657
void *sal_op_get_user_pointer(const SalOp *op);
jehan's avatar
jehan committed
658
const char* sal_op_get_call_id(const SalOp *op);
659
char* sal_op_get_dialog_id(const SalOp *op);
660
bool_t sal_op_is_forked_of(const SalOp *op1, const SalOp *op2);
661

jehan's avatar
jehan committed
662
663
664
const SalAddress* sal_op_get_service_route(const SalOp *op);
void sal_op_set_service_route(SalOp *op,const SalAddress* service_route);

665
void sal_op_set_manual_refresher_mode(SalOp *op, bool_t enabled);
666
bool_t sal_op_is_ipv6(SalOp *op);
667
668
/*returns TRUE if there is no pending request that may block a future one */
bool_t sal_op_is_idle(SalOp *op);
669

670
671
672
673
674
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
675
676
677
/*Call API*/
int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
int sal_call(SalOp *h, const char *from, const char *to);
678
int sal_call_notify_ringing(SalOp *h, bool_t early_media);
679
/*accept an incoming call or, during a call accept a reINVITE*/
680
int sal_call_accept(SalOp*h);
681
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
682
int sal_call_update(SalOp *h, const char *subject, bool_t no_user_consent);
683
SalMediaDescription * sal_call_get_remote_media_description(SalOp *h);
Simon Morlat's avatar
Simon Morlat committed
684
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
685
686
687
688
689
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);
690
691
/* 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
692
int sal_call_send_dtmf(SalOp *h, char dtmf);
693
int sal_call_terminate(SalOp *h);
694
bool_t sal_call_autoanswer_asked(SalOp *op);
695
void sal_call_send_vfu_request(SalOp *h);
696
int sal_call_is_offerer(const SalOp *h);
697
int sal_call_notify_refer_state(SalOp *h, SalOp *newcall);
698
/* Call test API */
699
700
701
702
703
704
705
706
707
708
709


/**
 * @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)
 */
710
LINPHONE_PUBLIC void sal_default_set_sdp_handling(Sal* h, SalOpSDPHandling handling_method) ;
711
/* Second version: for a specific call*/
712
LINPHONE_PUBLIC void sal_call_set_sdp_handling(SalOp *h, SalOpSDPHandling handling) ;
713

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

Simon Morlat's avatar
Simon Morlat committed
720
/*Messaging */
Simon Morlat's avatar
Simon Morlat committed
721
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
722
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
723
int sal_message_reply(SalOp *op, SalReason reason);
Simon Morlat's avatar
Simon Morlat committed
724
725

/*presence Subscribe/notify*/
Simon Morlat's avatar
Simon Morlat committed
726
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires);
727
int sal_notify_presence(SalOp *op, SalPresenceModel *presence);
728
int sal_notify_presence_close(SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
729

730
/*presence publish */
731
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence);
732

733
734
735
736

/*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
737
/*info messages*/
738
int sal_send_info(SalOp *op, const char *from, const char *to, const SalBodyHandler *body);
Simon Morlat's avatar
Simon Morlat committed
739

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

jehan's avatar
jehan committed
749
750
/*privacy, must be in sync with LinphonePrivacyMask*/
typedef enum _SalPrivacy {
Simon Morlat's avatar
Simon Morlat committed
751
	SalPrivacyNone=0x0,
jehan's avatar
jehan committed
752
753
754
755
	SalPrivacyUser=0x1,
	SalPrivacyHeader=0x2,
	SalPrivacySession=0x4,
	SalPrivacyId=0x8,
Simon Morlat's avatar
Simon Morlat committed
756
757
	SalPrivacyCritical=0x10,
	SalPrivacyDefault=0x8000
jehan's avatar
jehan committed
758
759
760
761
762
763
764
765
} 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);


766

767
768
#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)
769

770
771
772
/*misc*/
void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen);

773
774
typedef void (*SalResolverCallback)(void *data, const char *name, struct addrinfo *ai_list);

Simon Morlat's avatar
Simon Morlat committed
775
776
777
778
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);
779
780
781
782

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
783
SalCustomHeader *sal_custom_header_clone(const SalCustomHeader *ch);
Simon Morlat's avatar
Simon Morlat committed
784
785
786
787

const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op);

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

789
790
791
792
793
794

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);

795
/** deprecated. use sal_set_log_level instead **/
796
void sal_enable_log(void);
797
/** deprecated. use sal_set_log_level instead **/
798
void sal_disable_log(void);
799
void sal_set_log_level(OrtpLogLevel level);
Simon Morlat's avatar
Simon Morlat committed
800
801
802

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

808
809
/*test api*/
/*0 for no error*/
810
LINPHONE_PUBLIC	void sal_set_send_error(Sal *sal,int value);
jehan's avatar
jehan committed
811
/*1 for no error*/
812
LINPHONE_PUBLIC	void sal_set_recv_error(Sal *sal,int value);
813
814
815
816

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

817
818
819
820
821
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
822
823
824
/*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
825
826
827
/*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
828

Sylvain Berfini's avatar
Sylvain Berfini committed
829
LINPHONE_PUBLIC	void sal_set_dns_timeout(Sal* sal,int timeout);
830
LINPHONE_PUBLIC int sal_get_dns_timeout(const Sal* sal);
831
832
LINPHONE_PUBLIC	void sal_set_transport_timeout(Sal* sal,int timeout);
LINPHONE_PUBLIC int sal_get_transport_timeout(const Sal* sal);
833
834
LINPHONE_PUBLIC void sal_enable_dns_srv(Sal *sal, bool_t enable);
LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal);
835
836
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);