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