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