]> sjero.net Git - linphone/blob - coreapi/sal_eXosip2.c
Add tcp_tls_keepalive configuration option to (de)activate SIP keepalive for TCP...
[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->nstreams;++i){
593                         if (h->result->streams[i].rtp_port>0){
594                                 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
595                                 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
596                                 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
597                                 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
598                                 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
599                                 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
600                                 
601                                 if (h->result->streams[i].proto == SalProtoRtpSavp) {
602                                         h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0]; 
603                                 }
604                         }
605                 }
606         }
607         
608 }
609
610 int sal_call_is_offerer(const SalOp *h){
611         return h->sdp_offering;
612 }
613
614 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
615         if (desc)
616                 sal_media_description_ref(desc);
617         if (h->base.local_media)
618                 sal_media_description_unref(h->base.local_media);
619         h->base.local_media=desc;
620         if (h->base.remote_media){
621                 /*case of an incoming call where we modify the local capabilities between the time
622                  * the call is ringing and it is accepted (for example if you want to accept without video*/
623                 /*reset the sdp answer so that it is computed again*/
624                 if (h->sdp_answer){
625                         sdp_message_free(h->sdp_answer);
626                         h->sdp_answer=NULL;
627                 }
628         }
629         return 0;
630 }
631
632 int sal_call(SalOp *h, const char *from, const char *to){
633         int err;
634         const char *route;
635         osip_message_t *invite=NULL;
636         osip_call_id_t *callid;
637         sal_op_set_from(h,from);
638         sal_op_set_to(h,to);
639         sal_exosip_fix_route(h);
640         
641         h->terminated = FALSE;
642
643         route = sal_op_get_route(h);
644         err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
645         if (err!=0){
646                 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
647                                 err, from, to, route);
648                 return -1;
649         }
650         osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
651         if (h->base.contact){
652                 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
653                 osip_message_set_contact(invite,h->base.contact);
654         }
655         if (h->base.root->session_expires!=0){
656                 osip_message_set_header(invite, "Session-expires", "200");
657                 osip_message_set_supported(invite, "timer");
658         }
659         if (h->base.local_media){
660                 h->sdp_offering=TRUE;
661                 set_sdp_from_desc(invite,h->base.local_media);
662         }else h->sdp_offering=FALSE;
663         if (h->replaces){
664                 osip_message_set_header(invite,"Replaces",h->replaces);
665                 if (h->referred_by)
666                         osip_message_set_header(invite,"Referred-By",h->referred_by);
667         }
668         
669         eXosip_lock();
670         err=eXosip_call_send_initial_invite(invite);
671         eXosip_unlock();
672         h->cid=err;
673         if (err<0){
674                 ms_error("Fail to send invite ! Error code %d", err);
675                 return -1;
676         }else{
677                 callid=osip_message_get_call_id(invite);
678                 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
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_replaces(SalOp *op, osip_message_t *req){
1021         osip_header_t *h=NULL;
1022
1023         if (op->replaces){
1024                 ms_free(op->replaces);
1025                 op->replaces=NULL;
1026         }
1027         osip_message_header_get_byname(req,"replaces",0,&h);
1028         if (h){
1029                 if (h->hvalue && h->hvalue[0]!='\0'){
1030                         op->replaces=ms_strdup(h->hvalue);
1031                 }
1032         }
1033 }
1034
1035 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1036         if (ev->cid>0){
1037                 return sal_find_call(sal,ev->cid);
1038         }
1039         if (ev->rid>0){
1040                 return sal_find_register(sal,ev->rid);
1041         }
1042         if (ev->sid>0){
1043                 return sal_find_out_subscribe(sal,ev->sid);
1044         }
1045         if (ev->nid>0){
1046                 return sal_find_in_subscribe(sal,ev->nid);
1047         }
1048         if (ev->response) return sal_find_other(sal,ev->response);
1049         else if (ev->request) return sal_find_other(sal,ev->request);
1050         return NULL;
1051 }
1052
1053 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1054         SalOp *op=sal_op_new(sal);
1055         osip_from_t *from,*to;
1056         osip_call_info_t *call_info;
1057         char *tmp;
1058         sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1059         osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1060         osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1061
1062         set_network_origin(op,ev->request);
1063         set_remote_ua(op,ev->request);
1064         set_replaces(op,ev->request);
1065         
1066         if (sdp){
1067                 op->sdp_offering=FALSE;
1068                 op->base.remote_media=sal_media_description_new();
1069                 sdp_to_media_description(sdp,op->base.remote_media);
1070                 sdp_message_free(sdp);
1071         }else op->sdp_offering=TRUE;
1072
1073         from=osip_message_get_from(ev->request);
1074         to=osip_message_get_to(ev->request);
1075         osip_from_to_str(from,&tmp);
1076         sal_op_set_from(op,tmp);
1077         osip_free(tmp);
1078         osip_from_to_str(to,&tmp);
1079         sal_op_set_to(op,tmp);
1080         osip_free(tmp);
1081
1082         osip_message_get_call_info(ev->request,0,&call_info);
1083         if(call_info)
1084         {
1085                 osip_call_info_to_str(call_info,&tmp);
1086                 if( strstr(tmp,"answer-after=") != NULL)
1087                 {
1088                         op->auto_answer_asked=TRUE;
1089                         ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1090                 }
1091                 osip_free(tmp);
1092         }
1093
1094         op->tid=ev->tid;
1095         op->cid=ev->cid;
1096         op->did=ev->did;
1097         sal_add_call(op->base.root,op);
1098         sal->callbacks.call_received(op);
1099 }
1100
1101 static void handle_reinvite(Sal *sal,  eXosip_event_t *ev){
1102         SalOp *op=find_op(sal,ev);
1103         sdp_message_t *sdp;
1104
1105         if (op==NULL) {
1106                 ms_warning("Reinvite for non-existing operation !");
1107                 return;
1108         }
1109         op->reinvite=TRUE;
1110         op->tid=ev->tid;
1111         sdp=eXosip_get_sdp_info(ev->request);
1112         if (op->base.remote_media){
1113                 sal_media_description_unref(op->base.remote_media);
1114                 op->base.remote_media=NULL;
1115         }
1116         if (op->result){
1117                 sal_media_description_unref(op->result);
1118                 op->result=NULL;
1119         }
1120         if (sdp){
1121                 op->sdp_offering=FALSE;
1122                 op->base.remote_media=sal_media_description_new();
1123                 sdp_to_media_description(sdp,op->base.remote_media);
1124                 sdp_message_free(sdp);
1125                 
1126         }else {
1127                 op->sdp_offering=TRUE;
1128         }
1129         sal->callbacks.call_updating(op);
1130 }
1131
1132 static void handle_ack(Sal *sal,  eXosip_event_t *ev){
1133         SalOp *op=find_op(sal,ev);
1134         sdp_message_t *sdp;
1135
1136         if (op==NULL) {
1137                 ms_warning("ack for non-existing call !");
1138                 return;
1139         }
1140         if (op->terminated) {
1141                 ms_warning("ack for terminated call, ignoring");
1142                 return;
1143         }
1144         
1145         if (op->sdp_offering){
1146                 sdp=eXosip_get_sdp_info(ev->ack);
1147                 if (sdp){
1148                         if (op->base.remote_media)
1149                                 sal_media_description_unref(op->base.remote_media);
1150                         op->base.remote_media=sal_media_description_new();
1151                         sdp_to_media_description(sdp,op->base.remote_media);
1152                         sdp_process(op);
1153                         sdp_message_free(sdp);
1154                 }
1155         }
1156         if (op->reinvite){
1157                 op->reinvite=FALSE;
1158         }
1159         sal->callbacks.call_ack(op);
1160 }
1161
1162 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1163         const char *received;
1164         int rport;
1165         SalTransport transport;
1166         if (extract_received_rport(response,&received,&rport,&transport)==0){
1167                 const char *contact=sal_op_get_contact(op);
1168                 if (!contact){
1169                         /*no contact given yet, use from instead*/
1170                         contact=sal_op_get_from(op);
1171                 }
1172                 if (contact){
1173                         SalAddress *addr=sal_address_new(contact);
1174                         char *tmp;
1175                         sal_address_set_domain(addr,received);
1176                         sal_address_set_port_int(addr,rport);
1177                         if (transport!=SalTransportUDP)
1178                                 sal_address_set_transport(addr,transport);
1179                         tmp=sal_address_as_string(addr);
1180                         ms_message("Contact address updated to %s",tmp);
1181                         sal_op_set_contact(op,tmp);
1182                         sal_address_destroy(addr);
1183                         ms_free(tmp);
1184                 }
1185         }
1186 }
1187
1188 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1189         SalOp *op=find_op(sal,ev);
1190
1191         if (op==NULL || op->terminated==TRUE) {
1192                 ms_warning("This call has been canceled.");
1193                 eXosip_lock();
1194                 eXosip_call_terminate(ev->cid,ev->did);
1195                 eXosip_unlock();
1196                 return -1;
1197         }
1198         if (ev->did>0)
1199                 op->did=ev->did;
1200         op->tid=ev->tid;
1201         
1202         /* update contact if received and rport are set by the server
1203          note: will only be used by remote for next INVITE, if any...*/
1204         update_contact_from_response(op,ev->response);
1205         return 0;
1206 }
1207
1208 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1209         sdp_message_t *sdp;
1210         SalOp *op=find_op(sal,ev);
1211         if (call_proceeding(sal, ev)==-1) return;
1212
1213         set_remote_ua(op,ev->response);
1214         sdp=eXosip_get_sdp_info(ev->response);
1215         if (sdp){
1216                 op->base.remote_media=sal_media_description_new();
1217                 sdp_to_media_description(sdp,op->base.remote_media);
1218                 sdp_message_free(sdp);
1219                 if (op->base.local_media) sdp_process(op);
1220         }
1221         sal->callbacks.call_ringing(op);
1222 }
1223
1224 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1225         sdp_message_t *sdp;
1226         osip_message_t *msg=NULL;
1227         SalOp *op=find_op(sal,ev);
1228         const char *contact;
1229         
1230         if (op==NULL || op->terminated==TRUE) {
1231                 ms_warning("This call has been already terminated.");
1232                 eXosip_lock();
1233                 eXosip_call_terminate(ev->cid,ev->did);
1234                 eXosip_unlock();
1235                 return ;
1236         }
1237
1238         op->did=ev->did;
1239         set_remote_ua(op,ev->response);
1240
1241         sdp=eXosip_get_sdp_info(ev->response);
1242         if (sdp){
1243                 op->base.remote_media=sal_media_description_new();
1244                 sdp_to_media_description(sdp,op->base.remote_media);
1245                 sdp_message_free(sdp);
1246                 if (op->base.local_media) sdp_process(op);
1247         }
1248         eXosip_call_build_ack(ev->did,&msg);
1249         if (msg==NULL) {
1250                 ms_warning("This call has been already terminated.");
1251                 eXosip_lock();
1252                 eXosip_call_terminate(ev->cid,ev->did);
1253                 eXosip_unlock();
1254                 return ;
1255         }
1256         contact=sal_op_get_contact(op);
1257         if (contact) {
1258                 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1259                 osip_message_set_contact(msg,contact);
1260         }
1261         if (op->sdp_answer){
1262                 set_sdp(msg,op->sdp_answer);
1263                 sdp_message_free(op->sdp_answer);
1264                 op->sdp_answer=NULL;
1265         }
1266         eXosip_call_send_ack(ev->did,msg);
1267         sal->callbacks.call_accepted(op);
1268 }
1269
1270 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1271         char *from=NULL;
1272         SalOp *op=find_op(sal,ev);
1273         if (op==NULL){
1274                 ms_warning("Call terminated for already closed call ?");
1275                 return;
1276         }
1277         if (ev->request){
1278                 osip_from_to_str(ev->request->from,&from);
1279         }
1280         sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1281         if (from) osip_free(from);
1282         op->terminated=TRUE;
1283 }
1284
1285 static void call_released(Sal *sal, eXosip_event_t *ev){
1286         SalOp *op=find_op(sal,ev);
1287         if (op==NULL){
1288                 ms_warning("No op associated to this call_released()");
1289                 return;
1290         }
1291         if (!op->terminated){
1292                 /* no response received so far */
1293                 call_failure(sal,ev);
1294         }
1295         sal->callbacks.call_released(op);
1296 }
1297
1298 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1299         const char *prx_realm=NULL,*www_realm=NULL;
1300         osip_proxy_authenticate_t *prx_auth;
1301         osip_www_authenticate_t *www_auth;
1302         
1303         *username=osip_uri_get_username(resp->from->url);
1304         prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1305         www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1306         if (prx_auth!=NULL)
1307                 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1308         if (www_auth!=NULL)
1309                 www_realm=osip_www_authenticate_get_realm(www_auth);
1310
1311         if (prx_realm){
1312                 *realm=prx_realm;
1313         }else if (www_realm){
1314                 *realm=www_realm;
1315         }else{
1316                 return -1;
1317         }
1318         return 0;
1319 }
1320
1321 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1322         osip_authorization_t *auth=NULL;
1323         osip_proxy_authorization_t *prx_auth=NULL;
1324         
1325         *username=osip_uri_get_username(msg->from->url);
1326         osip_message_get_authorization(msg, 0, &auth);
1327         if (auth){
1328                 *realm=osip_authorization_get_realm(auth);
1329                 return 0;
1330         }
1331         osip_message_get_proxy_authorization(msg,0,&prx_auth);
1332         if (prx_auth){
1333                 *realm=osip_proxy_authorization_get_realm(prx_auth);
1334                 return 0;
1335         }
1336         return -1;
1337 }
1338
1339 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1340         if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1341         if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1342         return -1;
1343 }
1344
1345 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1346         if (op->pending_auth){
1347                 return get_auth_data(op->pending_auth,realm,username);
1348         }
1349         return -1;
1350 }
1351
1352 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1353         SalOp *op;
1354         const char *username,*realm;
1355         op=find_op(sal,ev);
1356         if (op==NULL){
1357                 ms_warning("No operation associated with this authentication !");
1358                 return TRUE;
1359         }
1360         if (get_auth_data(ev,&realm,&username)==0){
1361                 if (op->pending_auth!=NULL){
1362                         eXosip_event_free(op->pending_auth);
1363                         op->pending_auth=ev;
1364                 }else{
1365                         op->pending_auth=ev;
1366                         sal_add_pending_auth(sal,op);
1367                 }
1368                 
1369                 sal->callbacks.auth_requested(op,realm,username);
1370                 return FALSE;
1371         }
1372         return TRUE;
1373 }
1374
1375 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1376         SalOp *op;
1377         const char *username,*realm;
1378         op=find_op(sal,ev);
1379         if (op==NULL){
1380                 ms_warning("No operation associated with this authentication_ok!");
1381                 return ;
1382         }
1383         if (op->pending_auth){
1384                 eXosip_event_free(op->pending_auth);
1385                 sal_remove_pending_auth(sal,op);
1386                 op->pending_auth=NULL;
1387         }
1388         if (get_auth_data(ev,&realm,&username)==0){
1389                 sal->callbacks.auth_success(op,realm,username);
1390         }
1391 }
1392
1393 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1394         SalOp *op;
1395         int code=0;
1396         char* computedReason=NULL;
1397         const char *reason=NULL;
1398         SalError error=SalErrorUnknown;
1399         SalReason sr=SalReasonUnknown;
1400         
1401
1402         op=(SalOp*)find_op(sal,ev);
1403
1404         if (op==NULL) {
1405                 ms_warning("Call failure reported for a closed call, ignored.");
1406                 return TRUE;
1407         }
1408
1409         if (ev->response){
1410                 code=osip_message_get_status_code(ev->response);
1411                 reason=osip_message_get_reason_phrase(ev->response);
1412                 osip_header_t *h=NULL;
1413                 if (!osip_message_header_get_byname(    ev->response
1414                                                                                         ,"Reason"
1415                                                                                         ,0
1416                                                                                         ,&h)) {
1417                         computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1418                         reason = computedReason;
1419
1420                 }
1421         }
1422         switch(code)
1423         {
1424                 case 401:
1425                 case 407:
1426                         return process_authentication(sal,ev);
1427                         break;
1428                 case 400:
1429                         error=SalErrorUnknown;
1430                 break;
1431                 case 404:
1432                         error=SalErrorFailure;
1433                         sr=SalReasonNotFound;
1434                 break;
1435                 case 415:
1436                         error=SalErrorFailure;
1437                         sr=SalReasonMedia;
1438                 break;
1439                 case 422:
1440                         eXosip_default_action(ev);
1441                         return TRUE;
1442                 break;
1443                 case 480:
1444                         error=SalErrorFailure;
1445                         sr=SalReasonTemporarilyUnavailable;
1446                 case 486:
1447                         error=SalErrorFailure;
1448                         sr=SalReasonBusy;
1449                 break;
1450                 case 487:
1451                 break;
1452                 case 600:
1453                         error=SalErrorFailure;
1454                         sr=SalReasonDoNotDisturb;
1455                 break;
1456                 case 603:
1457                         error=SalErrorFailure;
1458                         sr=SalReasonDeclined;
1459                 break;
1460                 default:
1461                         if (code>0){
1462                                 error=SalErrorFailure;
1463                                 sr=SalReasonUnknown;
1464                         }else error=SalErrorNoResponse;
1465         }
1466         op->terminated=TRUE;
1467         sal->callbacks.call_failure(op,error,sr,reason,code);
1468         if (computedReason != NULL){
1469                 ms_free(computedReason);
1470         }
1471         return TRUE;
1472 }
1473
1474 /* Request remote side to send us VFU */
1475 void sal_call_send_vfu_request(SalOp *h){
1476         osip_message_t *msg=NULL;
1477         char info_body[] =
1478                         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1479                          "<media_control>"
1480                          "  <vc_primitive>"
1481                          "    <to_encoder>"
1482                          "      <picture_fast_update></picture_fast_update>"
1483                          "    </to_encoder>"
1484                          "  </vc_primitive>"
1485                          "</media_control>";
1486
1487         char clen[10];
1488
1489         eXosip_lock();
1490         eXosip_call_build_info(h->did,&msg);
1491         if (msg){
1492                 osip_message_set_body(msg,info_body,strlen(info_body));
1493                 osip_message_set_content_type(msg,"application/media_control+xml");
1494                 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1495                 osip_message_set_content_length(msg,clen);
1496                 eXosip_call_send_request(h->did,msg);
1497                 ms_message("Sending VFU request !");
1498         }
1499         eXosip_unlock();
1500 }
1501
1502 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1503         SalOp *op=find_op(sal,ev);
1504         osip_body_t *body=NULL;
1505
1506         if (op==NULL){
1507                 ms_warning("media control xml received without operation context!");
1508                 return ;
1509         }
1510         
1511         osip_message_get_body(ev->request,0,&body);
1512         if (body && body->body!=NULL &&
1513                 strstr(body->body,"picture_fast_update")){
1514                 osip_message_t *ans=NULL;
1515                 ms_message("Receiving VFU request !");
1516                 if (sal->callbacks.vfu_request){
1517                         sal->callbacks.vfu_request(op);
1518                         eXosip_call_build_answer(ev->tid,200,&ans);
1519                         if (ans)
1520                                 eXosip_call_send_answer(ev->tid,200,ans);
1521                         return;
1522                 }
1523         }
1524         /*in all other cases we must say it is not implemented.*/
1525         {
1526                 osip_message_t *ans=NULL;
1527                 eXosip_lock();
1528                 eXosip_call_build_answer(ev->tid,501,&ans);
1529                 if (ans)
1530                         eXosip_call_send_answer(ev->tid,501,ans);
1531                 eXosip_unlock();
1532         }
1533 }
1534
1535 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1536         SalOp *op=find_op(sal,ev);
1537         osip_body_t *body=NULL;
1538
1539         if (op==NULL){
1540                 ms_warning("media dtmf relay received without operation context!");
1541                 return ;
1542         }
1543         
1544         osip_message_get_body(ev->request,0,&body);
1545         if (body && body->body!=NULL){
1546                 osip_message_t *ans=NULL;
1547                 const char *name=strstr(body->body,"Signal");
1548                 if (name==NULL) name=strstr(body->body,"signal");
1549                 if (name==NULL) {
1550                         ms_warning("Could not extract the dtmf name from the SIP INFO.");
1551                 }else{
1552                         char tmp[2];
1553                         name+=strlen("signal");
1554                         if (sscanf(name," = %1s",tmp)==1){
1555                                 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1556                                 if (sal->callbacks.dtmf_received != NULL)
1557                                         sal->callbacks.dtmf_received(op, tmp[0]);
1558                         }
1559                 }
1560                 eXosip_lock();
1561                 eXosip_call_build_answer(ev->tid,200,&ans);
1562                 if (ans)
1563                         eXosip_call_send_answer(ev->tid,200,ans);
1564                 eXosip_unlock();
1565         }
1566 }
1567
1568 static void fill_options_answer(osip_message_t *options){
1569         osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1570         osip_message_set_accept(options,"application/sdp");
1571 }
1572
1573 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1574         osip_header_t *h=NULL;
1575         osip_message_t *ans=NULL;
1576         ms_message("Receiving REFER request !");
1577         osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1578
1579         if (h){
1580                 osip_from_t *from=NULL;
1581                 char *tmp;
1582                 osip_from_init(&from);
1583         
1584                 if (osip_from_parse(from,h->hvalue)==0){
1585                         if (op ){
1586                                 osip_uri_header_t *uh=NULL;
1587                                 osip_header_t *referred_by=NULL;
1588                                 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1589                                 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1590                                         ms_message("Found replaces in Refer-To");
1591                                         if (op->replaces){
1592                                                 ms_free(op->replaces);
1593                                         }
1594                                         op->replaces=ms_strdup(uh->gvalue);
1595                                 }
1596                                 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1597                                 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1598                                         if (op->referred_by)
1599                                                 ms_free(op->referred_by);
1600                                         op->referred_by=ms_strdup(referred_by->hvalue);
1601                                 }
1602                         }
1603                         osip_uri_header_freelist(&from->url->url_headers);
1604                         osip_from_to_str(from,&tmp);
1605                         sal->callbacks.refer_received(sal,op,tmp);
1606                         osip_free(tmp);
1607                         osip_from_free(from);
1608                 }
1609                 eXosip_lock();
1610                 eXosip_call_build_answer(ev->tid,202,&ans);
1611                 if (ans)
1612                         eXosip_call_send_answer(ev->tid,202,ans);
1613                 eXosip_unlock();
1614         }
1615         else
1616         {
1617                 ms_warning("cannot do anything with the refer without destination\n");
1618         }
1619 }
1620
1621 static void process_notify(Sal *sal, eXosip_event_t *ev){
1622         osip_header_t *h=NULL;
1623         char *from=NULL;
1624         SalOp *op=find_op(sal,ev);
1625         osip_message_t *ans=NULL;
1626
1627         ms_message("Receiving NOTIFY request !");
1628         osip_from_to_str(ev->request->from,&from);
1629         osip_message_header_get_byname(ev->request,"Event",0,&h);
1630         if(h){
1631                 osip_body_t *body=NULL;
1632                 //osip_content_type_t *ct=NULL;
1633                 osip_message_get_body(ev->request,0,&body);
1634                 //ct=osip_message_get_content_type(ev->request);
1635                 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1636                         /*special handling of refer events*/
1637                         if (body && body->body){
1638                                 osip_message_t *msg;
1639                                 osip_message_init(&msg);
1640                                 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1641                                         int code=osip_message_get_status_code(msg);
1642                                         if (code==100){
1643                                                 sal->callbacks.notify_refer(op,SalReferTrying);
1644                                         }else if (code==200){
1645                                                 sal->callbacks.notify_refer(op,SalReferSuccess);
1646                                         }else if (code>=400){
1647                                                 sal->callbacks.notify_refer(op,SalReferFailed);
1648                                         }
1649                                 }
1650                                 osip_message_free(msg);
1651                         }
1652                 }else{
1653                         /*generic handling*/
1654                         sal->callbacks.notify(op,from,h->hvalue);
1655                 }
1656         }
1657         /*answer that we received the notify*/
1658         eXosip_lock();
1659         eXosip_call_build_answer(ev->tid,200,&ans);
1660         if (ans)
1661                 eXosip_call_send_answer(ev->tid,200,ans);
1662         eXosip_unlock();
1663         osip_free(from);
1664 }
1665
1666 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1667         osip_message_t *ans=NULL;
1668         if (ev->request){
1669                 if (MSG_IS_INFO(ev->request)){
1670                         osip_content_type_t *ct;
1671                         ct=osip_message_get_content_type(ev->request);
1672                         if (ct && ct->subtype){
1673                                 if (strcmp(ct->subtype,"media_control+xml")==0)
1674                                         process_media_control_xml(sal,ev);
1675                                 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1676                                         process_dtmf_relay(sal,ev);
1677                                 else {
1678                                         ms_message("Unhandled SIP INFO.");
1679                                         /*send an "Not implemented" answer*/
1680                                         eXosip_lock();
1681                                         eXosip_call_build_answer(ev->tid,501,&ans);
1682                                         if (ans)
1683                                                 eXosip_call_send_answer(ev->tid,501,ans);
1684                                         eXosip_unlock();
1685                                 }
1686                         }else{
1687                                 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1688                                 eXosip_lock();
1689                                 eXosip_call_build_answer(ev->tid,200,&ans);
1690                                 if (ans)
1691                                         eXosip_call_send_answer(ev->tid,200,ans);
1692                                 eXosip_unlock();
1693                         }
1694                 }else if(MSG_IS_MESSAGE(ev->request)){
1695                         /* SIP messages could be received into call */
1696                         text_received(sal, ev);
1697                         eXosip_lock();
1698                         eXosip_call_build_answer(ev->tid,200,&ans);
1699                         if (ans)
1700                                 eXosip_call_send_answer(ev->tid,200,ans);
1701                         eXosip_unlock();
1702                 }else if(MSG_IS_REFER(ev->request)){
1703                         SalOp *op=find_op(sal,ev);
1704                         
1705                         ms_message("Receiving REFER request !");
1706                         process_refer(sal,op,ev);
1707                 }else if(MSG_IS_NOTIFY(ev->request)){
1708                         process_notify(sal,ev);
1709                 }else if (MSG_IS_OPTIONS(ev->request)){
1710                         eXosip_lock();
1711                         eXosip_call_build_answer(ev->tid,200,&ans);
1712                         if (ans){
1713                                 fill_options_answer(ans);
1714                                 eXosip_call_send_answer(ev->tid,200,ans);
1715                         }
1716                         eXosip_unlock();
1717                 }
1718         }else ms_warning("call_message_new: No request ?");
1719 }
1720
1721 static void inc_update(Sal *sal, eXosip_event_t *ev){
1722         osip_message_t *msg=NULL;
1723         ms_message("Processing incoming UPDATE");
1724         eXosip_lock();
1725         eXosip_message_build_answer(ev->tid,200,&msg);
1726         if (msg!=NULL)
1727                 eXosip_message_send_answer(ev->tid,200,msg);
1728         eXosip_unlock();
1729 }
1730
1731 static bool_t comes_from_local_if(osip_message_t *msg){
1732         osip_via_t *via=NULL;
1733         osip_message_get_via(msg,0,&via);
1734         if (via){
1735                 const char *host;
1736                 host=osip_via_get_host(via);
1737                 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1738                         osip_generic_param_t *param=NULL;
1739                         osip_via_param_get_byname(via,"received",&param);
1740                         if (param==NULL) return TRUE;
1741                         if (param->gvalue &&
1742                                 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1743                                 return TRUE;
1744                         }
1745                 }
1746         }
1747         return FALSE;
1748 }
1749
1750 static void text_received(Sal *sal, eXosip_event_t *ev){
1751         osip_body_t *body=NULL;
1752         char *from=NULL,*msg=NULL;
1753         osip_content_type_t* content_type;
1754         osip_uri_param_t* external_body_url; 
1755         char unquoted_external_body_url [256];
1756         int external_body_size=0;
1757         SalMessage salmsg;
1758         char message_id[256]={0};
1759         
1760         content_type= osip_message_get_content_type(ev->request);
1761         if (!content_type) {
1762                 ms_error("Could not get message because no content type");
1763                 return;
1764         }
1765         osip_from_to_str(ev->request->from,&from);
1766         if (content_type->type 
1767                 && strcmp(content_type->type, "text")==0 
1768                 && content_type->subtype
1769                 && strcmp(content_type->subtype, "plain")==0 ) {
1770                 osip_message_get_body(ev->request,0,&body);
1771                 if (body==NULL){
1772                         ms_error("Could not get text message from SIP body");
1773                         osip_free(from);
1774                         return;
1775                 }
1776                 msg=body->body;
1777         }else if (content_type->type 
1778                   && strcmp(content_type->type, "message")==0 
1779                   && content_type->subtype
1780                   && strcmp(content_type->subtype, "external-body")==0 ) {
1781                 
1782                 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1783                 /*remove both first and last character*/
1784                 strncpy(unquoted_external_body_url
1785                                 ,&external_body_url->gvalue[1]
1786                                 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1787                 unquoted_external_body_url[external_body_size-1]='\0';
1788         } else {
1789                 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1790                 osip_free(from);
1791                 return;
1792         }
1793         snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1794         
1795         salmsg.from=from;
1796         salmsg.text=msg;
1797         salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1798         salmsg.message_id=message_id;
1799         sal->callbacks.text_received(sal,&salmsg);
1800         osip_free(from);
1801 }
1802
1803
1804
1805 static void other_request(Sal *sal, eXosip_event_t *ev){
1806         ms_message("in other_request");
1807         if (ev->request==NULL) return;
1808         if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1809                 text_received(sal,ev);
1810                 eXosip_message_send_answer(ev->tid,200,NULL);
1811         }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1812                 osip_message_t *options=NULL;
1813                 eXosip_options_build_answer(ev->tid,200,&options);
1814                 fill_options_answer(options);
1815                 eXosip_options_send_answer(ev->tid,200,options);
1816         }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1817                 ms_message("Receiving REFER request !");
1818                 if (comes_from_local_if(ev->request)) {
1819                         process_refer(sal,NULL,ev);
1820                 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1821         }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1822                 inc_update(sal,ev);
1823         }else {
1824                 char *tmp=NULL;
1825                 size_t msglen=0;
1826                 osip_message_to_str(ev->request,&tmp,&msglen);
1827                 if (tmp){
1828                         ms_message("Unsupported request received:\n%s",tmp);
1829                         osip_free(tmp);
1830                 }
1831                 /*answer with a 501 Not implemented*/
1832                 eXosip_message_send_answer(ev->tid,501,NULL);
1833         }
1834 }
1835
1836 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1837         osip_via_t *via=NULL;
1838         osip_message_get_via(msg,0,&via);
1839         if (via){
1840                 osip_free(via->port);
1841                 via->port=osip_strdup(port);
1842                 osip_free(via->host);
1843                 via->host=osip_strdup(ip);
1844         }
1845 }
1846
1847
1848 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1849         osip_contact_t *ctt=NULL;
1850         const char *received;
1851         int rport;
1852         SalTransport transport;
1853         char port[20];
1854
1855         if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1856         osip_message_get_contact(request,0,&ctt);
1857         if (ctt == NULL) {
1858                 ms_warning("fix_message_contact(): no contact to update");
1859                 return FALSE;
1860         }
1861         if (expire_last_contact){
1862                 osip_contact_t *oldct=NULL,*prevct;
1863                 osip_generic_param_t *param=NULL;
1864                 osip_contact_clone(ctt,&oldct);
1865                 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1866                         osip_contact_free(prevct);
1867                         osip_list_remove(&request->contacts,1);
1868                 }
1869                 osip_list_add(&request->contacts,oldct,1);
1870                 osip_contact_param_get_byname(oldct,"expires",&param);
1871                 if (param){
1872                         if (param->gvalue) osip_free(param->gvalue);
1873                         param->gvalue=osip_strdup("0");
1874                 }else{
1875                         osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1876                 }
1877         }
1878         if (ctt->url->host!=NULL){
1879                 osip_free(ctt->url->host);
1880         }
1881         ctt->url->host=osip_strdup(received);
1882         if (ctt->url->port!=NULL){
1883                 osip_free(ctt->url->port);
1884         }
1885         snprintf(port,sizeof(port),"%i",rport);
1886         ctt->url->port=osip_strdup(port);
1887         if (op->masquerade_via) masquerade_via(request,received,port);
1888
1889         if (transport != SalTransportUDP) {
1890                 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport)); 
1891         }
1892         return TRUE;    
1893 }
1894
1895 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1896         osip_contact_t *ctt=NULL;
1897         SalAddress* ori_contact_address=NULL;
1898         const char *received;
1899         int rport;
1900         SalTransport transport;
1901         char* tmp;
1902         osip_message_t *msg=NULL;
1903         Sal* sal=op->base.root;
1904         int i=0;
1905         bool_t found_valid_contact=FALSE;
1906         bool_t from_request=FALSE;
1907
1908         if (sal->double_reg==FALSE ) return FALSE; 
1909
1910         if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1911         do{
1912                 ctt=NULL;
1913                 osip_message_get_contact(last_answer,i,&ctt);
1914                 if (!from_request && ctt==NULL) {
1915                         osip_message_get_contact(orig_request,0,&ctt);
1916                         from_request=TRUE;
1917                 }
1918                 if (ctt){
1919                         osip_contact_to_str(ctt,&tmp);
1920                         ori_contact_address = sal_address_new(tmp);
1921         
1922                         /*check if contact is up to date*/
1923                         if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0 
1924                                 && sal_address_get_port_int(ori_contact_address) == rport
1925                         && sal_address_get_transport(ori_contact_address) == transport) {
1926                                 if (!from_request){
1927                                         ms_message("Register response has up to date contact, doing nothing.");
1928                                 }else {
1929                                         ms_warning("Register response does not have up to date contact, but last request had."
1930                                                 "Stupid registrar detected, giving up.");
1931                                 }
1932                                 found_valid_contact=TRUE;
1933                         }
1934                         osip_free(tmp);
1935                         sal_address_destroy(ori_contact_address);
1936                 }else break;
1937                 i++;
1938         }while(!found_valid_contact);
1939         if (!found_valid_contact)
1940                 ms_message("Contact do not match, resending register.");
1941         else return FALSE;
1942
1943         eXosip_lock();
1944         eXosip_register_build_register(op->rid,op->expires,&msg);
1945         if (msg==NULL){
1946             eXosip_unlock();
1947             ms_warning("Fail to create a contact updated register.");
1948             return FALSE;
1949         }
1950         if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1951                 eXosip_register_send_register(op->rid,msg);
1952                 eXosip_unlock();  
1953                 ms_message("Resending new register with updated contact");
1954                 update_contact_from_response(op,last_answer);
1955                 return TRUE;
1956         } else {
1957             ms_warning("Fail to send updated register.");
1958             eXosip_unlock();
1959             return FALSE;
1960         }
1961         eXosip_unlock();
1962         return FALSE;
1963 }
1964
1965 static void registration_success(Sal *sal, eXosip_event_t *ev){
1966         SalOp *op=sal_find_register(sal,ev->rid);
1967         osip_header_t *h=NULL;
1968         bool_t registered;
1969         if (op==NULL){
1970                 ms_error("Receiving register response for unknown operation");
1971                 return;
1972         }
1973         osip_message_get_expires(ev->request,0,&h);
1974         if (h!=NULL && atoi(h->hvalue)!=0){
1975                 registered=TRUE;
1976                 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1977                         sal->callbacks.register_success(op,registered);
1978                 }
1979         }else {
1980                 sal->callbacks.register_success(op,FALSE);
1981         }
1982 }
1983
1984 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1985         int status_code=0;
1986         const char *reason=NULL;
1987         SalOp *op=sal_find_register(sal,ev->rid);
1988         SalReason sr=SalReasonUnknown;
1989         SalError se=SalErrorUnknown;
1990         
1991         if (op==NULL){
1992                 ms_error("Receiving register failure for unknown operation");
1993                 return TRUE;
1994         }
1995         if (ev->response){
1996                 status_code=osip_message_get_status_code(ev->response);
1997                 reason=osip_message_get_reason_phrase(ev->response);
1998         }
1999         switch(status_code){
2000                 case 401:
2001                 case 407:
2002                         return process_authentication(sal,ev);
2003                         break;
2004                 case 423: /*interval too brief*/
2005                         {/*retry with greater interval */
2006                                 osip_header_t *h=NULL;
2007                                 osip_message_t *msg=NULL;
2008                                 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
2009                                 if (h && h->hvalue && h->hvalue[0]!='\0'){
2010                                         int val=atoi(h->hvalue);
2011                                         if (val>op->expires)
2012                                                 op->expires=val;
2013                                 }else op->expires*=2;
2014                                 eXosip_lock();
2015                                 eXosip_register_build_register(op->rid,op->expires,&msg);
2016                                 eXosip_register_send_register(op->rid,msg);
2017                                 eXosip_unlock();
2018                         }
2019                 break;
2020                 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2021                                  in vias, such as ekiga.net 
2022                                  On the opposite, freephonie.net bugs when via are masqueraded.
2023                                  */
2024                         op->masquerade_via=TRUE;
2025                 default:
2026                         /* if contact is up to date, process the failure, otherwise resend a new register with
2027                                 updated contact first, just in case the faillure is due to incorrect contact */
2028                         if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2029                                 return TRUE; /*we are retrying with an updated contact*/
2030                         if (status_code==403){
2031                                 se=SalErrorFailure;
2032                                 sr=SalReasonForbidden;
2033                         }else if (status_code==0){
2034                                 se=SalErrorNoResponse;
2035                         }
2036                         sal->callbacks.register_failure(op,se,sr,reason);
2037         }
2038         return TRUE;
2039 }
2040
2041 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2042         SalOp *op=find_op(sal,ev);
2043         if (op==NULL){
2044                 ms_warning("other_request_reply(): Receiving response to unknown request.");
2045                 return;
2046         }
2047         if (ev->response){
2048                 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2049                 update_contact_from_response(op,ev->response);
2050                 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2051                         sal->callbacks.ping_reply(op);
2052         }
2053         if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2054                 /*out of call message acknolegment*/
2055                 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2056                 if (ev->response){
2057                         if (ev->response->status_code<200){
2058                                 status=SalTextDeliveryInProgress;
2059                         }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2060                                 status=SalTextDeliveryDone;
2061                         }
2062                 }
2063                 sal->callbacks.text_delivery_update(op,status);
2064         }
2065 }
2066
2067 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2068         SalOp *op=find_op(sal,ev);
2069         if (ev->response){
2070                 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2071                         if (op->sipfrag_pending){
2072                                 send_notify_for_refer(op->did,op->sipfrag_pending);
2073                                 op->sipfrag_pending=NULL;
2074                         }
2075                 }
2076         }
2077 }
2078
2079 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2080         ms_message("linphone process event get a message %d\n",ev->type);
2081         switch(ev->type){
2082                 case EXOSIP_CALL_ANSWERED:
2083                         ms_message("CALL_ANSWERED\n");
2084                         call_accepted(sal,ev);
2085                         authentication_ok(sal,ev);
2086                         break;
2087                 case EXOSIP_CALL_CLOSED:
2088                 case EXOSIP_CALL_CANCELLED:
2089                         ms_message("CALL_CLOSED or CANCELLED\n");
2090                         call_terminated(sal,ev);
2091                         break;
2092                 case EXOSIP_CALL_TIMEOUT:
2093                 case EXOSIP_CALL_NOANSWER:
2094                         ms_message("CALL_TIMEOUT or NOANSWER\n");
2095                         return call_failure(sal,ev);
2096                         break;
2097                 case EXOSIP_CALL_REQUESTFAILURE:
2098                 case EXOSIP_CALL_GLOBALFAILURE:
2099                 case EXOSIP_CALL_SERVERFAILURE:
2100                         ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2101                         return call_failure(sal,ev);
2102                         break;
2103                 case EXOSIP_CALL_RELEASED:
2104                         ms_message("CALL_RELEASED\n");
2105                         call_released(sal, ev);
2106                         break;
2107                 case EXOSIP_CALL_INVITE:
2108                         ms_message("CALL_NEW\n");
2109                         inc_new_call(sal,ev);
2110                         break;
2111                 case EXOSIP_CALL_REINVITE:
2112                         handle_reinvite(sal,ev);
2113                         break;
2114                 case EXOSIP_CALL_ACK:
2115                         ms_message("CALL_ACK");
2116                         handle_ack(sal,ev);
2117                         break;
2118                 case EXOSIP_CALL_REDIRECTED:
2119                         ms_message("CALL_REDIRECTED");
2120                         eXosip_default_action(ev);
2121                         break;
2122                 case EXOSIP_CALL_PROCEEDING:
2123                         ms_message("CALL_PROCEEDING");
2124                         call_proceeding(sal,ev);
2125                         break;
2126                 case EXOSIP_CALL_RINGING:
2127                         ms_message("CALL_RINGING");
2128                         call_ringing(sal,ev);
2129                         authentication_ok(sal,ev);
2130                         break;
2131                 case EXOSIP_CALL_MESSAGE_NEW:
2132                         ms_message("EXOSIP_CALL_MESSAGE_NEW");
2133                         call_message_new(sal,ev);
2134                         break;
2135                 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2136                         if (ev->response &&
2137                                 (ev->response->status_code==407 || ev->response->status_code==401)){
2138                                  return process_authentication(sal,ev);
2139                         }
2140                         break;
2141                 case EXOSIP_CALL_MESSAGE_ANSWERED:
2142                         ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2143                         process_in_call_reply(sal,ev);
2144                 break;
2145                 case EXOSIP_IN_SUBSCRIPTION_NEW:
2146                         ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2147                         sal_exosip_subscription_recv(sal,ev);
2148                         break;
2149                 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2150                         ms_message("CALL_SUBSCRIPTION_NEW ");
2151                         sal_exosip_in_subscription_closed(sal,ev);
2152                         break;
2153                 case EXOSIP_SUBSCRIPTION_UPDATE:
2154                         ms_message("CALL_SUBSCRIPTION_UPDATE");
2155                         break;
2156                 case EXOSIP_SUBSCRIPTION_NOTIFY:
2157                         ms_message("CALL_SUBSCRIPTION_NOTIFY");
2158                         sal_exosip_notify_recv(sal,ev);
2159                         break;
2160                 case EXOSIP_SUBSCRIPTION_ANSWERED:
2161                         ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2162                         sal_exosip_subscription_answered(sal,ev);
2163                         break;
2164                 case EXOSIP_SUBSCRIPTION_CLOSED:
2165                         ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2166                         sal_exosip_subscription_closed(sal,ev);
2167                         break;
2168                 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE:   /**< announce a request failure      */
2169                         if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2170                                 return process_authentication(sal,ev);
2171                         }
2172                 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2173                 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2174                         sal_exosip_subscription_closed(sal,ev);
2175                         break;
2176                 case EXOSIP_REGISTRATION_FAILURE:
2177                         ms_message("REGISTRATION_FAILURE\n");
2178                         return registration_failure(sal,ev);
2179                         break;
2180                 case EXOSIP_REGISTRATION_SUCCESS:
2181                         authentication_ok(sal,ev);
2182                         registration_success(sal,ev);
2183                         break;
2184                 case EXOSIP_MESSAGE_NEW:
2185                         other_request(sal,ev);
2186                         break;
2187                 case EXOSIP_MESSAGE_PROCEEDING:
2188                 case EXOSIP_MESSAGE_ANSWERED:
2189                 case EXOSIP_MESSAGE_REDIRECTED:
2190                 case EXOSIP_MESSAGE_SERVERFAILURE:
2191                 case EXOSIP_MESSAGE_GLOBALFAILURE:
2192                         other_request_reply(sal,ev);
2193                         break;
2194                 case EXOSIP_MESSAGE_REQUESTFAILURE:
2195                 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2196                         if (ev->response) {
2197                                 switch (ev->response->status_code) {
2198                                         case 407:
2199                                         case 401:
2200                                                 return process_authentication(sal,ev);
2201                                         case 412: {
2202                                                 eXosip_automatic_action ();
2203                                                 return 1;
2204                                         }
2205                                 }
2206                         }
2207                         other_request_reply(sal,ev);
2208                         break;
2209                 default:
2210                         ms_message("Unhandled exosip event ! %i",ev->type);
2211                         break;
2212         }
2213         return TRUE;
2214 }
2215
2216 int sal_iterate(Sal *sal){
2217         eXosip_event_t *ev;
2218         while((ev=eXosip_event_wait(0,0))!=NULL){
2219                 if (process_event(sal,ev))
2220                         eXosip_event_free(ev);
2221         }
2222 #ifdef HAVE_EXOSIP_TRYLOCK
2223         if (eXosip_trylock()==0){
2224                 eXosip_automatic_refresh();
2225                 eXosip_unlock();
2226         }else{
2227                 ms_warning("eXosip_trylock busy.");
2228         }
2229 #else
2230         eXosip_lock();
2231         eXosip_automatic_refresh();
2232         eXosip_unlock();
2233 #endif
2234         return 0;
2235 }
2236
2237 static void register_set_contact(osip_message_t *msg, const char *contact){
2238         osip_uri_param_t *param = NULL;
2239         osip_contact_t *ct=NULL;
2240         char *line=NULL;
2241         /*we get the line parameter choosed by exosip, and add it to our own contact*/
2242         osip_message_get_contact(msg,0,&ct);
2243         if (ct!=NULL){
2244                 osip_uri_uparam_get_byname(ct->url, "line", &param);
2245                 if (param && param->gvalue)
2246                         line=osip_strdup(param->gvalue);
2247         }
2248         _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2249         osip_message_set_contact(msg,contact);
2250         osip_message_get_contact(msg,0,&ct);
2251         osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2252 }
2253
2254 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2255         osip_route_t *route;
2256
2257         osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2258         
2259         osip_route_init(&route);
2260         if (osip_route_parse(route,proxy)==0){
2261                 osip_uri_param_t *lr_param = NULL;
2262                 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2263                 if (lr_param == NULL){
2264                         osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2265                 }
2266                 osip_list_add(&msg->routes,route,0);
2267                 return;
2268         }
2269         osip_route_free(route);
2270 }
2271
2272
2273 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2274         osip_message_t *msg;
2275         const char *contact=sal_op_get_contact(h);
2276
2277         sal_op_set_route(h,proxy);
2278         if (h->rid==-1){
2279                 SalAddress *from_parsed=sal_address_new(from);
2280                 char domain[256];
2281                 char *uri, *domain_ptr = NULL;
2282                 if (from_parsed==NULL) {
2283                         ms_warning("sal_register() bad from %s",from);
2284                         return -1;
2285                 }
2286                 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2287                    using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2288                 uri = sal_address_as_string_uri_only(from_parsed);
2289                 if (uri) domain_ptr = strchr(uri, '@');
2290                 if (domain_ptr) {
2291                         snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2292                 } else {
2293                         snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2294                 }
2295                 if (uri) ms_free(uri);
2296                 sal_address_destroy(from_parsed);
2297                 eXosip_lock();
2298                 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2299                 if (msg){
2300                         if (contact) register_set_contact(msg,contact);
2301                         sal_register_add_route(msg,proxy);
2302                         sal_add_register(h->base.root,h);
2303                 }else{
2304                         ms_error("Could not build initial register.");
2305                         eXosip_unlock();
2306                         return -1;
2307                 }
2308         }else{
2309                 eXosip_lock();
2310                 eXosip_register_build_register(h->rid,expires,&msg);
2311                 sal_register_add_route(msg,proxy);
2312         }
2313         if (msg){
2314                 eXosip_register_send_register(h->rid,msg);
2315         }
2316         eXosip_unlock();
2317         h->expires=expires;
2318         return (msg != NULL) ? 0 : -1;
2319 }
2320
2321 int sal_register_refresh(SalOp *op, int expires){
2322         osip_message_t *msg=NULL;
2323         const char *contact=sal_op_get_contact(op);
2324         
2325         if (op->rid==-1){
2326                 ms_error("Unexistant registration context, not possible to refresh.");
2327                 return -1;
2328         }
2329 #ifdef HAVE_EXOSIP_TRYLOCK
2330         {
2331                 int tries=0;
2332                 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2333                 * 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
2334                 * the exosip lock in a non blocking way, and give up if it takes too long*/
2335                 while (eXosip_trylock()!=0){
2336                         ms_usleep(100000);
2337                         if (tries>30) {/*after 3 seconds, give up*/
2338                                 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2339                                 return -1;
2340                         }
2341                 }
2342         }
2343 #else
2344         eXosip_lock();
2345 #endif
2346         eXosip_register_build_register(op->rid,expires,&msg);
2347         if (msg!=NULL){
2348                 if (contact) register_set_contact(msg,contact);
2349                 sal_register_add_route(msg,sal_op_get_route(op));
2350                 eXosip_register_send_register(op->rid,msg);
2351         }else ms_error("Could not build REGISTER refresh message.");
2352         eXosip_unlock();
2353         return (msg != NULL) ? 0 : -1;
2354 }
2355
2356
2357 int sal_unregister(SalOp *h){
2358         osip_message_t *msg=NULL;
2359         eXosip_lock();
2360         eXosip_register_build_register(h->rid,0,&msg);
2361         if (msg) eXosip_register_send_register(h->rid,msg);
2362         else ms_warning("Could not build unREGISTER !");
2363         eXosip_unlock();
2364         return 0;
2365 }
2366
2367 SalAddress * sal_address_new(const char *uri){
2368         osip_from_t *from;
2369         osip_from_init(&from);
2370
2371         // Remove front spaces
2372         while (uri[0]==' ') {
2373                 uri++;
2374         }
2375                 
2376         if (osip_from_parse(from,uri)!=0){
2377                 osip_from_free(from);
2378                 return NULL;
2379         }
2380         if (from->displayname!=NULL && from->displayname[0]=='"'){
2381                 char *unquoted=osip_strdup_without_quote(from->displayname);
2382                 osip_free(from->displayname);
2383                 from->displayname=unquoted;
2384         }
2385         return (SalAddress*)from;
2386 }
2387
2388 SalAddress * sal_address_clone(const SalAddress *addr){
2389         osip_from_t *ret=NULL;
2390         osip_from_clone((osip_from_t*)addr,&ret);
2391         return (SalAddress*)ret;
2392 }
2393
2394 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2395
2396 const char *sal_address_get_scheme(const SalAddress *addr){
2397         const osip_from_t *u=(const osip_from_t*)addr;
2398         return null_if_empty(u->url->scheme);
2399 }
2400
2401 const char *sal_address_get_display_name(const SalAddress* addr){
2402         const osip_from_t *u=(const osip_from_t*)addr;
2403         return null_if_empty(u->displayname);
2404 }
2405
2406 const char *sal_address_get_username(const SalAddress *addr){
2407         const osip_from_t *u=(const osip_from_t*)addr;
2408         return null_if_empty(u->url->username);
2409 }
2410
2411 const char *sal_address_get_domain(const SalAddress *addr){
2412         const osip_from_t *u=(const osip_from_t*)addr;
2413         return null_if_empty(u->url->host);
2414 }
2415
2416 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2417         osip_from_t *u=(osip_from_t*)addr;
2418         if (u->displayname!=NULL){
2419                 osip_free(u->displayname);
2420                 u->displayname=NULL;
2421         }
2422         if (display_name!=NULL && display_name[0]!='\0'){
2423                 u->displayname=osip_strdup(display_name);
2424         }
2425 }
2426
2427 void sal_address_set_username(SalAddress *addr, const char *username){
2428         osip_from_t *uri=(osip_from_t*)addr;
2429         if (uri->url->username!=NULL){
2430                 osip_free(uri->url->username);
2431                 uri->url->username=NULL;
2432         }
2433         if (username)
2434                 uri->url->username=osip_strdup(username);
2435 }
2436
2437 void sal_address_set_domain(SalAddress *addr, const char *host){
2438         osip_from_t *uri=(osip_from_t*)addr;
2439         if (uri->url->host!=NULL){
2440                 osip_free(uri->url->host);
2441                 uri->url->host=NULL;
2442         }
2443         if (host)
2444                 uri->url->host=osip_strdup(host);
2445 }
2446
2447 void sal_address_set_port(SalAddress *addr, const char *port){
2448         osip_from_t *uri=(osip_from_t*)addr;
2449         if (uri->url->port!=NULL){
2450                 osip_free(uri->url->port);
2451                 uri->url->port=NULL;
2452         }
2453         if (port)
2454                 uri->url->port=osip_strdup(port);
2455 }
2456
2457 void sal_address_set_port_int(SalAddress *uri, int port){
2458         char tmp[12];
2459         if (port==5060){
2460                 /*this is the default, special case to leave the port field blank*/
2461                 sal_address_set_port(uri,NULL);
2462                 return;
2463         }
2464         snprintf(tmp,sizeof(tmp),"%i",port);
2465         sal_address_set_port(uri,tmp);
2466 }
2467
2468 void sal_address_clean(SalAddress *addr){
2469         osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2470         osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2471 }
2472
2473 char *sal_address_as_string(const SalAddress *u){
2474         char *tmp,*ret;
2475         osip_from_t *from=(osip_from_t *)u;
2476         char *old_displayname=NULL;
2477         /* hack to force use of quotes around the displayname*/
2478         if (from->displayname!=NULL
2479             && from->displayname[0]!='"'){
2480                 old_displayname=from->displayname;
2481                 from->displayname=osip_enquote(from->displayname);
2482         }
2483         osip_from_to_str(from,&tmp);
2484         if (old_displayname!=NULL){
2485                 ms_free(from->displayname);
2486                 from->displayname=old_displayname;
2487         }
2488         ret=ms_strdup(tmp);
2489         osip_free(tmp);
2490         return ret;
2491 }
2492
2493 char *sal_address_as_string_uri_only(const SalAddress *u){
2494         char *tmp=NULL,*ret;
2495         osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2496         ret=ms_strdup(tmp);
2497         osip_free(tmp);
2498         return ret;
2499 }
2500 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2501         osip_uri_param_t *param=NULL;
2502     osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,&param);
2503     if (param == NULL){
2504         osip_uri_uparam_add     (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2505     } else {
2506         osip_free(param->gvalue);
2507         param->gvalue=value ? osip_strdup(value) : NULL;
2508     }
2509     
2510 }
2511
2512 void sal_address_destroy(SalAddress *u){
2513         osip_from_free((osip_from_t*)u);
2514 }
2515
2516 void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
2517         ctx->tcp_tls_keepalive = enabled;
2518 }
2519
2520 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2521         switch (ctx->transport) {
2522                 case SalTransportUDP:
2523                         ctx->keepalive_period = value;
2524                         break;
2525                 case SalTransportTCP:
2526                 case SalTransportTLS:
2527                         if (ctx->tcp_tls_keepalive) ctx->keepalive_period = value;
2528                         else ctx->keepalive_period = -1;
2529                         break;
2530                 default:
2531                         break;
2532         }
2533         eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
2534 }
2535 unsigned int sal_get_keepalive_period(Sal *ctx) {
2536         return ctx->keepalive_period;
2537 }
2538
2539 const char * sal_address_get_port(const SalAddress *addr) {
2540         const osip_from_t *u=(const osip_from_t*)addr;
2541         return null_if_empty(u->url->port);
2542 }
2543
2544 int sal_address_get_port_int(const SalAddress *uri) {
2545         const char* port = sal_address_get_port(uri);
2546         if (port != NULL) {
2547                 return atoi(port);
2548         } else {
2549                 return 5060;
2550         }
2551 }
2552 SalTransport sal_address_get_transport(const SalAddress* addr) {
2553     const osip_from_t *u=(const osip_from_t*)addr;
2554     osip_uri_param_t *transport_param=NULL;
2555     osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2556     if (transport_param == NULL){
2557         return SalTransportUDP;
2558     }  else {
2559         return sal_transport_parse(transport_param->gvalue);
2560     }
2561 }
2562 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2563     sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2564 }
2565
2566 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2567 int sal_call_update(SalOp *h, const char *subject){
2568         int err=0;
2569         osip_message_t *reinvite=NULL;
2570
2571         eXosip_lock();
2572         if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2573                 eXosip_unlock();
2574                 return -1;
2575         }
2576         eXosip_unlock();
2577         osip_message_set_subject(reinvite,subject);
2578         osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2579         if (h->base.contact){
2580                 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2581                 osip_message_set_contact(reinvite,h->base.contact);
2582         }
2583         if (h->base.root->session_expires!=0){
2584                 osip_message_set_header(reinvite, "Session-expires", "200");
2585                 osip_message_set_supported(reinvite, "timer");
2586         }
2587         if (h->base.local_media){
2588                 h->sdp_offering=TRUE;
2589                 set_sdp_from_desc(reinvite,h->base.local_media);
2590         }else h->sdp_offering=FALSE;
2591         eXosip_lock();
2592         err = eXosip_call_send_request(h->did, reinvite);
2593         eXosip_unlock();
2594         return err;
2595 }
2596 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2597         ctx->reuse_authorization=value;
2598 }