sal.h 32.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
struct addrinfo;

64
65
66
67
typedef enum {
	SalTransportUDP, /*UDP*/
	SalTransportTCP, /*TCP*/
	SalTransportTLS, /*TLS*/
68
	SalTransportDTLS, /*DTLS*/
69
70
}SalTransport;

jehan's avatar
jehan committed
71
72
73
74
75
76
77
78
79
80
#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*/


81

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

98
SalTransport sal_address_get_transport(const SalAddress* addr);
99
const char* sal_address_get_transport_name(const SalAddress* addr);
jehan's avatar
jehan committed
100

101
102
103
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);
104
void sal_address_set_port(SalAddress *uri, int port);
105
106
107
108
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);
109
110
void sal_address_set_param(SalAddress *u,const char* name,const char* value);
void sal_address_set_transport(SalAddress* addr,SalTransport transport);
111
void sal_address_set_transport_name(SalAddress* addr,const char* transport);
112
113
void sal_address_set_params(SalAddress *addr, const char *params);
void sal_address_set_uri_params(SalAddress *addr, const char *params);
114
bool_t sal_address_is_ipv6(const SalAddress *addr);
115
bool_t sal_address_is_sip(const SalAddress *addr);
116
117
118
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
119

Ghislain MARY's avatar
Ghislain MARY committed
120
121
LINPHONE_PUBLIC Sal * sal_init();
LINPHONE_PUBLIC void sal_uninit(Sal* sal);
Simon Morlat's avatar
Simon Morlat committed
122
123
void sal_set_user_pointer(Sal *sal, void *user_data);
void *sal_get_user_pointer(const Sal *sal);
124
125
126


typedef enum {
127
128
129
	SalAudio,
	SalVideo,
	SalOther
130
} SalStreamType;
jehan's avatar
jehan committed
131
const char* sal_stream_type_to_string(SalStreamType type);
132

Simon Morlat's avatar
Simon Morlat committed
133
typedef enum{
134
	SalProtoRtpAvp,
135
	SalProtoRtpSavp,
136
137
	SalProtoRtpAvpf,
	SalProtoRtpSavpf,
johan's avatar
johan committed
138
139
	SalProtoUdpTlsRtpSavp,
	SalProtoUdpTlsRtpSavpf,
140
	SalProtoOther
Simon Morlat's avatar
Simon Morlat committed
141
}SalMediaProto;
jehan's avatar
jehan committed
142
const char* sal_media_proto_to_string(SalMediaProto type);
Simon Morlat's avatar
Simon Morlat committed
143

Simon Morlat's avatar
Simon Morlat committed
144
145
146
147
148
149
typedef enum{
	SalStreamSendRecv,
	SalStreamSendOnly,
	SalStreamRecvOnly,
	SalStreamInactive
}SalStreamDir;
jehan's avatar
jehan committed
150
const char* sal_stream_dir_to_string(SalStreamDir type);
Simon Morlat's avatar
Simon Morlat committed
151

jehan's avatar
jehan committed
152

153
154
#define SAL_ENDPOINT_CANDIDATE_MAX 2

155
156
157
158
159
160
161
162
163
164
165
#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;
166
	int port;
167
168
	int rport;
} SalIceCandidate;
169

170
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_CANDIDATES 20
171
172
173
174
175
176
177

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

#define SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES 2
178

179
180
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN 256
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256
181

182
/*sufficient for 256bit keys encoded in base 64*/
183
#define SAL_SRTP_KEY_SIZE 128
184

185
186
typedef struct SalSrtpCryptoAlgo {
	unsigned int tag;
jehan's avatar
jehan committed
187
	MSCryptoSuite algo;
188
	char master_key[SAL_SRTP_KEY_SIZE];
189
190
191
192
} SalSrtpCryptoAlgo;

#define SAL_CRYPTO_ALGO_MAX 4

johan's avatar
johan committed
193
194
195
196
197
198
199
typedef enum {
	SalDtlsRoleInvalid,
	SalDtlsRoleIsServer,
	SalDtlsRoleIsClient,
	SalDtlsRoleUnset
} SalDtlsRole;

jehan's avatar
jehan committed
200
typedef enum {
201
202
203
	SalMulticastInactive=0,
	SalMulticastSender,
	SalMulticastReceiver,
jehan's avatar
jehan committed
204
205
206
	SalMulticastSenderReceiver
} SalMulticastRole;

207
208
209
210
211
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
212

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

247
248
249
250
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
251

252
typedef struct SalMediaDescription{
253
	int refcount;
254
	char name[64];
255
256
	char addr[64];
	char username[64];
257
	int nb_streams;
258
	int bandwidth;
259
260
	unsigned int session_ver;
	unsigned int session_id;
261
	SalStreamDir dir;
Simon Morlat's avatar
Simon Morlat committed
262
	SalStreamDescription streams[SAL_MEDIA_DESCRIPTION_MAX_STREAMS];
263
	OrtpRtcpXrConfiguration rtcp_xr;
264
265
266
267
	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;
268
	bool_t pad[2];
269
270
} SalMediaDescription;

271
272
273
274
275
typedef struct SalMessage{
	const char *from;
	const char *text;
	const char *url;
	const char *message_id;
276
	const char *content_type;
277
	time_t time;
278
279
}SalMessage;

280
281
282
283
284
typedef struct SalIsComposing {
	const char *from;
	const char *text;
} SalIsComposing;

285
286
#define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5

Simon Morlat's avatar
Simon Morlat committed
287
SalMediaDescription *sal_media_description_new();
288
SalMediaDescription * sal_media_description_ref(SalMediaDescription *md);
289
void sal_media_description_unref(SalMediaDescription *md);
Simon Morlat's avatar
Simon Morlat committed
290
bool_t sal_media_description_empty(const SalMediaDescription *md);
291
int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaDescription *md2);
Simon Morlat's avatar
Simon Morlat committed
292
bool_t sal_media_description_has_dir(const SalMediaDescription *md, SalStreamDir dir);
293
LINPHONE_PUBLIC SalStreamDescription *sal_media_description_find_stream(SalMediaDescription *md, SalMediaProto proto, SalStreamType type);
294
295
296
297
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
298
void sal_media_description_set_dir(SalMediaDescription *md, SalStreamDir stream_dir);
299
300
301
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
302
bool_t sal_stream_description_has_dtls(const SalStreamDescription *sd);
303
304
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
305
bool_t sal_media_description_has_dtls(const SalMediaDescription *md);
306
int sal_media_description_get_nb_active_streams(const SalMediaDescription *md);
Simon Morlat's avatar
Simon Morlat committed
307

308

Simon Morlat's avatar
Simon Morlat committed
309
310
311
/*this structure must be at the first byte of the SalOp structure defined by implementors*/
typedef struct SalOpBase{
	Sal *root;
312
	char *route; /*or request-uri for REGISTER*/
313
	MSList* route_addresses; /*list of SalAddress* */
jehan's avatar
jehan committed
314
	SalAddress* contact_address;
Simon Morlat's avatar
Simon Morlat committed
315
	char *from;
jehan's avatar
jehan committed
316
	SalAddress* from_address;
Simon Morlat's avatar
Simon Morlat committed
317
	char *to;
jehan's avatar
jehan committed
318
	SalAddress* to_address;
319
	char *origin;
jehan's avatar
jehan committed
320
	SalAddress* origin_address;
321
	char *remote_ua;
322
323
	SalAddress* remote_contact_address;
	char *remote_contact;
Simon Morlat's avatar
Simon Morlat committed
324
325
	SalMediaDescription *local_media;
	SalMediaDescription *remote_media;
Simon Morlat's avatar
Simon Morlat committed
326
	void *user_pointer;
jehan's avatar
jehan committed
327
	const char* call_id;
328
	char* realm;
jehan's avatar
jehan committed
329
	SalAddress* service_route; /*as defined by rfc3608, might be a list*/
Simon Morlat's avatar
Simon Morlat committed
330
331
	SalCustomHeader *sent_custom_headers;
	SalCustomHeader *recv_custom_headers;
Simon Morlat's avatar
Simon Morlat committed
332
333
} SalOpBase;

334

335
typedef enum SalReason{
336
	SalReasonNone, /*no error, please leave first so that it takes 0 value*/
337
338
339
340
	SalReasonDeclined,
	SalReasonBusy,
	SalReasonRedirect,
	SalReasonTemporarilyUnavailable,
341
	SalReasonRequestTimeout,
342
343
	SalReasonNotFound,
	SalReasonDoNotDisturb,
344
	SalReasonUnsupportedContent,
345
	SalReasonForbidden,
346
	SalReasonUnknown,
347
	SalReasonServiceUnavailable,
jehan's avatar
jehan committed
348
	SalReasonRequestPending,
349
	SalReasonUnauthorized,
350
	SalReasonNotAcceptable,
351
352
353
354
355
356
	SalReasonNoMatch, /*equivalent to 481 Transaction/Call leg does not exist*/
	SalReasonMovedPermanently,
	SalReasonGone,
	SalReasonAddressIncomplete,
	SalReasonNotImplemented,
	SalReasonBadGateway,
357
	SalReasonServerTimeout,
358
359
	SalReasonIOError,
	SalReasonInternalError
360
361
}SalReason;

jehan's avatar
jehan committed
362
363
const char* sal_reason_to_string(const SalReason reason);

364
365
366
367
368
369
370
371
typedef struct SalErrorInfo{
	SalReason reason;
	char *status_string;
	int protocol_code;
	char *warnings;
	char *full_string; /*concatenation of status_string + warnings*/
}SalErrorInfo;

372
373
374
375
376
377
378
379
380
381
382
typedef enum SalPresenceStatus{
	SalPresenceOffline,
	SalPresenceOnline,
	SalPresenceBusy,
	SalPresenceBerightback,
	SalPresenceAway,
	SalPresenceOnthephone,
	SalPresenceOuttolunch,
	SalPresenceDonotdisturb,
	SalPresenceMoved,
	SalPresenceAltService,
383
	SalPresenceOnVacation
384
385
}SalPresenceStatus;

386
387
388
struct _SalPresenceModel;
typedef struct _SalPresenceModel SalPresenceModel;

jehan's avatar
jehan committed
389
390
const char* sal_presence_status_to_string(const SalPresenceStatus status);

391
392
393
394
395
396
397
typedef enum SalReferStatus{
	SalReferTrying,
	SalReferSuccess,
	SalReferFailed
}SalReferStatus;

typedef enum SalSubscribeStatus{
398
399
	SalSubscribeNone,
	SalSubscribePending,
400
401
	SalSubscribeActive,
	SalSubscribeTerminated
402
}SalSubscribeStatus;
403

404
405
406
407
408
typedef enum SalTextDeliveryStatus{
	SalTextDeliveryInProgress,
	SalTextDeliveryDone,
	SalTextDeliveryFailed
}SalTextDeliveryStatus;
409

410
411
412
/**
 * auth event mode
 * */
jehan's avatar
jehan committed
413
typedef enum SalAuthMode { /*this enum must be same as belle_sip_auth_mode_t*/
414
415
416
417
418
419
420
421
422
423
424
425
	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
426
typedef enum SalCertificateRawFormat {/*this enum must be same as belle_sip_certificate_raw_format_t*/
427
428
429
430
431
432
	SAL_CERTIFICATE_RAW_FORMAT_PEM, /** PEM format*/
	SAL_CERTIFICATE_RAW_FORMAT_DER /** ASN.1 raw format*/
}SalCertificateRawFormat;



jehan's avatar
jehan committed
433
434
435
436
437
typedef struct SalAuthInfo{
	char *username;
	char *userid;
	char *password;
	char *realm;
438
	char *domain;
jehan's avatar
jehan committed
439
	char *ha1;
440
441
442
	SalAuthMode mode;
	SalSigningKey *key;
	SalCertificatesChain *certificates;
jehan's avatar
jehan committed
443
444
}SalAuthInfo;

Simon Morlat's avatar
Simon Morlat committed
445
446
447
448
449
typedef struct SalBody{
	const char *type;
	const char *subtype;
	const void *data;
	size_t size;
450
	const char *encoding;
Simon Morlat's avatar
Simon Morlat committed
451
452
}SalBody;

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


489

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

jehan's avatar
jehan committed
525

526

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

562
563
564
565
void sal_certificates_chain_delete(SalCertificatesChain *chain);
void sal_signing_key_delete(SalSigningKey *key);


jehan's avatar
jehan committed
566

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

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

Simon Morlat's avatar
Simon Morlat committed
608
int sal_iterate(Sal *sal);
609
MSList * sal_get_pending_auths(Sal *sal);
Simon Morlat's avatar
Simon Morlat committed
610
611
612
613
614

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

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

631
void sal_op_authenticate(SalOp *h, const SalAuthInfo *info);
jehan's avatar
jehan committed
632
void sal_op_cancel_authentication(SalOp *h);
Simon Morlat's avatar
Simon Morlat committed
633
void sal_op_set_user_pointer(SalOp *h, void *up);
634
SalAuthInfo * sal_op_get_auth_requested(SalOp *h);
635
const char *sal_op_get_from(const SalOp *op);
jehan's avatar
jehan committed
636
const SalAddress *sal_op_get_from_address(const SalOp *op);
637
const char *sal_op_get_to(const SalOp *op);
jehan's avatar
jehan committed
638
const SalAddress *sal_op_get_to_address(const SalOp *op);
jehan's avatar
jehan committed
639
const SalAddress *sal_op_get_contact_address(const SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
640
const char *sal_op_get_route(const SalOp *op);
641
const MSList* sal_op_get_route_addresses(const SalOp *op);
642
const char *sal_op_get_proxy(const SalOp *op);
643
const char *sal_op_get_remote_contact(const SalOp *op);
644
const SalAddress* sal_op_get_remote_contact_address(const SalOp *op);
645
646
/*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
647
const SalAddress *sal_op_get_network_origin_address(const SalOp *op);
648
649
/*returns far-end "User-Agent" string */
const char *sal_op_get_remote_ua(const SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
650
void *sal_op_get_user_pointer(const SalOp *op);
jehan's avatar
jehan committed
651
const char* sal_op_get_call_id(const SalOp *op);
652
char* sal_op_get_dialog_id(const SalOp *op);
653

jehan's avatar
jehan committed
654
655
656
const SalAddress* sal_op_get_service_route(const SalOp *op);
void sal_op_set_service_route(SalOp *op,const SalAddress* service_route);

657
void sal_op_set_manual_refresher_mode(SalOp *op, bool_t enabled);
658
bool_t sal_op_is_ipv6(SalOp *op);
659
660
/*returns TRUE if there is no pending request that may block a future one */
bool_t sal_op_is_idle(SalOp *op);
661

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


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

Simon Morlat's avatar
Simon Morlat committed
706
/*Registration*/
707
int sal_register(SalOp *op, const char *proxy, const char *from, int expires,SalAddress* old_contact);
708
/*refresh a register, -1 mean use the last known value*/
709
int sal_register_refresh(SalOp *op, int expires);
710
int sal_unregister(SalOp *h);
711

Simon Morlat's avatar
Simon Morlat committed
712
/*Messaging */
Simon Morlat's avatar
Simon Morlat committed
713
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
714
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
715
int sal_message_reply(SalOp *op, SalReason reason);
Simon Morlat's avatar
Simon Morlat committed
716
717

/*presence Subscribe/notify*/
Simon Morlat's avatar
Simon Morlat committed
718
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires);
719
int sal_notify_presence(SalOp *op, SalPresenceModel *presence);
720
int sal_notify_presence_close(SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
721

722
/*presence publish */
723
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence);
724

725
726
727
728

/*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
729
730
731
/*info messages*/
int sal_send_info(SalOp *op, const char *from, const char *to, const SalBody *body);

732
733
734
735
736
737
738
739
/*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
740

jehan's avatar
jehan committed
741
742
/*privacy, must be in sync with LinphonePrivacyMask*/
typedef enum _SalPrivacy {
Simon Morlat's avatar
Simon Morlat committed
743
	SalPrivacyNone=0x0,
jehan's avatar
jehan committed
744
745
746
747
	SalPrivacyUser=0x1,
	SalPrivacyHeader=0x2,
	SalPrivacySession=0x4,
	SalPrivacyId=0x8,
Simon Morlat's avatar
Simon Morlat committed
748
749
	SalPrivacyCritical=0x10,
	SalPrivacyDefault=0x8000
jehan's avatar
jehan committed
750
751
752
753
754
755
756
757
} 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);


758

759
#define payload_type_set_number(pt,n)		(pt)->user_data=(void*)((long)n);
760
761
#define payload_type_get_number(pt)		((int)(long)(pt)->user_data)

762
763
764
/*misc*/
void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen);

765
766
typedef void (*SalResolverCallback)(void *data, const char *name, struct addrinfo *ai_list);

Simon Morlat's avatar
Simon Morlat committed
767
768
769
770
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);
771
772
773
774

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
775
SalCustomHeader *sal_custom_header_clone(const SalCustomHeader *ch);
Simon Morlat's avatar
Simon Morlat committed
776
777
778
779

const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op);

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

781
782
783
784
785
/** deprecated. use sal_set_log_level instead **/
void sal_enable_log();
/** deprecated. use sal_set_log_level instead **/
void sal_disable_log();
void sal_set_log_level(OrtpLogLevel level);
Simon Morlat's avatar
Simon Morlat committed
786
787
788

/*internal API */
void __sal_op_init(SalOp *b, Sal *sal);
789
void __sal_op_set_network_origin(SalOp *op, const char *origin /*a sip uri*/);
jehan's avatar
jehan committed
790
void __sal_op_set_network_origin_address(SalOp *op, SalAddress *origin);
791
void __sal_op_set_remote_contact(SalOp *op, const char *ct);
Simon Morlat's avatar
Simon Morlat committed
792
793
void __sal_op_free(SalOp *b);

794
795
/*test api*/
/*0 for no error*/
796
LINPHONE_PUBLIC	void sal_set_send_error(Sal *sal,int value);
jehan's avatar
jehan committed
797
/*1 for no error*/
798
LINPHONE_PUBLIC	void sal_set_recv_error(Sal *sal,int value);
799
800
801
802

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

803
804
805
806
807
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
808
809
810
/*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
811
812
813
/*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
814

Sylvain Berfini's avatar
Sylvain Berfini committed
815
LINPHONE_PUBLIC	void sal_set_dns_timeout(Sal* sal,int timeout);
816
LINPHONE_PUBLIC int sal_get_dns_timeout(const Sal* sal);
817
818
LINPHONE_PUBLIC	void sal_set_transport_timeout(Sal* sal,int timeout);
LINPHONE_PUBLIC int sal_get_transport_timeout(const Sal* sal);
819
820
LINPHONE_PUBLIC void sal_enable_dns_srv(Sal *sal, bool_t enable);
LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal);
821
822
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);
823
unsigned int sal_get_random(void);
824
LINPHONE_PUBLIC char *sal_get_random_token(int size);
825
unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
826
827
belle_sip_source_t * sal_create_timer(Sal *sal, belle_sip_source_func_t func, void *data, unsigned int timeout_value_ms, const char* timer_name);
void sal_cancel_timer(Sal *sal, belle_sip_source_t *timer);
828

829
830
831
832
int sal_body_has_type(const SalBody *body, const char *type, const char *subtype);
/*this function parses a document with key=value pairs separated by new lines, and extracts the value for a given key*/
int sal_lines_get_value(const char *data, const char *key, char *value, size_t value_size);

833
LINPHONE_PUBLIC belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal);
834
char* sal_op_get_public_uri(SalOp *sal);
Simon Morlat's avatar
Simon Morlat committed
835

Guillaume BIENKOWSKI's avatar
Guillaume BIENKOWSKI committed
836
unsigned long sal_begin_background_task(const char *name, void (*max_time_reached)(void *), void *data);
Simon Morlat's avatar
Simon Morlat committed
837
838
void sal_end_background_task(unsigned long id);

839
840
841
842
/*Some old equipment may not only rely on attribute sendonly/recvonly/sendrecv/inative*/
void sal_op_cnx_ip_to_0000_if_sendonly_enable(SalOp *sal,bool_t yesno);
bool_t sal_op_cnx_ip_to_0000_if_sendonly_enabled(SalOp *sal);

843
#endif
Simon Morlat's avatar
Simon Morlat committed
844
845