]> sjero.net Git - linphone/blob - coreapi/sal_eXosip2.c
add get_remote_contact() api and clean java API.
[linphone] / coreapi / sal_eXosip2.c
1 /*
2 linphone
3 Copyright (C) 2010  Simon MORLAT (simon.morlat@free.fr)
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18 */
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "sal_eXosip2.h"
24 #include "offeranswer.h"
25
26 #ifdef ANDROID
27 // Necessary to make it linked
28 static void for_linker() { eXosip_transport_hook_register(NULL); }
29 #endif
30 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
31
32 static void text_received(Sal *sal, eXosip_event_t *ev);
33
34 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
35 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact);
36 static void update_contact_from_response(SalOp *op, osip_message_t *response);
37
38 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
39         void *data;
40         while(!osip_list_eol(l,0)) {
41                 data=osip_list_get(l,0);
42                 osip_list_remove(l,0);
43                 if (data) freefunc(data);
44         }
45 }
46
47 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
48         if (eXosip_guess_localip(address_family,ip,iplen)<0){
49                 /*default to something */
50                 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
51                 ms_error("Could not find default routable ip address !");
52         }
53 }
54
55
56 static SalOp * sal_find_call(Sal *sal, int cid){
57         const MSList *elem;
58         SalOp *op;
59         for(elem=sal->calls;elem!=NULL;elem=elem->next){
60                 op=(SalOp*)elem->data;
61                 if (op->cid==cid) return op;
62         }
63         return NULL;
64 }
65
66 static void sal_add_call(Sal *sal, SalOp *op){
67         sal->calls=ms_list_append(sal->calls,op);
68 }
69
70 static void sal_remove_call(Sal *sal, SalOp *op){
71         sal->calls=ms_list_remove(sal->calls, op);
72 }
73
74 static SalOp * sal_find_register(Sal *sal, int rid){
75         const MSList *elem;
76         SalOp *op;
77         for(elem=sal->registers;elem!=NULL;elem=elem->next){
78                 op=(SalOp*)elem->data;
79                 if (op->rid==rid) return op;
80         }
81         return NULL;
82 }
83
84 static void sal_add_register(Sal *sal, SalOp *op){
85         sal->registers=ms_list_append(sal->registers,op);
86 }
87
88 static void sal_remove_register(Sal *sal, int rid){
89         MSList *elem;
90         SalOp *op;
91         for(elem=sal->registers;elem!=NULL;elem=elem->next){
92                 op=(SalOp*)elem->data;
93                 if (op->rid==rid) {
94                         sal->registers=ms_list_remove_link(sal->registers,elem);
95                         return;
96                 }
97         }
98 }
99
100 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
101         const MSList *elem;
102         SalOp *op;
103         osip_call_id_t *callid=osip_message_get_call_id(message);
104         if (callid==NULL) {
105                 ms_error("There is no call-id in this message !");
106                 return NULL;
107         }
108         for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
109                 op=(SalOp*)elem->data;
110                 if (osip_call_id_match(callid,op->call_id)==0) return op;
111         }
112         return NULL;
113 }
114
115 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
116         osip_call_id_t *callid=osip_message_get_call_id(request);
117         if (callid==NULL) {
118                 ms_error("There is no call id in the request !");
119                 return;
120         }
121         osip_call_id_clone(callid,&op->call_id);
122         sal->other_transactions=ms_list_append(sal->other_transactions,op);
123 }
124
125 static void sal_remove_other(Sal *sal, SalOp *op){
126         sal->other_transactions=ms_list_remove(sal->other_transactions,op);
127 }
128
129
130 static void sal_add_pending_auth(Sal *sal, SalOp *op){
131         sal->pending_auths=ms_list_append(sal->pending_auths,op);
132 }
133
134
135 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
136         sal->pending_auths=ms_list_remove(sal->pending_auths,op);
137 }
138
139 void sal_exosip_fix_route(SalOp *op){
140         if (sal_op_get_route(op)!=NULL){
141                 osip_route_t *rt=NULL;
142                 osip_uri_param_t *lr_param=NULL;
143                 
144                 osip_route_init(&rt);
145                 if (osip_route_parse(rt,sal_op_get_route(op))<0){
146                         ms_warning("Bad route  %s!",sal_op_get_route(op));
147                         sal_op_set_route(op,NULL);
148                 }else{
149                         /* check if the lr parameter is set , if not add it */
150                         osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
151                         if (lr_param==NULL){
152                                 char *tmproute;
153                                 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
154                                 osip_route_to_str(rt,&tmproute);
155                                 sal_op_set_route(op,tmproute);
156                                 osip_free(tmproute);
157                         }
158                 }
159                 osip_route_free(rt);
160         }
161 }
162
163 SalOp * sal_op_new(Sal *sal){
164         SalOp *op=ms_new0(SalOp,1);
165         __sal_op_init(op,sal);
166         op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
167         op->result=NULL;
168         op->supports_session_timers=FALSE;
169         op->sdp_offering=TRUE;
170         op->pending_auth=NULL;
171         op->sdp_answer=NULL;
172         op->reinvite=FALSE;
173         op->call_id=NULL;
174         op->replaces=NULL;
175         op->referred_by=NULL;
176         op->masquerade_via=FALSE;
177         op->auto_answer_asked=FALSE;
178         op->auth_info=NULL;
179         op->terminated=FALSE;
180         return op;
181 }
182
183 bool_t sal_call_autoanswer_asked(SalOp *op)
184 {
185         return op->auto_answer_asked;
186 }
187
188 void sal_op_release(SalOp *op){
189         if (op->sdp_answer)
190                 sdp_message_free(op->sdp_answer);
191         if (op->pending_auth)
192                 eXosip_event_free(op->pending_auth);
193         if (op->rid!=-1){
194                 sal_remove_register(op->base.root,op->rid);
195                 eXosip_register_remove(op->rid);
196         }
197         if (op->cid!=-1){
198                 ms_message("Cleaning cid %i",op->cid);
199                 sal_remove_call(op->base.root,op);
200         }
201         if (op->sid!=-1){
202                 sal_remove_out_subscribe(op->base.root,op);
203         }
204         if (op->nid!=-1){
205                 sal_remove_in_subscribe(op->base.root,op);
206                 if (op->call_id)
207                         osip_call_id_free(op->call_id);
208                 op->call_id=NULL;
209         }
210         if (op->pending_auth){
211                 sal_remove_pending_auth(op->base.root,op);
212         }
213         if (op->result)
214                 sal_media_description_unref(op->result);
215         if (op->call_id){
216                 sal_remove_other(op->base.root,op);
217                 osip_call_id_free(op->call_id);
218         }
219         if (op->replaces){
220                 ms_free(op->replaces);
221         }
222         if (op->referred_by){
223                 ms_free(op->referred_by);
224         }
225         if (op->auth_info) {
226                 sal_auth_info_delete(op->auth_info);
227         }
228         __sal_op_free(op);
229 }
230
231 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
232         int ortp_level=ORTP_DEBUG;
233         switch(level){
234                 case OSIP_INFO1:
235                 case OSIP_INFO2:
236                 case OSIP_INFO3:
237                 case OSIP_INFO4:
238                         ortp_level=ORTP_MESSAGE;
239                         break;
240                 case OSIP_WARNING:
241                         ortp_level=ORTP_WARNING;
242                         break;
243                 case OSIP_ERROR:
244                 case OSIP_BUG:
245                         ortp_level=ORTP_ERROR;
246                         break;
247                 case OSIP_FATAL:
248                         ortp_level=ORTP_FATAL;
249                         break;
250                 case END_TRACE_LEVEL:
251                         break;
252         }
253         if (ortp_log_level_enabled(level)){
254                 int len=strlen(chfr);
255                 char *chfrdup=ortp_strdup(chfr);
256                 /*need to remove endline*/
257                 if (len>1){
258                         if (chfrdup[len-1]=='\n')
259                                 chfrdup[len-1]='\0';
260                         if (chfrdup[len-2]=='\r')
261                                 chfrdup[len-2]='\0';
262                 }
263                 ortp_logv(ortp_level,chfrdup,ap);
264                 ortp_free(chfrdup);
265         }
266 }
267
268
269 Sal * sal_init(){
270         static bool_t firsttime=TRUE;
271         Sal *sal;
272         if (firsttime){
273                 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
274                 firsttime=FALSE;
275         }
276         eXosip_init();
277         sal=ms_new0(Sal,1);
278         sal->keepalive_period=30;
279         sal->double_reg=TRUE;
280         sal->use_rports=TRUE;
281         sal->use_101=TRUE;
282         sal->reuse_authorization=FALSE;
283         sal->rootCa = 0;
284         sal->verify_server_certs=TRUE;
285         sal->verify_server_cn=TRUE;
286         sal->expire_old_contact=FALSE;
287         sal->add_dates=FALSE;
288         sal->dscp=-1;
289         return sal;
290 }
291
292 void sal_uninit(Sal* sal){
293         eXosip_quit();
294         if (sal->rootCa)
295                 ms_free(sal->rootCa);
296         ms_free(sal);
297 }
298
299 void sal_set_user_pointer(Sal *sal, void *user_data){
300         sal->up=user_data;
301 }
302
303 void *sal_get_user_pointer(const Sal *sal){
304         return sal->up;
305 }
306
307 static void unimplemented_stub(){
308         ms_warning("Unimplemented SAL callback");
309 }
310
311 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
312         memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
313         if (ctx->callbacks.call_received==NULL) 
314                 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
315         if (ctx->callbacks.call_ringing==NULL) 
316                 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
317         if (ctx->callbacks.call_accepted==NULL) 
318                 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
319         if (ctx->callbacks.call_failure==NULL) 
320                 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
321         if (ctx->callbacks.call_terminated==NULL) 
322                 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
323         if (ctx->callbacks.call_released==NULL)
324                 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
325         if (ctx->callbacks.call_updating==NULL) 
326                 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
327         if (ctx->callbacks.auth_requested==NULL) 
328                 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
329         if (ctx->callbacks.auth_success==NULL) 
330                 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
331         if (ctx->callbacks.register_success==NULL) 
332                 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
333         if (ctx->callbacks.register_failure==NULL) 
334                 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
335         if (ctx->callbacks.dtmf_received==NULL) 
336                 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
337         if (ctx->callbacks.notify==NULL)
338                 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
339         if (ctx->callbacks.notify_presence==NULL)
340                 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
341         if (ctx->callbacks.subscribe_received==NULL)
342                 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
343         if (ctx->callbacks.text_received==NULL)
344                 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
345         if (ctx->callbacks.ping_reply==NULL)
346                 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
347 }
348
349 int sal_unlisten_ports(Sal *ctx){
350         if (ctx->running){
351                 eXosip_quit();
352                 eXosip_init();
353                 ctx->running=FALSE;
354         }
355         return 0;
356 }
357
358 int sal_reset_transports(Sal *ctx){
359 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
360         if (ctx->running){
361                 ms_message("Exosip transports reset.");
362                 eXosip_reset_transports();
363         }
364         return 0;
365 #else
366         ms_warning("sal_reset_transports() not implemented in this version.");
367         return -1;
368 #endif
369 }
370
371
372 static void set_tls_options(Sal *ctx){
373         if (ctx->rootCa) {
374                 eXosip_tls_ctx_t tlsCtx;
375                 memset(&tlsCtx, 0, sizeof(tlsCtx));
376                 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
377                 eXosip_set_tls_ctx(&tlsCtx);
378         }                       
379 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
380         eXosip_tls_verify_certificate(ctx->verify_server_certs);
381 #endif
382 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
383         eXosip_tls_verify_cn(ctx->verify_server_cn);
384 #endif
385 }
386
387 void sal_set_dscp(Sal *ctx, int dscp){
388         ctx->dscp=dscp;
389 #ifdef HAVE_EXOSIP_DSCP
390         if (dscp!=-1)
391                 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
392 #endif
393 }
394
395 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
396         int err;
397         bool_t ipv6;
398         int proto=IPPROTO_UDP;
399         int keepalive = ctx->keepalive_period;
400
401         ctx->transport = tr;
402         switch (tr) {
403         case SalTransportUDP:
404                 proto=IPPROTO_UDP;
405                 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
406                 break;
407         case SalTransportTCP:
408         case SalTransportTLS:
409                 proto= IPPROTO_TCP;
410                 if (!ctx->tcp_tls_keepalive) keepalive=-1;
411                 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
412                 set_tls_options(ctx);
413                 break;
414         default:
415                 ms_warning("unexpected proto, using datagram");
416         }
417         /*see if it looks like an IPv6 address*/
418         int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
419         eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
420         int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
421         eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
422         sal_set_dscp(ctx,ctx->dscp);
423         sal_use_dates(ctx,ctx->add_dates);
424
425         ipv6=strchr(addr,':')!=NULL;
426         eXosip_enable_ipv6(ipv6);
427
428         if (is_secure && tr == SalTransportUDP){
429                 ms_fatal("SIP over DTLS is not supported yet.");
430                 return -1;
431         }
432         err=eXosip_listen_addr(proto, addr, port, ipv6 ?  PF_INET6 : PF_INET, is_secure);
433         ctx->running=TRUE;
434         return err;
435 }
436
437 ortp_socket_t sal_get_socket(Sal *ctx){
438 #ifdef HAVE_EXOSIP_GET_SOCKET
439         return eXosip_get_socket(IPPROTO_UDP);
440 #else
441         ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
442         return -1;
443 #endif
444 }
445
446 void sal_set_user_agent(Sal *ctx, const char *user_agent){
447         eXosip_set_user_agent(user_agent);
448 }
449
450 void sal_use_session_timers(Sal *ctx, int expires){
451         ctx->session_expires=expires;
452 }
453
454 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
455         ctx->one_matching_codec=one_matching_codec;
456 }
457
458 MSList *sal_get_pending_auths(Sal *sal){
459         return ms_list_copy(sal->pending_auths);
460 }
461
462 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
463         ctx->double_reg=enabled;
464 }
465
466 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
467         ctx->expire_old_contact=enabled;
468 }
469
470 void sal_use_dates(Sal *ctx, bool_t enabled){
471         ctx->add_dates=enabled;
472 #ifdef EXOSIP_OPT_REGISTER_WITH_DATE
473         {
474                 int tmp=enabled;
475                 eXosip_set_option(EXOSIP_OPT_REGISTER_WITH_DATE,&tmp);
476         }
477 #else
478         if (enabled) ms_warning("Exosip does not support EXOSIP_OPT_REGISTER_WITH_DATE option.");
479 #endif
480 }
481
482 void sal_use_rport(Sal *ctx, bool_t use_rports){
483         ctx->use_rports=use_rports;
484 }
485 void sal_use_101(Sal *ctx, bool_t use_101){
486         ctx->use_101=use_101;
487 }
488
489 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
490         if (ctx->rootCa)
491                 ms_free(ctx->rootCa);
492         ctx->rootCa = ms_strdup(rootCa);
493         set_tls_options(ctx);
494 }
495
496 const char *sal_get_root_ca(Sal* ctx) {
497         return ctx->rootCa;
498 }
499
500 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
501         ctx->verify_server_certs=verify;
502 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
503         eXosip_tls_verify_certificate(verify);
504 #endif
505 }
506
507 void sal_verify_server_cn(Sal *ctx, bool_t verify){
508         ctx->verify_server_cn=verify;
509 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
510         eXosip_tls_verify_cn(verify);
511 #endif
512 }
513
514 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
515         osip_via_t *via=NULL;
516         osip_generic_param_t *param=NULL;
517         const char *rport=NULL;
518
519         *rportval=5060;
520         *received=NULL;
521         osip_message_get_via(msg,0,&via);
522         if (!via) {
523                 ms_warning("extract_received_rport(): no via.");
524                 return -1;
525         }
526
527         *transport = sal_transport_parse(via->protocol);
528         
529         if (via->port && via->port[0]!='\0')
530                 *rportval=atoi(via->port);
531         
532         osip_via_param_get_byname(via,"rport",&param);
533         if (param) {
534                 rport=param->gvalue;
535                 if (rport && rport[0]!='\0') *rportval=atoi(rport);
536                 *received=via->host;
537         }
538         param=NULL;
539         osip_via_param_get_byname(via,"received",&param);
540         if (param) *received=param->gvalue;
541
542         if (rport==NULL && *received==NULL){
543                 ms_warning("extract_received_rport(): no rport and no received parameters.");
544                 return -1;
545         }
546         return 0;
547 }
548
549 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
550         int sdplen;
551         char clen[10];
552         char *sdp=NULL;
553         sdp_message_to_str(msg,&sdp);
554         sdplen=strlen(sdp);
555         snprintf(clen,sizeof(clen),"%i",sdplen);
556         osip_message_set_body(sip,sdp,sdplen);
557         osip_message_set_content_type(sip,"application/sdp");
558         osip_message_set_content_length(sip,clen);
559         osip_free(sdp);
560 }
561
562 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
563         sdp_message_t *msg=media_description_to_sdp(desc);
564         if (msg==NULL) {
565                 ms_error("Fail to print sdp message !");
566                 return;
567         }
568         set_sdp(sip,msg);
569         sdp_message_free(msg);
570 }
571
572 static void sdp_process(SalOp *h){
573         ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
574         if (h->result){
575                 sal_media_description_unref(h->result);
576         }
577         h->result=sal_media_description_new();
578         if (h->sdp_offering){   
579                 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
580         }else{
581                 int i;
582                 if (h->sdp_answer){
583                         sdp_message_free(h->sdp_answer);
584                 }
585                 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
586                 h->sdp_answer=media_description_to_sdp(h->result);
587                 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
588                  It should contains media parameters constraint from the remote offer, not our response*/
589                 strcpy(h->result->addr,h->base.remote_media->addr);
590                 h->result->bandwidth=h->base.remote_media->bandwidth;
591                 
592                 for(i=0;i<h->result->n_active_streams;++i){
593                         strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
594                         strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
595                         h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
596                         h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
597                         h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
598                         h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
599                         if (h->result->streams[i].proto == SalProtoRtpSavp) {
600                                 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
601                         }
602                 }
603         }
604         
605 }
606
607 int sal_call_is_offerer(const SalOp *h){
608         return h->sdp_offering;
609 }
610
611 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
612         if (desc)
613                 sal_media_description_ref(desc);
614         if (h->base.local_media)
615                 sal_media_description_unref(h->base.local_media);
616         h->base.local_media=desc;
617         if (h->base.remote_media){
618                 /*case of an incoming call where we modify the local capabilities between the time
619                  * the call is ringing and it is accepted (for example if you want to accept without video*/
620                 /*reset the sdp answer so that it is computed again*/
621                 if (h->sdp_answer){
622                         sdp_message_free(h->sdp_answer);
623                         h->sdp_answer=NULL;
624                 }
625         }
626         return 0;
627 }
628
629 int sal_call(SalOp *h, const char *from, const char *to){
630         int err;
631         const char *route;
632         osip_message_t *invite=NULL;
633         osip_call_id_t *callid;
634         sal_op_set_from(h,from);
635         sal_op_set_to(h,to);
636         sal_exosip_fix_route(h);
637         
638         h->terminated = FALSE;
639
640         route = sal_op_get_route(h);
641         err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
642         if (err!=0){
643                 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
644                                 err, from, to, route);
645                 return -1;
646         }
647         osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
648         if (h->base.contact){
649                 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
650                 osip_message_set_contact(invite,h->base.contact);
651         }
652         if (h->base.root->session_expires!=0){
653                 osip_message_set_header(invite, "Session-expires", "200");
654                 osip_message_set_supported(invite, "timer");
655         }
656         if (h->base.local_media){
657                 h->sdp_offering=TRUE;
658                 set_sdp_from_desc(invite,h->base.local_media);
659         }else h->sdp_offering=FALSE;
660         if (h->replaces){
661                 osip_message_set_header(invite,"Replaces",h->replaces);
662                 if (h->referred_by)
663                         osip_message_set_header(invite,"Referred-By",h->referred_by);
664         }
665         
666         eXosip_lock();
667         err=eXosip_call_send_initial_invite(invite);
668         eXosip_unlock();
669         h->cid=err;
670         if (err<0){
671                 ms_error("Fail to send invite ! Error code %d", err);
672                 return -1;
673         }else{
674                 char *tmp=NULL;
675                 callid=osip_message_get_call_id(invite);
676                 osip_call_id_to_str(callid,&tmp);
677                 h->base.call_id=ms_strdup(tmp);
678                 osip_free(tmp);
679                 sal_add_call(h->base.root,h);
680         }
681         return 0;
682 }
683
684 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
685         osip_message_t *msg;
686         
687         /*if early media send also 180 and 183 */
688         if (early_media){
689                 msg=NULL;
690                 eXosip_lock();
691                 eXosip_call_build_answer(h->tid,183,&msg);
692                 if (msg){
693                         sdp_process(h);
694                         if (h->sdp_answer){
695                                 set_sdp(msg,h->sdp_answer);
696                                 sdp_message_free(h->sdp_answer);
697                                 h->sdp_answer=NULL;
698                         }
699                         eXosip_call_send_answer(h->tid,183,msg);
700                 }
701                 eXosip_unlock();
702         }else{
703                 eXosip_lock();
704                 eXosip_call_send_answer(h->tid,180,NULL);
705                 eXosip_unlock();
706         }
707         return 0;
708 }
709
710 int sal_call_accept(SalOp * h){
711         osip_message_t *msg;
712         const char *contact=sal_op_get_contact(h);
713         /* sends a 200 OK */
714         int err=eXosip_call_build_answer(h->tid,200,&msg);
715         if (err<0 || msg==NULL){
716                 ms_error("Fail to build answer for call: err=%i",err);
717                 return -1;
718         }
719         if (h->base.root->session_expires!=0){
720                 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
721         }
722
723         if (contact) {
724                 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
725                 osip_message_set_contact(msg,contact);
726         }
727         
728         if (h->base.local_media){
729                 /*this is the case where we received an invite without SDP*/
730                 if (h->sdp_offering) {
731                         set_sdp_from_desc(msg,h->base.local_media);
732                 }else{
733                         if (h->sdp_answer==NULL) sdp_process(h);
734                         if (h->sdp_answer){
735                                 set_sdp(msg,h->sdp_answer);
736                                 sdp_message_free(h->sdp_answer);
737                                 h->sdp_answer=NULL;
738                         }
739                 }
740         }else{
741                 ms_error("You are accepting a call but not defined any media capabilities !");
742         }
743         eXosip_call_send_answer(h->tid,200,msg);
744         return 0;
745 }
746
747 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
748         if (reason==SalReasonBusy){
749                 eXosip_lock();
750                 eXosip_call_send_answer(h->tid,486,NULL);
751                 eXosip_unlock();
752         }
753         else if (reason==SalReasonTemporarilyUnavailable){
754                 eXosip_lock();
755                 eXosip_call_send_answer(h->tid,480,NULL);
756                 eXosip_unlock();
757         }else if (reason==SalReasonDoNotDisturb){
758                 eXosip_lock();
759                 eXosip_call_send_answer(h->tid,600,NULL);
760                 eXosip_unlock();
761         }else if (reason==SalReasonMedia){
762                 eXosip_lock();
763                 eXosip_call_send_answer(h->tid,415,NULL);
764                 eXosip_unlock();
765         }else if (redirect!=NULL && reason==SalReasonRedirect){
766                 osip_message_t *msg;
767                 int code;
768                 if (strstr(redirect,"sip:")!=0) code=302;
769                 else code=380;
770                 eXosip_lock();
771                 eXosip_call_build_answer(h->tid,code,&msg);
772                 osip_message_set_contact(msg,redirect);
773                 eXosip_call_send_answer(h->tid,code,msg);
774                 eXosip_unlock();
775         }else sal_call_terminate(h);
776         return 0;
777 }
778
779 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
780         return h->base.remote_media;
781 }
782
783 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
784         if (h->base.local_media && h->base.remote_media && !h->result){
785                 sdp_process(h);
786         }
787         return h->result;
788 }
789
790 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
791         if (refered_call->replaces)
792                 h->replaces=ms_strdup(refered_call->replaces);
793         if (refered_call->referred_by)
794                 h->referred_by=ms_strdup(refered_call->referred_by);
795         return 0;
796 }
797
798 static int send_notify_for_refer(int did, const char *sipfrag){
799         osip_message_t *msg;
800         eXosip_lock();
801         eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
802         if (msg==NULL){
803                 eXosip_unlock();
804                 ms_warning("Could not build NOTIFY for refer.");
805                 return -1;
806         }
807         osip_message_set_content_type(msg,"message/sipfrag");
808         osip_message_set_header(msg,"Event","refer");
809         osip_message_set_body(msg,sipfrag,strlen(sipfrag));
810         eXosip_call_send_request(did,msg);
811         eXosip_unlock();
812         return 0;
813 }
814
815 /* currently only support to notify trying and 200Ok*/
816 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
817         if (newcall==NULL){
818                 /* in progress*/
819                 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
820         }
821         else if (newcall->cid!=-1){
822                 if (newcall->did==-1){
823                         /* not yet established*/
824                         if (!newcall->terminated){
825                                 /* in progress*/
826                                 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
827                         }
828                 }else{
829                         if (!newcall->terminated){
830                                 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
831                                         /* we need previous notify transaction to complete, so buffer the request for later*/
832                                         h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
833                                 }
834                         }
835                 }
836         }
837         return 0;
838 }
839
840 int sal_ping(SalOp *op, const char *from, const char *to){
841         osip_message_t *options=NULL;
842         
843         sal_op_set_from(op,from);
844         sal_op_set_to(op,to);
845         sal_exosip_fix_route(op);
846
847         eXosip_options_build_request (&options, sal_op_get_to(op),
848                         sal_op_get_from(op),sal_op_get_route(op));
849         if (options){
850                 if (op->base.root->session_expires!=0){
851                         osip_message_set_header(options, "Session-expires", "200");
852                         osip_message_set_supported(options, "timer");
853                 }
854                 sal_add_other(sal_op_get_sal(op),op,options);
855                 return eXosip_options_send_request(options);
856         }
857         return -1;
858 }
859
860 int sal_call_refer(SalOp *h, const char *refer_to){
861         osip_message_t *msg=NULL;
862         int err=0;
863         eXosip_lock();
864         eXosip_call_build_refer(h->did,refer_to, &msg);
865         if (msg) err=eXosip_call_send_request(h->did, msg);
866         else err=-1;
867         eXosip_unlock();
868         return err;
869 }
870
871 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
872         osip_message_t *msg=NULL;
873         char referto[256]={0};
874         int err=0;
875         eXosip_lock();
876         if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
877                 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
878                 eXosip_unlock();
879                 return -1;
880         }
881         eXosip_call_build_refer(h->did,referto, &msg);
882         osip_message_set_header(msg,"Referred-By",h->base.from);
883         if (msg) err=eXosip_call_send_request(h->did, msg);
884         else err=-1;
885         eXosip_unlock();
886         return err;
887 }
888
889 SalOp *sal_call_get_replaces(SalOp *h){
890         if (h!=NULL && h->replaces!=NULL){
891                 int cid;
892                 eXosip_lock();
893                 cid=eXosip_call_find_by_replaces(h->replaces);
894                 eXosip_unlock();
895                 if (cid>0){
896                         SalOp *ret=sal_find_call(h->base.root,cid);
897                         return ret;
898                 }
899         }
900         return NULL;
901 }
902
903 int sal_call_send_dtmf(SalOp *h, char dtmf){
904         osip_message_t *msg=NULL;
905         char dtmf_body[128];
906         char clen[10];
907
908         eXosip_lock();
909         eXosip_call_build_info(h->did,&msg);
910         if (msg){
911                 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
912                 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
913                 osip_message_set_content_type(msg,"application/dtmf-relay");
914                 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
915                 osip_message_set_content_length(msg,clen);              
916                 eXosip_call_send_request(h->did,msg);
917         }
918         eXosip_unlock();
919         return 0;
920 }
921
922 static void push_auth_to_exosip(const SalAuthInfo *info){
923         const char *userid;
924         if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
925         else userid=info->userid;
926         ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
927         eXosip_add_authentication_info (info->username,userid,
928                                   info->password, NULL,info->realm);
929 }
930 /*
931  * Just for symmetry ;-)
932  */
933 static void pop_auth_from_exosip() {
934         eXosip_clear_authentication_info();
935 }
936
937 int sal_call_terminate(SalOp *h){
938         int err;
939         if (h == NULL) return -1;
940         if (h->auth_info) push_auth_to_exosip(h->auth_info);
941         eXosip_lock();
942         err=eXosip_call_terminate(h->cid,h->did);
943         eXosip_unlock();
944         if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
945         if (err!=0){
946                 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
947         }
948         h->terminated=TRUE;
949         return 0;
950 }
951
952 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
953        bool_t terminating=FALSE;
954        if (h->pending_auth && strcmp(h->pending_auth->request->sip_method,"BYE")==0) {
955                terminating=TRUE;
956        }
957        if (h->terminated && !terminating) return;
958
959        if (h->pending_auth){
960                 push_auth_to_exosip(info);
961                 
962         /*FIXME exosip does not take into account this update register message*/
963         /*
964         if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
965             
966         };
967         */
968                 update_contact_from_response(h,h->pending_auth->response);
969                 eXosip_lock();
970                 eXosip_default_action(h->pending_auth);
971                 eXosip_unlock();
972                 ms_message("eXosip_default_action() done");
973                 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
974                 
975                 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
976                 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
977         }
978 }
979 void sal_op_cancel_authentication(SalOp *h) {
980         if (h->rid >0) {
981                 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
982         } else if (h->cid >0) {
983                 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
984         } else {
985                 ms_warning("Auth failure not handled");
986         }
987
988 }
989 static void set_network_origin(SalOp *op, osip_message_t *req){
990         const char *received=NULL;
991         int rport=5060;
992         char origin[64]={0};
993     SalTransport transport;
994         if (extract_received_rport(req,&received,&rport,&transport)!=0){
995                 osip_via_t *via=NULL;
996                 char *tmp;
997                 osip_message_get_via(req,0,&via);
998                 received=osip_via_get_host(via);
999                 tmp=osip_via_get_port(via);
1000                 if (tmp) rport=atoi(tmp);
1001         }
1002     if (transport != SalTransportUDP) {
1003         snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
1004     } else {
1005        snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport)); 
1006     }
1007         __sal_op_set_network_origin(op,origin);
1008 }
1009
1010 static void set_remote_ua(SalOp* op, osip_message_t *req){
1011         if (op->base.remote_ua==NULL){
1012                 osip_header_t *h=NULL;
1013                 osip_message_get_user_agent(req,0,&h);
1014                 if (h){
1015                         op->base.remote_ua=ms_strdup(h->hvalue);
1016                 }
1017         }
1018 }
1019
1020 static void set_remote_contact(SalOp* op, osip_message_t *req){
1021         if (op->base.remote_contact==NULL){
1022                 osip_contact_t *h=NULL;
1023                 osip_message_get_contact(req,0,&h);
1024                 if (h){
1025                         char *tmp=NULL;
1026                         osip_contact_to_str(h,&tmp);
1027                         __sal_op_set_remote_contact(op,tmp);
1028                         osip_free(tmp);
1029                 }
1030         }
1031 }
1032
1033 static void set_replaces(SalOp *op, osip_message_t *req){
1034         osip_header_t *h=NULL;
1035
1036         if (op->replaces){
1037                 ms_free(op->replaces);
1038                 op->replaces=NULL;
1039         }
1040         osip_message_header_get_byname(req,"replaces",0,&h);
1041         if (h){
1042                 if (h->hvalue && h->hvalue[0]!='\0'){
1043                         op->replaces=ms_strdup(h->hvalue);
1044                 }
1045         }
1046 }
1047
1048 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1049         if (ev->cid>0){
1050                 return sal_find_call(sal,ev->cid);
1051         }
1052         if (ev->rid>0){
1053                 return sal_find_register(sal,ev->rid);
1054         }
1055         if (ev->sid>0){
1056                 return sal_find_out_subscribe(sal,ev->sid);
1057         }
1058         if (ev->nid>0){
1059                 return sal_find_in_subscribe(sal,ev->nid);
1060         }
1061         if (ev->response) return sal_find_other(sal,ev->response);
1062         else if (ev->request) return sal_find_other(sal,ev->request);
1063         return NULL;
1064 }
1065
1066 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1067         SalOp *op=sal_op_new(sal);
1068         osip_from_t *from,*to;
1069         osip_call_info_t *call_info;
1070         char *tmp=NULL;
1071         sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1072         
1073         osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1074         
1075         osip_call_id_to_str(callid,&tmp);
1076         op->base.call_id=ms_strdup(tmp);
1077         osip_free(tmp);
1078         
1079         set_network_origin(op,ev->request);
1080         set_remote_contact(op,ev->request);
1081         set_remote_ua(op,ev->request);
1082         set_replaces(op,ev->request);
1083         
1084         if (sdp){
1085                 op->sdp_offering=FALSE;
1086                 op->base.remote_media=sal_media_description_new();
1087                 sdp_to_media_description(sdp,op->base.remote_media);
1088                 sdp_message_free(sdp);
1089         }else op->sdp_offering=TRUE;
1090
1091         from=osip_message_get_from(ev->request);
1092         to=osip_message_get_to(ev->request);
1093         osip_from_to_str(from,&tmp);
1094         sal_op_set_from(op,tmp);
1095         osip_free(tmp);
1096         osip_from_to_str(to,&tmp);
1097         sal_op_set_to(op,tmp);
1098         osip_free(tmp);
1099
1100         osip_message_get_call_info(ev->request,0,&call_info);
1101         if(call_info)
1102         {
1103                 osip_call_info_to_str(call_info,&tmp);
1104                 if( strstr(tmp,"answer-after=") != NULL)
1105                 {
1106                         op->auto_answer_asked=TRUE;
1107                         ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1108                 }
1109                 osip_free(tmp);
1110         }
1111
1112         op->tid=ev->tid;
1113         op->cid=ev->cid;
1114         op->did=ev->did;
1115         sal_add_call(op->base.root,op);
1116         sal->callbacks.call_received(op);
1117 }
1118
1119 static void handle_reinvite(Sal *sal,  eXosip_event_t *ev){
1120         SalOp *op=find_op(sal,ev);
1121         sdp_message_t *sdp;
1122
1123         if (op==NULL) {
1124                 ms_warning("Reinvite for non-existing operation !");
1125                 return;
1126         }
1127         op->reinvite=TRUE;
1128         op->tid=ev->tid;
1129         sdp=eXosip_get_sdp_info(ev->request);
1130         if (op->base.remote_media){
1131                 sal_media_description_unref(op->base.remote_media);
1132                 op->base.remote_media=NULL;
1133         }
1134         if (op->result){
1135                 sal_media_description_unref(op->result);
1136                 op->result=NULL;
1137         }
1138         if (sdp){
1139                 op->sdp_offering=FALSE;
1140                 op->base.remote_media=sal_media_description_new();
1141                 sdp_to_media_description(sdp,op->base.remote_media);
1142                 sdp_message_free(sdp);
1143                 
1144         }else {
1145                 op->sdp_offering=TRUE;
1146         }
1147         sal->callbacks.call_updating(op);
1148 }
1149
1150 static void handle_ack(Sal *sal,  eXosip_event_t *ev){
1151         SalOp *op=find_op(sal,ev);
1152         sdp_message_t *sdp;
1153
1154         if (op==NULL) {
1155                 ms_warning("ack for non-existing call !");
1156                 return;
1157         }
1158         if (op->terminated) {
1159                 ms_warning("ack for terminated call, ignoring");
1160                 return;
1161         }
1162         
1163         if (op->sdp_offering){
1164                 sdp=eXosip_get_sdp_info(ev->ack);
1165                 if (sdp){
1166                         if (op->base.remote_media)
1167                                 sal_media_description_unref(op->base.remote_media);
1168                         op->base.remote_media=sal_media_description_new();
1169                         sdp_to_media_description(sdp,op->base.remote_media);
1170                         sdp_process(op);
1171                         sdp_message_free(sdp);
1172                 }
1173         }
1174         if (op->reinvite){
1175                 op->reinvite=FALSE;
1176         }
1177         sal->callbacks.call_ack(op);
1178 }
1179
1180 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1181         const char *received;
1182         int rport;
1183         SalTransport transport;
1184         if (extract_received_rport(response,&received,&rport,&transport)==0){
1185                 const char *contact=sal_op_get_contact(op);
1186                 if (!contact){
1187                         /*no contact given yet, use from instead*/
1188                         contact=sal_op_get_from(op);
1189                 }
1190                 if (contact){
1191                         SalAddress *addr=sal_address_new(contact);
1192                         char *tmp;
1193                         sal_address_set_domain(addr,received);
1194                         sal_address_set_port_int(addr,rport);
1195                         if (transport!=SalTransportUDP)
1196                                 sal_address_set_transport(addr,transport);
1197                         tmp=sal_address_as_string(addr);
1198                         ms_message("Contact address updated to %s",tmp);
1199                         sal_op_set_contact(op,tmp);
1200                         sal_address_destroy(addr);
1201                         ms_free(tmp);
1202                 }
1203         }
1204 }
1205
1206 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1207         SalOp *op=find_op(sal,ev);
1208
1209         if (op==NULL || op->terminated==TRUE) {
1210                 ms_warning("This call has been canceled.");
1211                 eXosip_lock();
1212                 eXosip_call_terminate(ev->cid,ev->did);
1213                 eXosip_unlock();
1214                 return -1;
1215         }
1216         if (ev->did>0)
1217                 op->did=ev->did;
1218         op->tid=ev->tid;
1219         
1220         /* update contact if received and rport are set by the server
1221          note: will only be used by remote for next INVITE, if any...*/
1222         update_contact_from_response(op,ev->response);
1223         return 0;
1224 }
1225
1226 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1227         sdp_message_t *sdp;
1228         SalOp *op=find_op(sal,ev);
1229         if (call_proceeding(sal, ev)==-1) return;
1230
1231         set_remote_ua(op,ev->response);
1232         sdp=eXosip_get_sdp_info(ev->response);
1233         if (sdp){
1234                 op->base.remote_media=sal_media_description_new();
1235                 sdp_to_media_description(sdp,op->base.remote_media);
1236                 sdp_message_free(sdp);
1237                 if (op->base.local_media) sdp_process(op);
1238         }
1239         sal->callbacks.call_ringing(op);
1240 }
1241
1242 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1243         sdp_message_t *sdp;
1244         osip_message_t *msg=NULL;
1245         SalOp *op=find_op(sal,ev);
1246         const char *contact;
1247         
1248         if (op==NULL || op->terminated==TRUE) {
1249                 ms_warning("This call has been already terminated.");
1250                 eXosip_lock();
1251                 eXosip_call_terminate(ev->cid,ev->did);
1252                 eXosip_unlock();
1253                 return ;
1254         }
1255
1256         op->did=ev->did;
1257         set_remote_ua(op,ev->response);
1258         set_remote_contact(op,ev->response);
1259
1260         sdp=eXosip_get_sdp_info(ev->response);
1261         if (sdp){
1262                 op->base.remote_media=sal_media_description_new();
1263                 sdp_to_media_description(sdp,op->base.remote_media);
1264                 sdp_message_free(sdp);
1265                 if (op->base.local_media) sdp_process(op);
1266         }
1267         eXosip_call_build_ack(ev->did,&msg);
1268         if (msg==NULL) {
1269                 ms_warning("This call has been already terminated.");
1270                 eXosip_lock();
1271                 eXosip_call_terminate(ev->cid,ev->did);
1272                 eXosip_unlock();
1273                 return ;
1274         }
1275         contact=sal_op_get_contact(op);
1276         if (contact) {
1277                 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1278                 osip_message_set_contact(msg,contact);
1279         }
1280         if (op->sdp_answer){
1281                 set_sdp(msg,op->sdp_answer);
1282                 sdp_message_free(op->sdp_answer);
1283                 op->sdp_answer=NULL;
1284         }
1285         eXosip_call_send_ack(ev->did,msg);
1286         sal->callbacks.call_accepted(op);
1287 }
1288
1289 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1290         char *from=NULL;
1291         SalOp *op=find_op(sal,ev);
1292         if (op==NULL){
1293                 ms_warning("Call terminated for already closed call ?");
1294                 return;
1295         }
1296         if (ev->request){
1297                 osip_from_to_str(ev->request->from,&from);
1298         }
1299         sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1300         if (from) osip_free(from);
1301         op->terminated=TRUE;
1302 }
1303
1304 static void call_released(Sal *sal, eXosip_event_t *ev){
1305         SalOp *op=find_op(sal,ev);
1306         if (op==NULL){
1307                 ms_warning("No op associated to this call_released()");
1308                 return;
1309         }
1310         if (!op->terminated){
1311                 /* no response received so far */
1312                 call_failure(sal,ev);
1313         }
1314         sal->callbacks.call_released(op);
1315 }
1316
1317 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1318         const char *prx_realm=NULL,*www_realm=NULL;
1319         osip_proxy_authenticate_t *prx_auth;
1320         osip_www_authenticate_t *www_auth;
1321         
1322         *username=osip_uri_get_username(resp->from->url);
1323         prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1324         www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1325         if (prx_auth!=NULL)
1326                 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1327         if (www_auth!=NULL)
1328                 www_realm=osip_www_authenticate_get_realm(www_auth);
1329
1330         if (prx_realm){
1331                 *realm=prx_realm;
1332         }else if (www_realm){
1333                 *realm=www_realm;
1334         }else{
1335                 return -1;
1336         }
1337         return 0;
1338 }
1339
1340 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1341         osip_authorization_t *auth=NULL;
1342         osip_proxy_authorization_t *prx_auth=NULL;
1343         
1344         *username=osip_uri_get_username(msg->from->url);
1345         osip_message_get_authorization(msg, 0, &auth);
1346         if (auth){
1347                 *realm=osip_authorization_get_realm(auth);
1348                 return 0;
1349         }
1350         osip_message_get_proxy_authorization(msg,0,&prx_auth);
1351         if (prx_auth){
1352                 *realm=osip_proxy_authorization_get_realm(prx_auth);
1353                 return 0;
1354         }
1355         return -1;
1356 }
1357
1358 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1359         if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1360         if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1361         return -1;
1362 }
1363
1364 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1365         if (op->pending_auth){
1366                 return get_auth_data(op->pending_auth,realm,username);
1367         }
1368         return -1;
1369 }
1370
1371 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1372         SalOp *op;
1373         const char *username,*realm;
1374         op=find_op(sal,ev);
1375         if (op==NULL){
1376                 ms_warning("No operation associated with this authentication !");
1377                 return TRUE;
1378         }
1379         if (get_auth_data(ev,&realm,&username)==0){
1380                 if (op->pending_auth!=NULL){
1381                         eXosip_event_free(op->pending_auth);
1382                         op->pending_auth=ev;
1383                 }else{
1384                         op->pending_auth=ev;
1385                         sal_add_pending_auth(sal,op);
1386                 }
1387                 
1388                 sal->callbacks.auth_requested(op,realm,username);
1389                 return FALSE;
1390         }
1391         return TRUE;
1392 }
1393
1394 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1395         SalOp *op;
1396         const char *username,*realm;
1397         op=find_op(sal,ev);
1398         if (op==NULL){
1399                 ms_warning("No operation associated with this authentication_ok!");
1400                 return ;
1401         }
1402         if (op->pending_auth){
1403                 eXosip_event_free(op->pending_auth);
1404                 sal_remove_pending_auth(sal,op);
1405                 op->pending_auth=NULL;
1406         }
1407         if (get_auth_data(ev,&realm,&username)==0){
1408                 sal->callbacks.auth_success(op,realm,username);
1409         }
1410 }
1411
1412 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1413         SalOp *op;
1414         int code=0;
1415         char* computedReason=NULL;
1416         const char *reason=NULL;
1417         SalError error=SalErrorUnknown;
1418         SalReason sr=SalReasonUnknown;
1419         
1420
1421         op=(SalOp*)find_op(sal,ev);
1422
1423         if (op==NULL) {
1424                 ms_warning("Call failure reported for a closed call, ignored.");
1425                 return TRUE;
1426         }
1427
1428         if (ev->response){
1429                 code=osip_message_get_status_code(ev->response);
1430                 reason=osip_message_get_reason_phrase(ev->response);
1431                 osip_header_t *h=NULL;
1432                 if (!osip_message_header_get_byname(    ev->response
1433                                                                                         ,"Reason"
1434                                                                                         ,0
1435                                                                                         ,&h)) {
1436                         computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1437                         reason = computedReason;
1438
1439                 }
1440         }
1441         switch(code)
1442         {
1443                 case 401:
1444                 case 407:
1445                         return process_authentication(sal,ev);
1446                         break;
1447                 case 400:
1448                         error=SalErrorUnknown;
1449                 break;
1450                 case 404:
1451                         error=SalErrorFailure;
1452                         sr=SalReasonNotFound;
1453                 break;
1454                 case 415:
1455                         error=SalErrorFailure;
1456                         sr=SalReasonMedia;
1457                 break;
1458                 case 422:
1459                         eXosip_default_action(ev);
1460                         return TRUE;
1461                 break;
1462                 case 480:
1463                         error=SalErrorFailure;
1464                         sr=SalReasonTemporarilyUnavailable;
1465                 case 486:
1466                         error=SalErrorFailure;
1467                         sr=SalReasonBusy;
1468                 break;
1469                 case 487:
1470                 break;
1471                 case 600:
1472                         error=SalErrorFailure;
1473                         sr=SalReasonDoNotDisturb;
1474                 break;
1475                 case 603:
1476                         error=SalErrorFailure;
1477                         sr=SalReasonDeclined;
1478                 break;
1479                 default:
1480                         if (code>0){
1481                                 error=SalErrorFailure;
1482                                 sr=SalReasonUnknown;
1483                         }else error=SalErrorNoResponse;
1484         }
1485         op->terminated=TRUE;
1486         sal->callbacks.call_failure(op,error,sr,reason,code);
1487         if (computedReason != NULL){
1488                 ms_free(computedReason);
1489         }
1490         return TRUE;
1491 }
1492
1493 /* Request remote side to send us VFU */
1494 void sal_call_send_vfu_request(SalOp *h){
1495         osip_message_t *msg=NULL;
1496         char info_body[] =
1497                         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1498                          "<media_control>"
1499                          "  <vc_primitive>"
1500                          "    <to_encoder>"
1501                          "      <picture_fast_update></picture_fast_update>"
1502                          "    </to_encoder>"
1503                          "  </vc_primitive>"
1504                          "</media_control>";
1505
1506         char clen[10];
1507
1508         eXosip_lock();
1509         eXosip_call_build_info(h->did,&msg);
1510         if (msg){
1511                 osip_message_set_body(msg,info_body,strlen(info_body));
1512                 osip_message_set_content_type(msg,"application/media_control+xml");
1513                 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1514                 osip_message_set_content_length(msg,clen);
1515                 eXosip_call_send_request(h->did,msg);
1516                 ms_message("Sending VFU request !");
1517         }
1518         eXosip_unlock();
1519 }
1520
1521 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1522         SalOp *op=find_op(sal,ev);
1523         osip_body_t *body=NULL;
1524
1525         if (op==NULL){
1526                 ms_warning("media control xml received without operation context!");
1527                 return ;
1528         }
1529         
1530         osip_message_get_body(ev->request,0,&body);
1531         if (body && body->body!=NULL &&
1532                 strstr(body->body,"picture_fast_update")){
1533                 osip_message_t *ans=NULL;
1534                 ms_message("Receiving VFU request !");
1535                 if (sal->callbacks.vfu_request){
1536                         sal->callbacks.vfu_request(op);
1537                         eXosip_call_build_answer(ev->tid,200,&ans);
1538                         if (ans)
1539                                 eXosip_call_send_answer(ev->tid,200,ans);
1540                         return;
1541                 }
1542         }
1543         /*in all other cases we must say it is not implemented.*/
1544         {
1545                 osip_message_t *ans=NULL;
1546                 eXosip_lock();
1547                 eXosip_call_build_answer(ev->tid,501,&ans);
1548                 if (ans)
1549                         eXosip_call_send_answer(ev->tid,501,ans);
1550                 eXosip_unlock();
1551         }
1552 }
1553
1554 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1555         SalOp *op=find_op(sal,ev);
1556         osip_body_t *body=NULL;
1557
1558         if (op==NULL){
1559                 ms_warning("media dtmf relay received without operation context!");
1560                 return ;
1561         }
1562         
1563         osip_message_get_body(ev->request,0,&body);
1564         if (body && body->body!=NULL){
1565                 osip_message_t *ans=NULL;
1566                 const char *name=strstr(body->body,"Signal");
1567                 if (name==NULL) name=strstr(body->body,"signal");
1568                 if (name==NULL) {
1569                         ms_warning("Could not extract the dtmf name from the SIP INFO.");
1570                 }else{
1571                         char tmp[2];
1572                         name+=strlen("signal");
1573                         if (sscanf(name," = %1s",tmp)==1){
1574                                 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1575                                 if (sal->callbacks.dtmf_received != NULL)
1576                                         sal->callbacks.dtmf_received(op, tmp[0]);
1577                         }
1578                 }
1579                 eXosip_lock();
1580                 eXosip_call_build_answer(ev->tid,200,&ans);
1581                 if (ans)
1582                         eXosip_call_send_answer(ev->tid,200,ans);
1583                 eXosip_unlock();
1584         }
1585 }
1586
1587 static void fill_options_answer(osip_message_t *options){
1588         osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1589         osip_message_set_accept(options,"application/sdp");
1590 }
1591
1592 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1593         osip_header_t *h=NULL;
1594         osip_message_t *ans=NULL;
1595         ms_message("Receiving REFER request !");
1596         osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1597
1598         if (h){
1599                 osip_from_t *from=NULL;
1600                 char *tmp;
1601                 osip_from_init(&from);
1602         
1603                 if (osip_from_parse(from,h->hvalue)==0){
1604                         if (op ){
1605                                 osip_uri_header_t *uh=NULL;
1606                                 osip_header_t *referred_by=NULL;
1607                                 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1608                                 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1609                                         ms_message("Found replaces in Refer-To");
1610                                         if (op->replaces){
1611                                                 ms_free(op->replaces);
1612                                         }
1613                                         op->replaces=ms_strdup(uh->gvalue);
1614                                 }
1615                                 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1616                                 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1617                                         if (op->referred_by)
1618                                                 ms_free(op->referred_by);
1619                                         op->referred_by=ms_strdup(referred_by->hvalue);
1620                                 }
1621                         }
1622                         osip_uri_header_freelist(&from->url->url_headers);
1623                         osip_from_to_str(from,&tmp);
1624                         sal->callbacks.refer_received(sal,op,tmp);
1625                         osip_free(tmp);
1626                         osip_from_free(from);
1627                 }
1628                 eXosip_lock();
1629                 eXosip_call_build_answer(ev->tid,202,&ans);
1630                 if (ans)
1631                         eXosip_call_send_answer(ev->tid,202,ans);
1632                 eXosip_unlock();
1633         }
1634         else
1635         {
1636                 ms_warning("cannot do anything with the refer without destination\n");
1637         }
1638 }
1639
1640 static void process_notify(Sal *sal, eXosip_event_t *ev){
1641         osip_header_t *h=NULL;
1642         char *from=NULL;
1643         SalOp *op=find_op(sal,ev);
1644         osip_message_t *ans=NULL;
1645
1646         ms_message("Receiving NOTIFY request !");
1647         osip_from_to_str(ev->request->from,&from);
1648         osip_message_header_get_byname(ev->request,"Event",0,&h);
1649         if(h){
1650                 osip_body_t *body=NULL;
1651                 //osip_content_type_t *ct=NULL;
1652                 osip_message_get_body(ev->request,0,&body);
1653                 //ct=osip_message_get_content_type(ev->request);
1654                 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1655                         /*special handling of refer events*/
1656                         if (body && body->body){
1657                                 osip_message_t *msg;
1658                                 osip_message_init(&msg);
1659                                 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1660                                         int code=osip_message_get_status_code(msg);
1661                                         if (code==100){
1662                                                 sal->callbacks.notify_refer(op,SalReferTrying);
1663                                         }else if (code==200){
1664                                                 sal->callbacks.notify_refer(op,SalReferSuccess);
1665                                         }else if (code>=400){
1666                                                 sal->callbacks.notify_refer(op,SalReferFailed);
1667                                         }
1668                                 }
1669                                 osip_message_free(msg);
1670                         }
1671                 }else{
1672                         /*generic handling*/
1673                         sal->callbacks.notify(op,from,h->hvalue);
1674                 }
1675         }
1676         /*answer that we received the notify*/
1677         eXosip_lock();
1678         eXosip_call_build_answer(ev->tid,200,&ans);
1679         if (ans)
1680                 eXosip_call_send_answer(ev->tid,200,ans);
1681         eXosip_unlock();
1682         osip_free(from);
1683 }
1684
1685 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1686         osip_message_t *ans=NULL;
1687         if (ev->request){
1688                 if (MSG_IS_INFO(ev->request)){
1689                         osip_content_type_t *ct;
1690                         ct=osip_message_get_content_type(ev->request);
1691                         if (ct && ct->subtype){
1692                                 if (strcmp(ct->subtype,"media_control+xml")==0)
1693                                         process_media_control_xml(sal,ev);
1694                                 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1695                                         process_dtmf_relay(sal,ev);
1696                                 else {
1697                                         ms_message("Unhandled SIP INFO.");
1698                                         /*send an "Not implemented" answer*/
1699                                         eXosip_lock();
1700                                         eXosip_call_build_answer(ev->tid,501,&ans);
1701                                         if (ans)
1702                                                 eXosip_call_send_answer(ev->tid,501,ans);
1703                                         eXosip_unlock();
1704                                 }
1705                         }else{
1706                                 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1707                                 eXosip_lock();
1708                                 eXosip_call_build_answer(ev->tid,200,&ans);
1709                                 if (ans)
1710                                         eXosip_call_send_answer(ev->tid,200,ans);
1711                                 eXosip_unlock();
1712                         }
1713                 }else if(MSG_IS_MESSAGE(ev->request)){
1714                         /* SIP messages could be received into call */
1715                         text_received(sal, ev);
1716                         eXosip_lock();
1717                         eXosip_call_build_answer(ev->tid,200,&ans);
1718                         if (ans)
1719                                 eXosip_call_send_answer(ev->tid,200,ans);
1720                         eXosip_unlock();
1721                 }else if(MSG_IS_REFER(ev->request)){
1722                         SalOp *op=find_op(sal,ev);
1723                         
1724                         ms_message("Receiving REFER request !");
1725                         process_refer(sal,op,ev);
1726                 }else if(MSG_IS_NOTIFY(ev->request)){
1727                         process_notify(sal,ev);
1728                 }else if (MSG_IS_OPTIONS(ev->request)){
1729                         eXosip_lock();
1730                         eXosip_call_build_answer(ev->tid,200,&ans);
1731                         if (ans){
1732                                 fill_options_answer(ans);
1733                                 eXosip_call_send_answer(ev->tid,200,ans);
1734                         }
1735                         eXosip_unlock();
1736                 }
1737         }else ms_warning("call_message_new: No request ?");
1738 }
1739
1740 static void inc_update(Sal *sal, eXosip_event_t *ev){
1741         osip_message_t *msg=NULL;
1742         ms_message("Processing incoming UPDATE");
1743         eXosip_lock();
1744         eXosip_message_build_answer(ev->tid,200,&msg);
1745         if (msg!=NULL)
1746                 eXosip_message_send_answer(ev->tid,200,msg);
1747         eXosip_unlock();
1748 }
1749
1750 static bool_t comes_from_local_if(osip_message_t *msg){
1751         osip_via_t *via=NULL;
1752         osip_message_get_via(msg,0,&via);
1753         if (via){
1754                 const char *host;
1755                 host=osip_via_get_host(via);
1756                 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1757                         osip_generic_param_t *param=NULL;
1758                         osip_via_param_get_byname(via,"received",&param);
1759                         if (param==NULL) return TRUE;
1760                         if (param->gvalue &&
1761                                 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1762                                 return TRUE;
1763                         }
1764                 }
1765         }
1766         return FALSE;
1767 }
1768
1769 static void text_received(Sal *sal, eXosip_event_t *ev){
1770         osip_body_t *body=NULL;
1771         char *from=NULL,*msg=NULL;
1772         osip_content_type_t* content_type;
1773         osip_uri_param_t* external_body_url; 
1774         char unquoted_external_body_url [256];
1775         int external_body_size=0;
1776         SalMessage salmsg;
1777         char message_id[256]={0};
1778         
1779         content_type= osip_message_get_content_type(ev->request);
1780         if (!content_type) {
1781                 ms_error("Could not get message because no content type");
1782                 return;
1783         }
1784         osip_from_to_str(ev->request->from,&from);
1785         if (content_type->type 
1786                 && strcmp(content_type->type, "text")==0 
1787                 && content_type->subtype
1788                 && strcmp(content_type->subtype, "plain")==0 ) {
1789                 osip_message_get_body(ev->request,0,&body);
1790                 if (body==NULL){
1791                         ms_error("Could not get text message from SIP body");
1792                         osip_free(from);
1793                         return;
1794                 }
1795                 msg=body->body;
1796         }else if (content_type->type 
1797                   && strcmp(content_type->type, "message")==0 
1798                   && content_type->subtype
1799                   && strcmp(content_type->subtype, "external-body")==0 ) {
1800                 
1801                 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1802                 /*remove both first and last character*/
1803                 strncpy(unquoted_external_body_url
1804                                 ,&external_body_url->gvalue[1]
1805                                 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1806                 unquoted_external_body_url[external_body_size-1]='\0';
1807         } else {
1808                 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1809                 osip_free(from);
1810                 return;
1811         }
1812         snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1813         
1814         salmsg.from=from;
1815         salmsg.text=msg;
1816         salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1817         salmsg.message_id=message_id;
1818         sal->callbacks.text_received(sal,&salmsg);
1819         osip_free(from);
1820 }
1821
1822
1823
1824 static void other_request(Sal *sal, eXosip_event_t *ev){
1825         ms_message("in other_request");
1826         if (ev->request==NULL) return;
1827         if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1828                 text_received(sal,ev);
1829                 eXosip_message_send_answer(ev->tid,200,NULL);
1830         }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1831                 osip_message_t *options=NULL;
1832                 eXosip_options_build_answer(ev->tid,200,&options);
1833                 fill_options_answer(options);
1834                 eXosip_options_send_answer(ev->tid,200,options);
1835         }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1836                 ms_message("Receiving REFER request !");
1837                 if (comes_from_local_if(ev->request)) {
1838                         process_refer(sal,NULL,ev);
1839                 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1840         }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1841                 inc_update(sal,ev);
1842         }else {
1843                 char *tmp=NULL;
1844                 size_t msglen=0;
1845                 osip_message_to_str(ev->request,&tmp,&msglen);
1846                 if (tmp){
1847                         ms_message("Unsupported request received:\n%s",tmp);
1848                         osip_free(tmp);
1849                 }
1850                 /*answer with a 501 Not implemented*/
1851                 eXosip_message_send_answer(ev->tid,501,NULL);
1852         }
1853 }
1854
1855 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1856         osip_via_t *via=NULL;
1857         osip_message_get_via(msg,0,&via);
1858         if (via){
1859                 osip_free(via->port);
1860                 via->port=osip_strdup(port);
1861                 osip_free(via->host);
1862                 via->host=osip_strdup(ip);
1863         }
1864 }
1865
1866
1867 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1868         osip_contact_t *ctt=NULL;
1869         const char *received;
1870         int rport;
1871         SalTransport transport;
1872         char port[20];
1873
1874         if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1875         osip_message_get_contact(request,0,&ctt);
1876         if (ctt == NULL) {
1877                 ms_warning("fix_message_contact(): no contact to update");
1878                 return FALSE;
1879         }
1880         if (expire_last_contact){
1881                 osip_contact_t *oldct=NULL,*prevct;
1882                 osip_generic_param_t *param=NULL;
1883                 osip_contact_clone(ctt,&oldct);
1884                 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1885                         osip_contact_free(prevct);
1886                         osip_list_remove(&request->contacts,1);
1887                 }
1888                 osip_list_add(&request->contacts,oldct,1);
1889                 osip_contact_param_get_byname(oldct,"expires",&param);
1890                 if (param){
1891                         if (param->gvalue) osip_free(param->gvalue);
1892                         param->gvalue=osip_strdup("0");
1893                 }else{
1894                         osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1895                 }
1896         }
1897         if (ctt->url->host!=NULL){
1898                 osip_free(ctt->url->host);
1899         }
1900         ctt->url->host=osip_strdup(received);
1901         if (ctt->url->port!=NULL){
1902                 osip_free(ctt->url->port);
1903         }
1904         snprintf(port,sizeof(port),"%i",rport);
1905         ctt->url->port=osip_strdup(port);
1906         if (op->masquerade_via) masquerade_via(request,received,port);
1907
1908         if (transport != SalTransportUDP) {
1909                 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport)); 
1910         }
1911         return TRUE;    
1912 }
1913
1914 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1915         osip_contact_t *ctt=NULL;
1916         SalAddress* ori_contact_address=NULL;
1917         const char *received;
1918         int rport;
1919         SalTransport transport;
1920         char* tmp;
1921         osip_message_t *msg=NULL;
1922         Sal* sal=op->base.root;
1923         int i=0;
1924         bool_t found_valid_contact=FALSE;
1925         bool_t from_request=FALSE;
1926
1927         if (sal->double_reg==FALSE ) return FALSE; 
1928
1929         if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1930         do{
1931                 ctt=NULL;
1932                 osip_message_get_contact(last_answer,i,&ctt);
1933                 if (!from_request && ctt==NULL) {
1934                         osip_message_get_contact(orig_request,0,&ctt);
1935                         from_request=TRUE;
1936                 }
1937                 if (ctt){
1938                         osip_contact_to_str(ctt,&tmp);
1939                         ori_contact_address = sal_address_new(tmp);
1940         
1941                         /*check if contact is up to date*/
1942                         if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0 
1943                                 && sal_address_get_port_int(ori_contact_address) == rport
1944                         && sal_address_get_transport(ori_contact_address) == transport) {
1945                                 if (!from_request){
1946                                         ms_message("Register response has up to date contact, doing nothing.");
1947                                 }else {
1948                                         ms_warning("Register response does not have up to date contact, but last request had."
1949                                                 "Stupid registrar detected, giving up.");
1950                                 }
1951                                 found_valid_contact=TRUE;
1952                         }
1953                         osip_free(tmp);
1954                         sal_address_destroy(ori_contact_address);
1955                 }else break;
1956                 i++;
1957         }while(!found_valid_contact);
1958         if (!found_valid_contact)
1959                 ms_message("Contact do not match, resending register.");
1960         else return FALSE;
1961
1962         eXosip_lock();
1963         eXosip_register_build_register(op->rid,op->expires,&msg);
1964         if (msg==NULL){
1965             eXosip_unlock();
1966             ms_warning("Fail to create a contact updated register.");
1967             return FALSE;
1968         }
1969         if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1970                 eXosip_register_send_register(op->rid,msg);
1971                 eXosip_unlock();  
1972                 ms_message("Resending new register with updated contact");
1973                 update_contact_from_response(op,last_answer);
1974                 return TRUE;
1975         } else {
1976             ms_warning("Fail to send updated register.");
1977             eXosip_unlock();
1978             return FALSE;
1979         }
1980         eXosip_unlock();
1981         return FALSE;
1982 }
1983
1984 static void registration_success(Sal *sal, eXosip_event_t *ev){
1985         SalOp *op=sal_find_register(sal,ev->rid);
1986         osip_header_t *h=NULL;
1987         bool_t registered;
1988         if (op==NULL){
1989                 ms_error("Receiving register response for unknown operation");
1990                 return;
1991         }
1992         osip_message_get_expires(ev->request,0,&h);
1993         if (h!=NULL && atoi(h->hvalue)!=0){
1994                 registered=TRUE;
1995                 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1996                         sal->callbacks.register_success(op,registered);
1997                 }
1998         }else {
1999                 sal->callbacks.register_success(op,FALSE);
2000         }
2001 }
2002
2003 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
2004         int status_code=0;
2005         const char *reason=NULL;
2006         SalOp *op=sal_find_register(sal,ev->rid);
2007         SalReason sr=SalReasonUnknown;
2008         SalError se=SalErrorUnknown;
2009         
2010         if (op==NULL){
2011                 ms_error("Receiving register failure for unknown operation");
2012                 return TRUE;
2013         }
2014         if (ev->response){
2015                 status_code=osip_message_get_status_code(ev->response);
2016                 reason=osip_message_get_reason_phrase(ev->response);
2017         }
2018         switch(status_code){
2019                 case 401:
2020                 case 407:
2021                         return process_authentication(sal,ev);
2022                         break;
2023                 case 423: /*interval too brief*/
2024                         {/*retry with greater interval */
2025                                 osip_header_t *h=NULL;
2026                                 osip_message_t *msg=NULL;
2027                                 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
2028                                 if (h && h->hvalue && h->hvalue[0]!='\0'){
2029                                         int val=atoi(h->hvalue);
2030                                         if (val>op->expires)
2031                                                 op->expires=val;
2032                                 }else op->expires*=2;
2033                                 eXosip_lock();
2034                                 eXosip_register_build_register(op->rid,op->expires,&msg);
2035                                 eXosip_register_send_register(op->rid,msg);
2036                                 eXosip_unlock();
2037                         }
2038                 break;
2039                 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2040                                  in vias, such as ekiga.net 
2041                                  On the opposite, freephonie.net bugs when via are masqueraded.
2042                                  */
2043                         op->masquerade_via=TRUE;
2044                 default:
2045                         /* if contact is up to date, process the failure, otherwise resend a new register with
2046                                 updated contact first, just in case the faillure is due to incorrect contact */
2047                         if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2048                                 return TRUE; /*we are retrying with an updated contact*/
2049                         if (status_code==403){
2050                                 se=SalErrorFailure;
2051                                 sr=SalReasonForbidden;
2052                         }else if (status_code==0){
2053                                 se=SalErrorNoResponse;
2054                         }
2055                         sal->callbacks.register_failure(op,se,sr,reason);
2056         }
2057         return TRUE;
2058 }
2059
2060 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2061         SalOp *op=find_op(sal,ev);
2062         if (op==NULL){
2063                 ms_warning("other_request_reply(): Receiving response to unknown request.");
2064                 return;
2065         }
2066         if (ev->response){
2067                 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2068                 update_contact_from_response(op,ev->response);
2069                 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2070                         sal->callbacks.ping_reply(op);
2071         }
2072         if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2073                 /*out of call message acknolegment*/
2074                 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2075                 if (ev->response){
2076                         if (ev->response->status_code<200){
2077                                 status=SalTextDeliveryInProgress;
2078                         }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2079                                 status=SalTextDeliveryDone;
2080                         }
2081                 }
2082                 sal->callbacks.text_delivery_update(op,status);
2083         }
2084 }
2085
2086 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2087         SalOp *op=find_op(sal,ev);
2088         if (ev->response){
2089                 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2090                         if (op->sipfrag_pending){
2091                                 send_notify_for_refer(op->did,op->sipfrag_pending);
2092                                 op->sipfrag_pending=NULL;
2093                         }
2094                 }
2095         }
2096 }
2097
2098 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2099         ms_message("linphone process event get a message %d\n",ev->type);
2100         switch(ev->type){
2101                 case EXOSIP_CALL_ANSWERED:
2102                         ms_message("CALL_ANSWERED\n");
2103                         call_accepted(sal,ev);
2104                         authentication_ok(sal,ev);
2105                         break;
2106                 case EXOSIP_CALL_CLOSED:
2107                 case EXOSIP_CALL_CANCELLED:
2108                         ms_message("CALL_CLOSED or CANCELLED\n");
2109                         call_terminated(sal,ev);
2110                         break;
2111                 case EXOSIP_CALL_TIMEOUT:
2112                 case EXOSIP_CALL_NOANSWER:
2113                         ms_message("CALL_TIMEOUT or NOANSWER\n");
2114                         return call_failure(sal,ev);
2115                         break;
2116                 case EXOSIP_CALL_REQUESTFAILURE:
2117                 case EXOSIP_CALL_GLOBALFAILURE:
2118                 case EXOSIP_CALL_SERVERFAILURE:
2119                         ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2120                         return call_failure(sal,ev);
2121                         break;
2122                 case EXOSIP_CALL_RELEASED:
2123                         ms_message("CALL_RELEASED\n");
2124                         call_released(sal, ev);
2125                         break;
2126                 case EXOSIP_CALL_INVITE:
2127                         ms_message("CALL_NEW\n");
2128                         inc_new_call(sal,ev);
2129                         break;
2130                 case EXOSIP_CALL_REINVITE:
2131                         handle_reinvite(sal,ev);
2132                         break;
2133                 case EXOSIP_CALL_ACK:
2134                         ms_message("CALL_ACK");
2135                         handle_ack(sal,ev);
2136                         break;
2137                 case EXOSIP_CALL_REDIRECTED:
2138                         ms_message("CALL_REDIRECTED");
2139                         eXosip_default_action(ev);
2140                         break;
2141                 case EXOSIP_CALL_PROCEEDING:
2142                         ms_message("CALL_PROCEEDING");
2143                         call_proceeding(sal,ev);
2144                         break;
2145                 case EXOSIP_CALL_RINGING:
2146                         ms_message("CALL_RINGING");
2147                         call_ringing(sal,ev);
2148                         authentication_ok(sal,ev);
2149                         break;
2150                 case EXOSIP_CALL_MESSAGE_NEW:
2151                         ms_message("EXOSIP_CALL_MESSAGE_NEW");
2152                         call_message_new(sal,ev);
2153                         break;
2154                 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2155                         if (ev->response &&
2156                                 (ev->response->status_code==407 || ev->response->status_code==401)){
2157                                  return process_authentication(sal,ev);
2158                         }
2159                         break;
2160                 case EXOSIP_CALL_MESSAGE_ANSWERED:
2161                         ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2162                         process_in_call_reply(sal,ev);
2163                 break;
2164                 case EXOSIP_IN_SUBSCRIPTION_NEW:
2165                         ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2166                         sal_exosip_subscription_recv(sal,ev);
2167                         break;
2168                 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2169                         ms_message("CALL_SUBSCRIPTION_NEW ");
2170                         sal_exosip_in_subscription_closed(sal,ev);
2171                         break;
2172                 case EXOSIP_SUBSCRIPTION_UPDATE:
2173                         ms_message("CALL_SUBSCRIPTION_UPDATE");
2174                         break;
2175                 case EXOSIP_SUBSCRIPTION_NOTIFY:
2176                         ms_message("CALL_SUBSCRIPTION_NOTIFY");
2177                         sal_exosip_notify_recv(sal,ev);
2178                         break;
2179                 case EXOSIP_SUBSCRIPTION_ANSWERED:
2180                         ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2181                         sal_exosip_subscription_answered(sal,ev);
2182                         break;
2183                 case EXOSIP_SUBSCRIPTION_CLOSED:
2184                         ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2185                         sal_exosip_subscription_closed(sal,ev);
2186                         break;
2187                 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE:   /**< announce a request failure      */
2188                         if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2189                                 return process_authentication(sal,ev);
2190                         }
2191                 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2192                 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2193                         sal_exosip_subscription_closed(sal,ev);
2194                         break;
2195                 case EXOSIP_REGISTRATION_FAILURE:
2196                         ms_message("REGISTRATION_FAILURE\n");
2197                         return registration_failure(sal,ev);
2198                         break;
2199                 case EXOSIP_REGISTRATION_SUCCESS:
2200                         authentication_ok(sal,ev);
2201                         registration_success(sal,ev);
2202                         break;
2203                 case EXOSIP_MESSAGE_NEW:
2204                         other_request(sal,ev);
2205                         break;
2206                 case EXOSIP_MESSAGE_PROCEEDING:
2207                 case EXOSIP_MESSAGE_ANSWERED:
2208                 case EXOSIP_MESSAGE_REDIRECTED:
2209                 case EXOSIP_MESSAGE_SERVERFAILURE:
2210                 case EXOSIP_MESSAGE_GLOBALFAILURE:
2211                         other_request_reply(sal,ev);
2212                         break;
2213                 case EXOSIP_MESSAGE_REQUESTFAILURE:
2214                 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2215                         if (ev->response) {
2216                                 switch (ev->response->status_code) {
2217                                         case 407:
2218                                         case 401:
2219                                                 return process_authentication(sal,ev);
2220                                         case 412: {
2221                                                 eXosip_automatic_action ();
2222                                                 return 1;
2223                                         }
2224                                 }
2225                         }
2226                         other_request_reply(sal,ev);
2227                         break;
2228                 default:
2229                         ms_message("Unhandled exosip event ! %i",ev->type);
2230                         break;
2231         }
2232         return TRUE;
2233 }
2234
2235 int sal_iterate(Sal *sal){
2236         eXosip_event_t *ev;
2237         while((ev=eXosip_event_wait(0,0))!=NULL){
2238                 if (process_event(sal,ev))
2239                         eXosip_event_free(ev);
2240         }
2241 #ifdef HAVE_EXOSIP_TRYLOCK
2242         if (eXosip_trylock()==0){
2243                 eXosip_automatic_refresh();
2244                 eXosip_unlock();
2245         }else{
2246                 ms_warning("eXosip_trylock busy.");
2247         }
2248 #else
2249         eXosip_lock();
2250         eXosip_automatic_refresh();
2251         eXosip_unlock();
2252 #endif
2253         return 0;
2254 }
2255
2256 static void register_set_contact(osip_message_t *msg, const char *contact){
2257         osip_uri_param_t *param = NULL;
2258         osip_contact_t *ct=NULL;
2259         char *line=NULL;
2260         /*we get the line parameter choosed by exosip, and add it to our own contact*/
2261         osip_message_get_contact(msg,0,&ct);
2262         if (ct!=NULL){
2263                 osip_uri_uparam_get_byname(ct->url, "line", &param);
2264                 if (param && param->gvalue)
2265                         line=osip_strdup(param->gvalue);
2266         }
2267         _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2268         osip_message_set_contact(msg,contact);
2269         osip_message_get_contact(msg,0,&ct);
2270         osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2271 }
2272
2273 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2274         osip_route_t *route;
2275
2276         osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2277         
2278         osip_route_init(&route);
2279         if (osip_route_parse(route,proxy)==0){
2280                 osip_uri_param_t *lr_param = NULL;
2281                 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2282                 if (lr_param == NULL){
2283                         osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2284                 }
2285                 osip_list_add(&msg->routes,route,0);
2286                 return;
2287         }
2288         osip_route_free(route);
2289 }
2290
2291
2292 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2293         osip_message_t *msg;
2294         const char *contact=sal_op_get_contact(h);
2295
2296         sal_op_set_route(h,proxy);
2297         if (h->rid==-1){
2298                 SalAddress *from_parsed=sal_address_new(from);
2299                 char domain[256];
2300                 char *uri, *domain_ptr = NULL;
2301                 if (from_parsed==NULL) {
2302                         ms_warning("sal_register() bad from %s",from);
2303                         return -1;
2304                 }
2305                 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2306                    using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2307                 uri = sal_address_as_string_uri_only(from_parsed);
2308                 if (uri) domain_ptr = strchr(uri, '@');
2309                 if (domain_ptr) {
2310                         snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2311                 } else {
2312                         snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2313                 }
2314                 if (uri) ms_free(uri);
2315                 sal_address_destroy(from_parsed);
2316                 eXosip_lock();
2317                 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2318                 if (msg){
2319                         if (contact) register_set_contact(msg,contact);
2320                         sal_register_add_route(msg,proxy);
2321                         sal_add_register(h->base.root,h);
2322                 }else{
2323                         ms_error("Could not build initial register.");
2324                         eXosip_unlock();
2325                         return -1;
2326                 }
2327         }else{
2328                 eXosip_lock();
2329                 eXosip_register_build_register(h->rid,expires,&msg);
2330                 sal_register_add_route(msg,proxy);
2331         }
2332         if (msg){
2333                 eXosip_register_send_register(h->rid,msg);
2334         }
2335         eXosip_unlock();
2336         h->expires=expires;
2337         return (msg != NULL) ? 0 : -1;
2338 }
2339
2340 int sal_register_refresh(SalOp *op, int expires){
2341         osip_message_t *msg=NULL;
2342         const char *contact=sal_op_get_contact(op);
2343         
2344         if (op->rid==-1){
2345                 ms_error("Unexistant registration context, not possible to refresh.");
2346                 return -1;
2347         }
2348 #ifdef HAVE_EXOSIP_TRYLOCK
2349         {
2350                 int tries=0;
2351                 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2352                 * In order to prevent this case that can occur when the exosip thread is busy with DNS while network isn't in a good shape, we try to take
2353                 * the exosip lock in a non blocking way, and give up if it takes too long*/
2354                 while (eXosip_trylock()!=0){
2355                         ms_usleep(100000);
2356                         if (tries>30) {/*after 3 seconds, give up*/
2357                                 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2358                                 return -1;
2359                         }
2360                 }
2361         }
2362 #else
2363         eXosip_lock();
2364 #endif
2365         eXosip_register_build_register(op->rid,expires,&msg);
2366         if (msg!=NULL){
2367                 if (contact) register_set_contact(msg,contact);
2368                 sal_register_add_route(msg,sal_op_get_route(op));
2369                 eXosip_register_send_register(op->rid,msg);
2370         }else ms_error("Could not build REGISTER refresh message.");
2371         eXosip_unlock();
2372         return (msg != NULL) ? 0 : -1;
2373 }
2374
2375
2376 int sal_unregister(SalOp *h){
2377         osip_message_t *msg=NULL;
2378         eXosip_lock();
2379         eXosip_register_build_register(h->rid,0,&msg);
2380         if (msg) eXosip_register_send_register(h->rid,msg);
2381         else ms_warning("Could not build unREGISTER !");
2382         eXosip_unlock();
2383         return 0;
2384 }
2385
2386 SalAddress * sal_address_new(const char *uri){
2387         osip_from_t *from;
2388         osip_from_init(&from);
2389
2390         // Remove front spaces
2391         while (uri[0]==' ') {
2392                 uri++;
2393         }
2394                 
2395         if (osip_from_parse(from,uri)!=0){
2396                 osip_from_free(from);
2397                 return NULL;
2398         }
2399         if (from->displayname!=NULL && from->displayname[0]=='"'){
2400                 char *unquoted=osip_strdup_without_quote(from->displayname);
2401                 osip_free(from->displayname);
2402                 from->displayname=unquoted;
2403         }
2404         return (SalAddress*)from;
2405 }
2406
2407 SalAddress * sal_address_clone(const SalAddress *addr){
2408         osip_from_t *ret=NULL;
2409         osip_from_clone((osip_from_t*)addr,&ret);
2410         return (SalAddress*)ret;
2411 }
2412
2413 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2414
2415 const char *sal_address_get_scheme(const SalAddress *addr){
2416         const osip_from_t *u=(const osip_from_t*)addr;
2417         return null_if_empty(u->url->scheme);
2418 }
2419
2420 const char *sal_address_get_display_name(const SalAddress* addr){
2421         const osip_from_t *u=(const osip_from_t*)addr;
2422         return null_if_empty(u->displayname);
2423 }
2424
2425 const char *sal_address_get_username(const SalAddress *addr){
2426         const osip_from_t *u=(const osip_from_t*)addr;
2427         return null_if_empty(u->url->username);
2428 }
2429
2430 const char *sal_address_get_domain(const SalAddress *addr){
2431         const osip_from_t *u=(const osip_from_t*)addr;
2432         return null_if_empty(u->url->host);
2433 }
2434
2435 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2436         osip_from_t *u=(osip_from_t*)addr;
2437         if (u->displayname!=NULL){
2438                 osip_free(u->displayname);
2439                 u->displayname=NULL;
2440         }
2441         if (display_name!=NULL && display_name[0]!='\0'){
2442                 u->displayname=osip_strdup(display_name);
2443         }
2444 }
2445
2446 void sal_address_set_username(SalAddress *addr, const char *username){
2447         osip_from_t *uri=(osip_from_t*)addr;
2448         if (uri->url->username!=NULL){
2449                 osip_free(uri->url->username);
2450                 uri->url->username=NULL;
2451         }
2452         if (username)
2453                 uri->url->username=osip_strdup(username);
2454 }
2455
2456 void sal_address_set_domain(SalAddress *addr, const char *host){
2457         osip_from_t *uri=(osip_from_t*)addr;
2458         if (uri->url->host!=NULL){
2459                 osip_free(uri->url->host);
2460                 uri->url->host=NULL;
2461         }
2462         if (host)
2463                 uri->url->host=osip_strdup(host);
2464 }
2465
2466 void sal_address_set_port(SalAddress *addr, const char *port){
2467         osip_from_t *uri=(osip_from_t*)addr;
2468         if (uri->url->port!=NULL){
2469                 osip_free(uri->url->port);
2470                 uri->url->port=NULL;
2471         }
2472         if (port)
2473                 uri->url->port=osip_strdup(port);
2474 }
2475
2476 void sal_address_set_port_int(SalAddress *uri, int port){
2477         char tmp[12];
2478         if (port==5060){
2479                 /*this is the default, special case to leave the port field blank*/
2480                 sal_address_set_port(uri,NULL);
2481                 return;
2482         }
2483         snprintf(tmp,sizeof(tmp),"%i",port);
2484         sal_address_set_port(uri,tmp);
2485 }
2486
2487 void sal_address_clean(SalAddress *addr){
2488         osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2489         osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2490 }
2491
2492 char *sal_address_as_string(const SalAddress *u){
2493         char *tmp,*ret;
2494         osip_from_t *from=(osip_from_t *)u;
2495         char *old_displayname=NULL;
2496         /* hack to force use of quotes around the displayname*/
2497         if (from->displayname!=NULL
2498             && from->displayname[0]!='"'){
2499                 old_displayname=from->displayname;
2500                 from->displayname=osip_enquote(from->displayname);
2501         }
2502         osip_from_to_str(from,&tmp);
2503         if (old_displayname!=NULL){
2504                 ms_free(from->displayname);
2505                 from->displayname=old_displayname;
2506         }
2507         ret=ms_strdup(tmp);
2508         osip_free(tmp);
2509         return ret;
2510 }
2511
2512 char *sal_address_as_string_uri_only(const SalAddress *u){
2513         char *tmp=NULL,*ret;
2514         osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2515         ret=ms_strdup(tmp);
2516         osip_free(tmp);
2517         return ret;
2518 }
2519 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2520         osip_uri_param_t *param=NULL;
2521     osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,&param);
2522     if (param == NULL){
2523         osip_uri_uparam_add     (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2524     } else {
2525         osip_free(param->gvalue);
2526         param->gvalue=value ? osip_strdup(value) : NULL;
2527     }
2528     
2529 }
2530
2531 void sal_address_destroy(SalAddress *u){
2532         osip_from_free((osip_from_t*)u);
2533 }
2534
2535 void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
2536         ctx->tcp_tls_keepalive = enabled;
2537 }
2538
2539 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2540         switch (ctx->transport) {
2541                 case SalTransportUDP:
2542                         ctx->keepalive_period = value;
2543                         break;
2544                 case SalTransportTCP:
2545                 case SalTransportTLS:
2546                         if (ctx->tcp_tls_keepalive) ctx->keepalive_period = value;
2547                         else ctx->keepalive_period = -1;
2548                         break;
2549                 default:
2550                         break;
2551         }
2552         eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
2553 }
2554 unsigned int sal_get_keepalive_period(Sal *ctx) {
2555         return ctx->keepalive_period;
2556 }
2557
2558 const char * sal_address_get_port(const SalAddress *addr) {
2559         const osip_from_t *u=(const osip_from_t*)addr;
2560         return null_if_empty(u->url->port);
2561 }
2562
2563 int sal_address_get_port_int(const SalAddress *uri) {
2564         const char* port = sal_address_get_port(uri);
2565         if (port != NULL) {
2566                 return atoi(port);
2567         } else {
2568                 return 5060;
2569         }
2570 }
2571 SalTransport sal_address_get_transport(const SalAddress* addr) {
2572     const osip_from_t *u=(const osip_from_t*)addr;
2573     osip_uri_param_t *transport_param=NULL;
2574     osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2575     if (transport_param == NULL){
2576         return SalTransportUDP;
2577     }  else {
2578         return sal_transport_parse(transport_param->gvalue);
2579     }
2580 }
2581 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2582     sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2583 }
2584
2585 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2586 int sal_call_update(SalOp *h, const char *subject){
2587         int err=0;
2588         osip_message_t *reinvite=NULL;
2589
2590         eXosip_lock();
2591         if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2592                 eXosip_unlock();
2593                 return -1;
2594         }
2595         eXosip_unlock();
2596         osip_message_set_subject(reinvite,subject);
2597         osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2598         if (h->base.contact){
2599                 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2600                 osip_message_set_contact(reinvite,h->base.contact);
2601         }
2602         if (h->base.root->session_expires!=0){
2603                 osip_message_set_header(reinvite, "Session-expires", "200");
2604                 osip_message_set_supported(reinvite, "timer");
2605         }
2606         if (h->base.local_media){
2607                 h->sdp_offering=TRUE;
2608                 set_sdp_from_desc(reinvite,h->base.local_media);
2609         }else h->sdp_offering=FALSE;
2610         eXosip_lock();
2611         err = eXosip_call_send_request(h->did, reinvite);
2612         eXosip_unlock();
2613         return err;
2614 }
2615 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2616         ctx->reuse_authorization=value;
2617 }