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