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