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