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