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