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