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