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

71
72
73
74
75
76
77
#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)

78
#define SAL_MEDIA_DESCRIPTION_CHANGED		(SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED |\
79
						SAL_MEDIA_DESCRIPTION_CRYPTO_KEYS_CHANGED |SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED | SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)
80

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

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

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

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


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

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

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

jehan's avatar
jehan committed
151

152
153
#define SAL_ENDPOINT_CANDIDATE_MAX 2

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

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

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

#define SAL_MEDIA_DESCRIPTION_MAX_ICE_REMOTE_CANDIDATES 2
177

178
179
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_UFRAG_LEN 256
#define SAL_MEDIA_DESCRIPTION_MAX_ICE_PWD_LEN 256
180

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

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

#define SAL_CRYPTO_ALGO_MAX 4

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

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


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

241
242
243
244
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
245

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

267
268
269
270
271
typedef struct SalMessage{
	const char *from;
	const char *text;
	const char *url;
	const char *message_id;
272
	const char *content_type;
273
	time_t time;
274
275
}SalMessage;

276
277
278
279
280
typedef struct SalIsComposing {
	const char *from;
	const char *text;
} SalIsComposing;

281
282
#define SAL_MEDIA_DESCRIPTION_MAX_MESSAGE_ATTRIBUTES 5

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

305

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

331

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

jehan's avatar
jehan committed
358
359
const char* sal_reason_to_string(const SalReason reason);

360
361
362
363
364
365
366
367
typedef struct SalErrorInfo{
	SalReason reason;
	char *status_string;
	int protocol_code;
	char *warnings;
	char *full_string; /*concatenation of status_string + warnings*/
}SalErrorInfo;

368
369
370
371
372
373
374
375
376
377
378
typedef enum SalPresenceStatus{
	SalPresenceOffline,
	SalPresenceOnline,
	SalPresenceBusy,
	SalPresenceBerightback,
	SalPresenceAway,
	SalPresenceOnthephone,
	SalPresenceOuttolunch,
	SalPresenceDonotdisturb,
	SalPresenceMoved,
	SalPresenceAltService,
379
	SalPresenceOnVacation
380
381
}SalPresenceStatus;

382
383
384
struct _SalPresenceModel;
typedef struct _SalPresenceModel SalPresenceModel;

jehan's avatar
jehan committed
385
386
const char* sal_presence_status_to_string(const SalPresenceStatus status);

387
388
389
390
391
392
393
typedef enum SalReferStatus{
	SalReferTrying,
	SalReferSuccess,
	SalReferFailed
}SalReferStatus;

typedef enum SalSubscribeStatus{
394
395
	SalSubscribeNone,
	SalSubscribePending,
396
397
	SalSubscribeActive,
	SalSubscribeTerminated
398
}SalSubscribeStatus;
399

400
401
402
403
404
typedef enum SalTextDeliveryStatus{
	SalTextDeliveryInProgress,
	SalTextDeliveryDone,
	SalTextDeliveryFailed
}SalTextDeliveryStatus;
405

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



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

Simon Morlat's avatar
Simon Morlat committed
441
442
443
444
445
typedef struct SalBody{
	const char *type;
	const char *subtype;
	const void *data;
	size_t size;
446
	const char *encoding;
Simon Morlat's avatar
Simon Morlat committed
447
448
}SalBody;

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


485

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

jehan's avatar
jehan committed
521

522

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

558
559
560
561
void sal_certificates_chain_delete(SalCertificatesChain *chain);
void sal_signing_key_delete(SalSigningKey *key);


jehan's avatar
jehan committed
562

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

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

Simon Morlat's avatar
Simon Morlat committed
604
int sal_iterate(Sal *sal);
605
MSList * sal_get_pending_auths(Sal *sal);
Simon Morlat's avatar
Simon Morlat committed
606
607
608
609
610

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

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

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

jehan's avatar
jehan committed
650
651
652
const SalAddress* sal_op_get_service_route(const SalOp *op);
void sal_op_set_service_route(SalOp *op,const SalAddress* service_route);

653
void sal_op_set_manual_refresher_mode(SalOp *op, bool_t enabled);
654
bool_t sal_op_is_ipv6(SalOp *op);
655
656
/*returns TRUE if there is no pending request that may block a future one */
bool_t sal_op_is_idle(SalOp *op);
657

658
659
660
661
662
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
663
664
665
/*Call API*/
int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
int sal_call(SalOp *h, const char *from, const char *to);
666
int sal_call_notify_ringing(SalOp *h, bool_t early_media);
667
/*accept an incoming call or, during a call accept a reINVITE*/
668
int sal_call_accept(SalOp*h);
669
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
670
int sal_call_update(SalOp *h, const char *subject, bool_t no_user_consent);
671
SalMediaDescription * sal_call_get_remote_media_description(SalOp *h);
Simon Morlat's avatar
Simon Morlat committed
672
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
673
674
675
676
677
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);
678
679
/* 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
680
int sal_call_send_dtmf(SalOp *h, char dtmf);
681
int sal_call_terminate(SalOp *h);
682
bool_t sal_call_autoanswer_asked(SalOp *op);
683
void sal_call_send_vfu_request(SalOp *h);
684
int sal_call_is_offerer(const SalOp *h);
685
int sal_call_notify_refer_state(SalOp *h, SalOp *newcall);
686
687
688
689
690
691
/* Call test API */
/*willingly fails to parse SDP from received packets (INVITE and/or ACK) if value=true */
/* First version: for all new SalOp created (eg. each incoming or outgoing call). Do not forget to reset previous value when you are done!*/
void sal_default_enable_sdp_removal(Sal* h, bool_t enable) ;
/* Second version: for a specific call*/
void sal_call_enable_sdp_removal(SalOp *h, bool_t enable) ;
692

Simon Morlat's avatar
Simon Morlat committed
693
/*Registration*/
694
int sal_register(SalOp *op, const char *proxy, const char *from, int expires);
695
/*refresh a register, -1 mean use the last known value*/
696
int sal_register_refresh(SalOp *op, int expires);
697
int sal_unregister(SalOp *h);
698

Simon Morlat's avatar
Simon Morlat committed
699
/*Messaging */
Simon Morlat's avatar
Simon Morlat committed
700
701
int sal_text_send(SalOp *op, const char *from, const char *to, const char *text);
int sal_message_send(SalOp *op, const char *from, const char *to, const char* content_type, const char *msg);
Simon Morlat's avatar
Simon Morlat committed
702
int sal_message_reply(SalOp *op, SalReason reason);
Simon Morlat's avatar
Simon Morlat committed
703
704

/*presence Subscribe/notify*/
Simon Morlat's avatar
Simon Morlat committed
705
int sal_subscribe_presence(SalOp *op, const char *from, const char *to, int expires);
706
int sal_notify_presence(SalOp *op, SalPresenceModel *presence);
707
int sal_notify_presence_close(SalOp *op);
Simon Morlat's avatar
Simon Morlat committed
708

709
/*presence publish */
710
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence);
711

712
713
714
715

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

719
720
721
722
723
724
725
726
/*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
727

jehan's avatar
jehan committed
728
729
/*privacy, must be in sync with LinphonePrivacyMask*/
typedef enum _SalPrivacy {
Simon Morlat's avatar
Simon Morlat committed
730
	SalPrivacyNone=0x0,
jehan's avatar
jehan committed
731
732
733
734
	SalPrivacyUser=0x1,
	SalPrivacyHeader=0x2,
	SalPrivacySession=0x4,
	SalPrivacyId=0x8,
Simon Morlat's avatar
Simon Morlat committed
735
736
	SalPrivacyCritical=0x10,
	SalPrivacyDefault=0x8000
jehan's avatar
jehan committed
737
738
739
740
741
742
743
744
} 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);


745

746
#define payload_type_set_number(pt,n)		(pt)->user_data=(void*)((long)n);
747
748
#define payload_type_get_number(pt)		((int)(long)(pt)->user_data)

749
750
751
/*misc*/
void sal_get_default_local_ip(Sal *sal, int address_family, char *ip, size_t iplen);

752
753
typedef void (*SalResolverCallback)(void *data, const char *name, struct addrinfo *ai_list);

Simon Morlat's avatar
Simon Morlat committed
754
755
756
757
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);
758
759
760
761

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
762
SalCustomHeader *sal_custom_header_clone(const SalCustomHeader *ch);
Simon Morlat's avatar
Simon Morlat committed
763
764
765
766

const SalCustomHeader *sal_op_get_recv_custom_header(SalOp *op);

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

jehan's avatar
jehan committed
768
769
void sal_enable_logs();
void sal_disable_logs();
Simon Morlat's avatar
Simon Morlat committed
770
771
772

/*internal API */
void __sal_op_init(SalOp *b, Sal *sal);
773
void __sal_op_set_network_origin(SalOp *op, const char *origin /*a sip uri*/);
jehan's avatar
jehan committed
774
void __sal_op_set_network_origin_address(SalOp *op, SalAddress *origin);
775
void __sal_op_set_remote_contact(SalOp *op, const char *ct);
Simon Morlat's avatar
Simon Morlat committed
776
777
void __sal_op_free(SalOp *b);

778
779
/*test api*/
/*0 for no error*/
780
LINPHONE_PUBLIC	void sal_set_send_error(Sal *sal,int value);
jehan's avatar
jehan committed
781
/*1 for no error*/
782
LINPHONE_PUBLIC	void sal_set_recv_error(Sal *sal,int value);
783
784
785
786

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

jehan's avatar
jehan committed
787
788
789
/*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
790
791
792
/*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
793

Sylvain Berfini's avatar
Sylvain Berfini committed
794
LINPHONE_PUBLIC	void sal_set_dns_timeout(Sal* sal,int timeout);
795
LINPHONE_PUBLIC int sal_get_dns_timeout(const Sal* sal);
796
797
LINPHONE_PUBLIC	void sal_set_transport_timeout(Sal* sal,int timeout);
LINPHONE_PUBLIC int sal_get_transport_timeout(const Sal* sal);
798
799
LINPHONE_PUBLIC void sal_enable_dns_srv(Sal *sal, bool_t enable);
LINPHONE_PUBLIC bool_t sal_dns_srv_enabled(const Sal *sal);
800
801
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);
802
unsigned int sal_get_random(void);
803
char *sal_get_random_token(int size);
804
unsigned char * sal_get_random_bytes(unsigned char *ret, size_t size);
805
806
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);
807

808
809
810
811
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);

812
belle_sip_stack_t *sal_get_belle_sip_stack(Sal *sal);
813
char* sal_op_get_public_uri(SalOp *sal);
814
#endif