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