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