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