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