]> sjero.net Git - linphone/blob - coreapi/sal_eXosip2.c
Merge branch 'master' of git.sv.gnu.org:/srv/git/linphone
[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
25 #include "offeranswer.h"
26
27 static void text_received(Sal *sal, eXosip_event_t *ev);
28
29 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
30         void *data;
31         while((data=osip_list_get(l,0))!=NULL){
32                 osip_list_remove(l,0);
33                 freefunc(data);
34         }
35 }
36
37 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
38         if (eXosip_guess_localip(address_family,ip,iplen)<0){
39                 /*default to something */
40                 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
41                 ms_error("Could not find default routable ip address !");
42         }
43 }
44
45
46 static SalOp * sal_find_call(Sal *sal, int cid){
47         const MSList *elem;
48         SalOp *op;
49         for(elem=sal->calls;elem!=NULL;elem=elem->next){
50                 op=(SalOp*)elem->data;
51                 if (op->cid==cid) return op;
52         }
53         return NULL;
54 }
55
56 static void sal_add_call(Sal *sal, SalOp *op){
57         sal->calls=ms_list_append(sal->calls,op);
58 }
59
60 static void sal_remove_call(Sal *sal, SalOp *op){
61         sal->calls=ms_list_remove(sal->calls, op);
62 }
63
64 static SalOp * sal_find_register(Sal *sal, int rid){
65         const MSList *elem;
66         SalOp *op;
67         for(elem=sal->registers;elem!=NULL;elem=elem->next){
68                 op=(SalOp*)elem->data;
69                 if (op->rid==rid) return op;
70         }
71         return NULL;
72 }
73
74 static void sal_add_register(Sal *sal, SalOp *op){
75         sal->registers=ms_list_append(sal->registers,op);
76 }
77
78 static void sal_remove_register(Sal *sal, int rid){
79         MSList *elem;
80         SalOp *op;
81         for(elem=sal->registers;elem!=NULL;elem=elem->next){
82                 op=(SalOp*)elem->data;
83                 if (op->rid==rid) {
84                         sal->registers=ms_list_remove_link(sal->registers,elem);
85                         return;
86                 }
87         }
88 }
89
90 static SalOp * sal_find_other(Sal *sal, osip_message_t *response){
91         const MSList *elem;
92         SalOp *op;
93         osip_call_id_t *callid=osip_message_get_call_id(response);
94         if (callid==NULL) {
95                 ms_error("There is no call-id in this response !");
96                 return NULL;
97         }
98         for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
99                 op=(SalOp*)elem->data;
100                 if (osip_call_id_match(callid,op->call_id)==0) return op;
101         }
102         return NULL;
103 }
104
105 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
106         osip_call_id_t *callid=osip_message_get_call_id(request);
107         if (callid==NULL) {
108                 ms_error("There is no call id in the request !");
109                 return;
110         }
111         osip_call_id_clone(callid,&op->call_id);
112         sal->other_transactions=ms_list_append(sal->other_transactions,op);
113 }
114
115 static void sal_remove_other(Sal *sal, SalOp *op){
116         sal->other_transactions=ms_list_remove(sal->other_transactions,op);
117 }
118
119
120 static void sal_add_pending_auth(Sal *sal, SalOp *op){
121         sal->pending_auths=ms_list_append(sal->pending_auths,op);
122 }
123
124
125 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
126         sal->pending_auths=ms_list_remove(sal->pending_auths,op);
127 }
128
129 void sal_exosip_fix_route(SalOp *op){
130         if (sal_op_get_route(op)!=NULL){
131                 osip_route_t *rt=NULL;
132                 osip_uri_param_t *lr_param=NULL;
133                 
134                 osip_route_init(&rt);
135                 if (osip_route_parse(rt,sal_op_get_route(op))<0){
136                         ms_warning("Bad route  %s!",sal_op_get_route(op));
137                         sal_op_set_route(op,NULL);
138                 }else{
139                         /* check if the lr parameter is set , if not add it */
140                         osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
141                         if (lr_param==NULL){
142                                 char *tmproute;
143                                 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
144                                 osip_route_to_str(rt,&tmproute);
145                                 sal_op_set_route(op,tmproute);
146                                 osip_free(tmproute);
147                         }
148                 }
149                 osip_route_free(rt);
150         }
151 }
152
153 SalOp * sal_op_new(Sal *sal){
154         SalOp *op=ms_new(SalOp,1);
155         __sal_op_init(op,sal);
156         op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
157         op->result=NULL;
158         op->supports_session_timers=FALSE;
159         op->sdp_offering=TRUE;
160         op->pending_auth=NULL;
161         op->sdp_answer=NULL;
162         op->reinvite=FALSE;
163         op->call_id=NULL;
164         op->replaces=NULL;
165         op->referred_by=NULL;
166         op->masquerade_via=FALSE;
167         op->auto_answer_asked=FALSE;
168         op->auth_info=NULL;
169         return op;
170 }
171
172 bool_t sal_call_autoanswer_asked(SalOp *op)
173 {
174         return op->auto_answer_asked;
175 }
176
177 void sal_op_release(SalOp *op){
178         if (op->sdp_answer)
179                 sdp_message_free(op->sdp_answer);
180         if (op->pending_auth)
181                 eXosip_event_free(op->pending_auth);
182         if (op->rid!=-1){
183                 sal_remove_register(op->base.root,op->rid);
184         }
185         if (op->cid!=-1){
186                 ms_message("Cleaning cid %i",op->cid);
187                 sal_remove_call(op->base.root,op);
188         }
189         if (op->sid!=-1){
190                 sal_remove_out_subscribe(op->base.root,op);
191         }
192         if (op->nid!=-1){
193                 sal_remove_in_subscribe(op->base.root,op);
194                 if (op->call_id)
195                         osip_call_id_free(op->call_id);
196                 op->call_id=NULL;
197         }
198         if (op->pending_auth){
199                 sal_remove_pending_auth(op->base.root,op);
200         }
201         if (op->result)
202                 sal_media_description_unref(op->result);
203         if (op->call_id){
204                 sal_remove_other(op->base.root,op);
205                 osip_call_id_free(op->call_id);
206         }
207         if (op->replaces){
208                 ms_free(op->replaces);
209         }
210         if (op->referred_by){
211                 ms_free(op->referred_by);
212         }
213         if (op->auth_info) {
214                 sal_auth_info_delete(op->auth_info);
215         }
216         __sal_op_free(op);
217 }
218
219 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
220         int ortp_level=ORTP_DEBUG;
221         switch(level){
222                 case OSIP_INFO1:
223                 case OSIP_INFO2:
224                 case OSIP_INFO3:
225                 case OSIP_INFO4:
226                         ortp_level=ORTP_MESSAGE;
227                         break;
228                 case OSIP_WARNING:
229                         ortp_level=ORTP_WARNING;
230                         break;
231                 case OSIP_ERROR:
232                 case OSIP_BUG:
233                         ortp_level=ORTP_ERROR;
234                         break;
235                 case OSIP_FATAL:
236                         ortp_level=ORTP_FATAL;
237                         break;
238                 case END_TRACE_LEVEL:
239                         break;
240         }
241         if (ortp_log_level_enabled(level)){
242                 int len=strlen(chfr);
243                 char *chfrdup=ortp_strdup(chfr);
244                 /*need to remove endline*/
245                 if (len>1){
246                         if (chfrdup[len-1]=='\n')
247                                 chfrdup[len-1]='\0';
248                         if (chfrdup[len-2]=='\r')
249                                 chfrdup[len-2]='\0';
250                 }
251                 ortp_logv(ortp_level,chfrdup,ap);
252                 ortp_free(chfrdup);
253         }
254 }
255
256
257 Sal * sal_init(){
258         static bool_t firsttime=TRUE;
259         Sal *sal;
260         if (firsttime){
261                 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
262                 firsttime=FALSE;
263         }
264         eXosip_init();
265         sal=ms_new0(Sal,1);
266         sal->keepalive_period=30;
267         sal->double_reg=TRUE;
268         return sal;
269 }
270
271 void sal_uninit(Sal* sal){
272         eXosip_quit();
273         ms_free(sal);
274 }
275
276 void sal_set_user_pointer(Sal *sal, void *user_data){
277         sal->up=user_data;
278 }
279
280 void *sal_get_user_pointer(const Sal *sal){
281         return sal->up;
282 }
283
284 static void unimplemented_stub(){
285         ms_warning("Unimplemented SAL callback");
286 }
287
288 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
289         memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
290         if (ctx->callbacks.call_received==NULL) 
291                 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
292         if (ctx->callbacks.call_ringing==NULL) 
293                 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
294         if (ctx->callbacks.call_accepted==NULL) 
295                 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
296         if (ctx->callbacks.call_failure==NULL) 
297                 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
298         if (ctx->callbacks.call_terminated==NULL) 
299                 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
300         if (ctx->callbacks.call_released==NULL)
301                 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
302         if (ctx->callbacks.call_updating==NULL) 
303                 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
304         if (ctx->callbacks.auth_requested==NULL) 
305                 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
306         if (ctx->callbacks.auth_success==NULL) 
307                 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
308         if (ctx->callbacks.register_success==NULL) 
309                 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
310         if (ctx->callbacks.register_failure==NULL) 
311                 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
312         if (ctx->callbacks.dtmf_received==NULL) 
313                 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
314         if (ctx->callbacks.notify==NULL)
315                 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
316         if (ctx->callbacks.notify_presence==NULL)
317                 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
318         if (ctx->callbacks.subscribe_received==NULL)
319                 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
320         if (ctx->callbacks.text_received==NULL)
321                 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
322         if (ctx->callbacks.internal_message==NULL)
323                 ctx->callbacks.internal_message=(SalOnInternalMsg)unimplemented_stub;
324         if (ctx->callbacks.ping_reply==NULL)
325                 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
326 }
327
328 int sal_unlisten_ports(Sal *ctx){
329         if (ctx->running){
330                 eXosip_quit();
331                 eXosip_init();
332         }
333         return 0;
334 }
335
336 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
337         int err;
338         bool_t ipv6;
339         int proto=IPPROTO_UDP;
340         int keepalive = ctx->keepalive_period;
341         
342         switch (tr) {
343         case SalTransportDatagram:
344                 proto=IPPROTO_UDP;
345                 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);      
346                 break;
347         case SalTransportStream:
348                 proto= IPPROTO_TCP;
349                         keepalive=-1;   
350                 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);       
351                 break;
352         default:
353                 ms_warning("unexpected proto, using datagram");
354         }
355
356         err=0;
357         eXosip_set_option(13,&err); /*13=EXOSIP_OPT_SRV_WITH_NAPTR, as it is an enum value, we can't use it unless we are sure of the
358                                         version of eXosip, which is not the case*/
359         /*see if it looks like an IPv6 address*/
360         ipv6=strchr(addr,':')!=NULL;
361         eXosip_enable_ipv6(ipv6);
362
363         if (is_secure){
364                 ms_fatal("SIP over TLS or DTLS is not supported yet.");
365                 return -1;
366         }
367         err=eXosip_listen_addr(proto, addr, port, ipv6 ?  PF_INET6 : PF_INET, 0);
368 #ifdef HAVE_EXOSIP_GET_SOCKET
369         ms_message("Exosip has socket number %i",eXosip_get_socket(proto));
370 #endif
371         
372         ctx->running=TRUE;
373         return err;
374 }
375
376 ortp_socket_t sal_get_socket(Sal *ctx){
377 #ifdef HAVE_EXOSIP_GET_SOCKET
378         return eXosip_get_socket(IPPROTO_UDP);
379 #else
380         ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
381         return -1;
382 #endif
383 }
384
385 void sal_set_user_agent(Sal *ctx, const char *user_agent){
386         eXosip_set_user_agent(user_agent);
387 }
388
389 void sal_use_session_timers(Sal *ctx, int expires){
390         ctx->session_expires=expires;
391 }
392
393 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
394         ctx->one_matching_codec=one_matching_codec;
395 }
396
397 MSList *sal_get_pending_auths(Sal *sal){
398         return ms_list_copy(sal->pending_auths);
399 }
400
401 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
402         ctx->double_reg=enabled;
403 }
404
405 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval){
406         osip_via_t *via=NULL;
407         osip_generic_param_t *param=NULL;
408         const char *rport=NULL;
409
410         *rportval=5060;
411         *received=NULL;
412         osip_message_get_via(msg,0,&via);
413         if (!via) return -1;
414
415         /* it is useless to do that with tcp since client socket might have a different port
416                 than the server socket.
417         */
418         if (strcasecmp(via->protocol,"tcp")==0) return -1;
419         
420         if (via->port && via->port[0]!='\0')
421                 *rportval=atoi(via->port);
422         
423         osip_via_param_get_byname(via,"rport",&param);
424         if (param) {
425                 rport=param->gvalue;
426                 if (rport && rport[0]!='\0') *rportval=atoi(rport);
427                 else *rportval=5060;
428                 *received=via->host;
429         }
430         param=NULL;
431         osip_via_param_get_byname(via,"received",&param);
432         if (param) *received=param->gvalue;
433
434         if (rport==NULL && *received==NULL) return -1;
435         return 0;
436 }
437
438 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
439         int sdplen;
440         char clen[10];
441         char *sdp=NULL;
442         sdp_message_to_str(msg,&sdp);
443         sdplen=strlen(sdp);
444         snprintf(clen,sizeof(clen),"%i",sdplen);
445         osip_message_set_body(sip,sdp,sdplen);
446         osip_message_set_content_type(sip,"application/sdp");
447         osip_message_set_content_length(sip,clen);
448         osip_free(sdp);
449 }
450
451 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
452         sdp_message_t *msg=media_description_to_sdp(desc);
453         if (msg==NULL) {
454                 ms_error("Fail to print sdp message !");
455                 return;
456         }
457         set_sdp(sip,msg);
458         sdp_message_free(msg);
459 }
460
461 static void sdp_process(SalOp *h){
462         ms_message("Doing SDP offer/answer process");
463         if (h->result){
464                 sal_media_description_unref(h->result);
465         }
466         h->result=sal_media_description_new();
467         if (h->sdp_offering){   
468                 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
469         }else{
470                 int i;
471                 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
472                 h->sdp_answer=media_description_to_sdp(h->result);
473                 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
474                  It should contains media parameters constraint from the remote offer, not our response*/
475                 strcpy(h->result->addr,h->base.remote_media->addr);
476                 h->result->bandwidth=h->base.remote_media->bandwidth;
477                 for(i=0;i<h->result->nstreams;++i){
478                         if (h->result->streams[i].port>0){
479                                 strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr);
480                                 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
481                                 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
482                                 h->result->streams[i].port=h->base.remote_media->streams[i].port;
483                         }
484                 }
485         }
486         
487 }
488
489 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
490         if (desc)
491                 sal_media_description_ref(desc);
492         if (h->base.local_media)
493                 sal_media_description_unref(h->base.local_media);
494         h->base.local_media=desc;
495         return 0;
496 }
497
498 int sal_call(SalOp *h, const char *from, const char *to){
499         int err;
500         osip_message_t *invite=NULL;
501         sal_op_set_from(h,from);
502         sal_op_set_to(h,to);
503         sal_exosip_fix_route(h);
504         err=eXosip_call_build_initial_invite(&invite,to,from,sal_op_get_route(h),"Phone call");
505         if (err!=0){
506                 ms_error("Could not create call.");
507                 return -1;
508         }
509         osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
510         if (h->base.contact){
511                 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
512                 osip_message_set_contact(invite,h->base.contact);
513         }
514         if (h->base.root->session_expires!=0){
515                 osip_message_set_header(invite, "Session-expires", "200");
516                 osip_message_set_supported(invite, "timer");
517         }
518         if (h->base.local_media){
519                 h->sdp_offering=TRUE;
520                 set_sdp_from_desc(invite,h->base.local_media);
521         }else h->sdp_offering=FALSE;
522         if (h->replaces){
523                 osip_message_set_header(invite,"Replaces",h->replaces);
524                 if (h->referred_by)
525                         osip_message_set_header(invite,"Referred-By",h->referred_by);
526         }
527         
528         eXosip_lock();
529         err=eXosip_call_send_initial_invite(invite);
530         eXosip_unlock();
531         h->cid=err;
532         if (err<0){
533                 ms_error("Fail to send invite !");
534                 return -1;
535         }else{
536                 sal_add_call(h->base.root,h);
537         }
538         return 0;
539 }
540
541 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
542         osip_message_t *msg;
543         int err;
544         
545         /*if early media send also 180 and 183 */
546         if (early_media && h->sdp_answer){
547                 msg=NULL;
548                 eXosip_lock();
549                 err=eXosip_call_build_answer(h->tid,180,&msg);
550                 if (msg){
551                         set_sdp(msg,h->sdp_answer);
552                         eXosip_call_send_answer(h->tid,180,msg);
553                 }
554                 msg=NULL;
555                 err=eXosip_call_build_answer(h->tid,183,&msg);
556                 if (msg){
557                         set_sdp(msg,h->sdp_answer);
558                         eXosip_call_send_answer(h->tid,183,msg);
559                 }
560                 eXosip_unlock();
561         }else{
562                 eXosip_lock();
563                 eXosip_call_send_answer(h->tid,180,NULL);
564                 eXosip_unlock();
565         }
566         return 0;
567 }
568
569 int sal_call_accept(SalOp * h){
570         osip_message_t *msg;
571         const char *contact=sal_op_get_contact(h);
572         /* sends a 200 OK */
573         int err=eXosip_call_build_answer(h->tid,200,&msg);
574         if (err<0 || msg==NULL){
575                 ms_error("Fail to build answer for call: err=%i",err);
576                 return -1;
577         }
578         if (h->base.root->session_expires!=0){
579                 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
580         }
581
582         if (contact) {
583                 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
584                 osip_message_set_contact(msg,contact);
585         }
586         
587         if (h->base.local_media){
588                 /*this is the case where we received an invite without SDP*/
589                 if (h->sdp_offering) {
590                         set_sdp_from_desc(msg,h->base.local_media);
591                 }else{
592                         if (h->sdp_answer){
593                                 set_sdp(msg,h->sdp_answer);
594                                 sdp_message_free(h->sdp_answer);
595                                 h->sdp_answer=NULL;
596                         }
597                 }
598         }else{
599                 ms_error("You are accepting a call but not defined any media capabilities !");
600         }
601         eXosip_call_send_answer(h->tid,200,msg);
602         return 0;
603 }
604
605 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
606         if (reason==SalReasonBusy){
607                 eXosip_lock();
608                 eXosip_call_send_answer(h->tid,486,NULL);
609                 eXosip_unlock();
610         }
611         else if (reason==SalReasonTemporarilyUnavailable){
612                 eXosip_lock();
613                 eXosip_call_send_answer(h->tid,480,NULL);
614                 eXosip_unlock();
615         }else if (reason==SalReasonDoNotDisturb){
616                 eXosip_lock();
617                 eXosip_call_send_answer(h->tid,600,NULL);
618                 eXosip_unlock();
619         }else if (reason==SalReasonMedia){
620                 eXosip_lock();
621                 eXosip_call_send_answer(h->tid,415,NULL);
622                 eXosip_unlock();
623         }else if (redirect!=NULL && reason==SalReasonRedirect){
624                 osip_message_t *msg;
625                 int code;
626                 if (strstr(redirect,"sip:")!=0) code=302;
627                 else code=380;
628                 eXosip_lock();
629                 eXosip_call_build_answer(h->tid,code,&msg);
630                 osip_message_set_contact(msg,redirect);
631                 eXosip_call_send_answer(h->tid,code,msg);
632                 eXosip_unlock();
633         }else sal_call_terminate(h);
634         return 0;
635 }
636
637 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
638         if (h->base.local_media && h->base.remote_media && !h->result){
639                 sdp_process(h);
640         }
641         return h->result;
642 }
643
644 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
645         if (refered_call->replaces)
646                 h->replaces=ms_strdup(refered_call->replaces);
647         if (refered_call->referred_by)
648                 h->referred_by=ms_strdup(refered_call->referred_by);
649         return 0;
650 }
651
652 int sal_ping(SalOp *op, const char *from, const char *to){
653         osip_message_t *options=NULL;
654         
655         sal_op_set_from(op,from);
656         sal_op_set_to(op,to);
657         /*bug here: eXosip2 does not honor the route argument*/
658         eXosip_options_build_request (&options, sal_op_get_to(op),
659                         sal_op_get_from(op),sal_op_get_route(op));
660         if (options){
661                 if (op->base.root->session_expires!=0){
662                         osip_message_set_header(options, "Session-expires", "200");
663                         osip_message_set_supported(options, "timer");
664                 }
665                 sal_add_other(sal_op_get_sal(op),op,options);
666                 return eXosip_options_send_request(options);
667         }
668         return -1;
669 }
670
671 int sal_call_accept_refer(SalOp *op){
672         osip_message_t *msg=NULL;
673         int err=0;
674         eXosip_lock();
675         err = eXosip_call_build_notify(op->did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
676         if(msg != NULL)
677         {
678                 osip_message_set_header(msg,(const char *)"event","refer");
679                 osip_message_set_content_type(msg,"message/sipfrag");
680                 osip_message_set_body(msg,"SIP/2.0 100 Trying",sizeof("SIP/2.0 100 Trying"));
681                 eXosip_call_send_request(op->did,msg);
682         }
683         else
684         {
685                 ms_error("could not get a notify built\n");
686         }
687         eXosip_unlock();
688         return err;
689 }
690
691 int sal_call_refer(SalOp *h, const char *refer_to){
692         osip_message_t *msg=NULL;
693         int err=0;
694         eXosip_lock();
695         eXosip_call_build_refer(h->did,refer_to, &msg);
696         if (msg) err=eXosip_call_send_request(h->did, msg);
697         else err=-1;
698         eXosip_unlock();
699         return err;
700 }
701
702 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
703         osip_message_t *msg=NULL;
704         char referto[256]={0};
705         int err=0;
706         eXosip_lock();
707         if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
708                 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
709                 eXosip_unlock();
710                 return -1;
711         }
712         eXosip_call_build_refer(h->did,referto, &msg);
713         osip_message_set_header(msg,"Referred-By",h->base.from);
714         if (msg) err=eXosip_call_send_request(h->did, msg);
715         else err=-1;
716         eXosip_unlock();
717         return err;
718 }
719
720 SalOp *sal_call_get_replaces(SalOp *h){
721         if (h->replaces!=NULL){
722                 int cid;
723                 eXosip_lock();
724                 cid=eXosip_call_find_by_replaces(h->replaces);
725                 eXosip_unlock();
726                 if (cid>0){
727                         SalOp *ret=sal_find_call(h->base.root,cid);
728                         return ret;
729                 }
730         }
731         return NULL;
732 }
733
734 int sal_call_send_dtmf(SalOp *h, char dtmf){
735         osip_message_t *msg=NULL;
736         char dtmf_body[128];
737         char clen[10];
738
739         eXosip_lock();
740         eXosip_call_build_info(h->did,&msg);
741         if (msg){
742                 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
743                 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
744                 osip_message_set_content_type(msg,"application/dtmf-relay");
745                 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
746                 osip_message_set_content_length(msg,clen);              
747                 eXosip_call_send_request(h->did,msg);
748         }
749         eXosip_unlock();
750         return 0;
751 }
752
753 static void push_auth_to_exosip(const SalAuthInfo *info){
754         const char *userid;
755         if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
756         else userid=info->userid;
757         ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
758         eXosip_add_authentication_info (info->username,userid,
759                                   info->password, NULL,info->realm);
760 }
761 /*
762  * Just for symmetry ;-)
763  */
764 static void pop_auth_from_exosip() {
765         eXosip_clear_authentication_info();
766 }
767
768 int sal_call_terminate(SalOp *h){
769         int err;
770         if (h->auth_info) push_auth_to_exosip(h->auth_info);
771         eXosip_lock();
772         err=eXosip_call_terminate(h->cid,h->did);
773         eXosip_unlock();
774         pop_auth_from_exosip();
775         if (err!=0){
776                 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
777         }
778         return 0;
779 }
780
781 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
782         if (h->pending_auth){
783                 push_auth_to_exosip(info);
784                 eXosip_lock();
785                 eXosip_default_action(h->pending_auth);
786                 eXosip_unlock();
787                 ms_message("eXosip_default_action() done");
788                 pop_auth_from_exosip();
789                 eXosip_event_free(h->pending_auth);
790                 sal_remove_pending_auth(sal_op_get_sal(h),h);
791                 h->pending_auth=NULL;
792                 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
793                 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
794         }
795 }
796
797 static void set_network_origin(SalOp *op, osip_message_t *req){
798         const char *received=NULL;
799         int rport=5060;
800         char origin[64];
801         if (extract_received_rport(req,&received,&rport)!=0){
802                 osip_via_t *via=NULL;
803                 char *tmp;
804                 osip_message_get_via(req,0,&via);
805                 received=osip_via_get_host(via);
806                 tmp=osip_via_get_port(via);
807                 if (tmp) rport=atoi(tmp);
808         }
809         snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
810         __sal_op_set_network_origin(op,origin);
811 }
812
813 static void set_remote_ua(SalOp* op, osip_message_t *req){
814         if (op->base.remote_ua==NULL){
815                 osip_header_t *h=NULL;
816                 osip_message_get_user_agent(req,0,&h);
817                 if (h){
818                         op->base.remote_ua=ms_strdup(h->hvalue);
819                 }
820         }
821 }
822
823 static void set_replaces(SalOp *op, osip_message_t *req){
824         osip_header_t *h=NULL;
825
826         if (op->replaces){
827                 ms_free(op->replaces);
828                 op->replaces=NULL;
829         }
830         osip_message_header_get_byname(req,"replaces",0,&h);
831         if (h){
832                 if (h->hvalue && h->hvalue[0]!='\0'){
833                         op->replaces=ms_strdup(h->hvalue);
834                 }
835         }
836 }
837
838 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
839         if (ev->cid>0){
840                 return sal_find_call(sal,ev->cid);
841         }
842         if (ev->rid>0){
843                 return sal_find_register(sal,ev->rid);
844         }
845         if (ev->sid>0){
846                 return sal_find_out_subscribe(sal,ev->sid);
847         }
848         if (ev->nid>0){
849                 return sal_find_in_subscribe(sal,ev->nid);
850         }
851         if (ev->response) return sal_find_other(sal,ev->response);
852         return NULL;
853 }
854
855 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
856         SalOp *op=sal_op_new(sal);
857         osip_from_t *from,*to;
858         osip_call_info_t *call_info;
859         char *tmp;
860         sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
861
862         set_network_origin(op,ev->request);
863         set_remote_ua(op,ev->request);
864         set_replaces(op,ev->request);
865         
866         if (sdp){
867                 op->sdp_offering=FALSE;
868                 op->base.remote_media=sal_media_description_new();
869                 sdp_to_media_description(sdp,op->base.remote_media);
870                 sdp_message_free(sdp);
871         }else op->sdp_offering=TRUE;
872
873         from=osip_message_get_from(ev->request);
874         to=osip_message_get_to(ev->request);
875         osip_from_to_str(from,&tmp);
876         sal_op_set_from(op,tmp);
877         osip_free(tmp);
878         osip_from_to_str(to,&tmp);
879         sal_op_set_to(op,tmp);
880         osip_free(tmp);
881
882         osip_message_get_call_info(ev->request,0,&call_info);
883         if(call_info)
884         {
885                 osip_call_info_to_str(call_info,&tmp);
886                 if( strstr(tmp,"answer-after=") != NULL)
887                 {
888                         op->auto_answer_asked=TRUE;
889                         ms_message("The caller asked to automatically answer the call(Emergency?)\n");
890                 }
891                 osip_free(tmp);
892         }
893
894         op->tid=ev->tid;
895         op->cid=ev->cid;
896         op->did=ev->did;
897         
898         sal_add_call(op->base.root,op);
899         sal->callbacks.call_received(op);
900 }
901
902 static void handle_reinvite(Sal *sal,  eXosip_event_t *ev){
903         SalOp *op=find_op(sal,ev);
904         sdp_message_t *sdp;
905         osip_message_t *msg=NULL;
906
907         if (op==NULL) {
908                 ms_warning("Reinvite for non-existing operation !");
909                 return;
910         }
911         op->reinvite=TRUE;
912         op->tid=ev->tid;
913         sdp=eXosip_get_sdp_info(ev->request);
914         if (op->base.remote_media){
915                 sal_media_description_unref(op->base.remote_media);
916                 op->base.remote_media=NULL;
917         }
918         if (op->result){
919                 sal_media_description_unref(op->result);
920                 op->result=NULL;
921         }
922         if (sdp){
923                 op->sdp_offering=FALSE;
924                 op->base.remote_media=sal_media_description_new();
925                 sdp_to_media_description(sdp,op->base.remote_media);
926                 sdp_message_free(sdp);
927                 sal->callbacks.call_updating(op);
928         }else {
929                 op->sdp_offering=TRUE;
930                 eXosip_lock();
931                 eXosip_call_build_answer(ev->tid,200,&msg);
932                 if (msg!=NULL){
933                         set_sdp_from_desc(msg,op->base.local_media);
934                         eXosip_call_send_answer(ev->tid,200,msg);
935                 }
936                 eXosip_unlock();
937         }
938         
939 }
940
941 static void handle_ack(Sal *sal,  eXosip_event_t *ev){
942         SalOp *op=find_op(sal,ev);
943         sdp_message_t *sdp;
944
945         if (op==NULL) {
946                 ms_warning("ack for non-existing call !");
947                 return;
948         }
949         sdp=eXosip_get_sdp_info(ev->ack);
950         if (sdp){
951                 op->base.remote_media=sal_media_description_new();
952                 sdp_to_media_description(sdp,op->base.remote_media);
953                 sdp_process(op);
954                 sdp_message_free(sdp);
955         }
956         if (op->reinvite){
957                 if (sdp) sal->callbacks.call_updating(op);
958                 op->reinvite=FALSE;
959         }else{
960                 sal->callbacks.call_ack(op);
961         }
962 }
963
964 static void update_contact_from_response(SalOp *op, osip_message_t *response){
965         const char *received;
966         int rport;
967         if (extract_received_rport(response,&received,&rport)==0){
968                 const char *contact=sal_op_get_contact(op);
969                 if (!contact){
970                         /*no contact given yet, use from instead*/
971                         contact=sal_op_get_from(op);
972                 }
973                 if (contact){
974                         SalAddress *addr=sal_address_new(contact);
975                         char *tmp;
976                         sal_address_set_domain(addr,received);
977                         sal_address_set_port_int(addr,rport);
978                         tmp=sal_address_as_string(addr);
979                         ms_message("Contact address updated to %s for this dialog",tmp);
980                         sal_op_set_contact(op,tmp);
981                         sal_address_destroy(addr);
982                         ms_free(tmp);
983                 }
984         }
985 }
986
987 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
988         SalOp *op=find_op(sal,ev);
989         
990         if (op==NULL) {
991                 ms_warning("This call has been canceled.");
992                 eXosip_lock();
993                 eXosip_call_terminate(ev->cid,ev->did);
994                 eXosip_unlock();
995                 return -1;
996         }
997         if (ev->did>0)
998                 op->did=ev->did;
999         op->tid=ev->tid;
1000         
1001         /* update contact if received and rport are set by the server
1002          note: will only be used by remote for next INVITE, if any...*/
1003         update_contact_from_response(op,ev->response);
1004         return 0;
1005 }
1006
1007 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1008         sdp_message_t *sdp;
1009         SalOp *op=find_op(sal,ev);
1010         if (call_proceeding(sal, ev)==-1) return;
1011
1012         set_remote_ua(op,ev->response);
1013         sdp=eXosip_get_sdp_info(ev->response);
1014         if (sdp){
1015                 op->base.remote_media=sal_media_description_new();
1016                 sdp_to_media_description(sdp,op->base.remote_media);
1017                 sdp_message_free(sdp);
1018                 if (op->base.local_media) sdp_process(op);
1019         }
1020         sal->callbacks.call_ringing(op);
1021 }
1022
1023 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1024         sdp_message_t *sdp;
1025         osip_message_t *msg=NULL;
1026         SalOp *op=find_op(sal,ev);
1027         const char *contact;
1028         
1029         if (op==NULL){
1030                 ms_error("A closed call is accepted ?");
1031                 return;
1032         }
1033
1034         op->did=ev->did;
1035         set_remote_ua(op,ev->response);
1036
1037         sdp=eXosip_get_sdp_info(ev->response);
1038         if (sdp){
1039                 op->base.remote_media=sal_media_description_new();
1040                 sdp_to_media_description(sdp,op->base.remote_media);
1041                 sdp_message_free(sdp);
1042                 if (op->base.local_media) sdp_process(op);
1043         }
1044         eXosip_call_build_ack(ev->did,&msg);
1045         contact=sal_op_get_contact(op);
1046         if (contact) {
1047                 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1048                 osip_message_set_contact(msg,contact);
1049         }
1050         if (op->sdp_answer){
1051                 set_sdp(msg,op->sdp_answer);
1052                 sdp_message_free(op->sdp_answer);
1053                 op->sdp_answer=NULL;
1054         }
1055         eXosip_call_send_ack(ev->did,msg);
1056         sal->callbacks.call_accepted(op);
1057 }
1058
1059 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1060         char *from=NULL;
1061         SalOp *op=find_op(sal,ev);
1062         if (op==NULL){
1063                 ms_warning("Call terminated for already closed call ?");
1064                 return;
1065         }
1066         if (ev->request){
1067                 osip_from_to_str(ev->request->from,&from);
1068         }
1069         sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1070         if (from) osip_free(from);
1071 }
1072
1073 static void call_released(Sal *sal, eXosip_event_t *ev){
1074         SalOp *op=find_op(sal,ev);
1075         if (op==NULL){
1076                 ms_warning("No op associated to this call_released()");
1077                 return;
1078         }
1079         if (op->did==-1) {
1080                 sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL, 487);
1081         }
1082         sal->callbacks.call_released(op);
1083 }
1084
1085 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1086         const char *prx_realm=NULL,*www_realm=NULL;
1087         osip_proxy_authenticate_t *prx_auth;
1088         osip_www_authenticate_t *www_auth;
1089         
1090         *username=osip_uri_get_username(resp->from->url);
1091         prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1092         www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1093         if (prx_auth!=NULL)
1094                 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1095         if (www_auth!=NULL)
1096                 www_realm=osip_www_authenticate_get_realm(www_auth);
1097
1098         if (prx_realm){
1099                 *realm=prx_realm;
1100         }else if (www_realm){
1101                 *realm=www_realm;
1102         }else{
1103                 return -1;
1104         }
1105         return 0;
1106 }
1107
1108 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1109         osip_authorization_t *auth=NULL;
1110         osip_proxy_authorization_t *prx_auth=NULL;
1111         
1112         *username=osip_uri_get_username(msg->from->url);
1113         osip_message_get_authorization(msg, 0, &auth);
1114         if (auth){
1115                 *realm=osip_authorization_get_realm(auth);
1116                 return 0;
1117         }
1118         osip_message_get_proxy_authorization(msg,0,&prx_auth);
1119         if (prx_auth){
1120                 *realm=osip_proxy_authorization_get_realm(prx_auth);
1121                 return 0;
1122         }
1123         return -1;
1124 }
1125
1126 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1127         if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1128         if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1129         return -1;
1130 }
1131
1132 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1133         if (op->pending_auth){
1134                 return get_auth_data(op->pending_auth,realm,username);
1135         }
1136         return -1;
1137 }
1138
1139 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1140         SalOp *op;
1141         const char *username,*realm;
1142         op=find_op(sal,ev);
1143         if (op==NULL){
1144                 ms_warning("No operation associated with this authentication !");
1145                 return TRUE;
1146         }
1147         if (get_auth_data(ev,&realm,&username)==0){
1148                 if (op->pending_auth!=NULL)
1149                         eXosip_event_free(op->pending_auth);
1150                 op->pending_auth=ev;
1151                 sal_add_pending_auth (sal,op);
1152                 sal->callbacks.auth_requested(op,realm,username);
1153                 return FALSE;
1154         }
1155         return TRUE;
1156 }
1157
1158 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1159         SalOp *op;
1160         const char *username,*realm;
1161         op=find_op(sal,ev);
1162         if (op==NULL){
1163                 ms_warning("No operation associated with this authentication_ok!");
1164                 return ;
1165         }
1166         if (get_auth_data(ev,&realm,&username)==0){
1167                 sal->callbacks.auth_success(op,realm,username);
1168         }
1169 }
1170
1171 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1172         SalOp *op;
1173         int code=0;
1174         char* computedReason=NULL;
1175         const char *reason=NULL;
1176         SalError error=SalErrorUnknown;
1177         SalReason sr=SalReasonUnknown;
1178         
1179
1180         op=(SalOp*)find_op(sal,ev);
1181
1182         if (op==NULL) {
1183                 ms_warning("Call failure reported for a closed call, ignored.");
1184                 return TRUE;
1185         }
1186
1187         if (ev->response){
1188                 code=osip_message_get_status_code(ev->response);
1189                 reason=osip_message_get_reason_phrase(ev->response);
1190                 osip_header_t *h=NULL;
1191                 if (!osip_message_header_get_byname(    ev->response
1192                                                                                         ,"Reason"
1193                                                                                         ,0
1194                                                                                         ,&h)) {
1195                         computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1196                         reason = computedReason;
1197
1198                 }
1199         }
1200         switch(code)
1201         {
1202                 case 401:
1203                 case 407:
1204                         return process_authentication(sal,ev);
1205                         break;
1206                 case 400:
1207                         error=SalErrorUnknown;
1208                 break;
1209                 case 404:
1210                         error=SalErrorFailure;
1211                         sr=SalReasonNotFound;
1212                 break;
1213                 case 415:
1214                         error=SalErrorFailure;
1215                         sr=SalReasonMedia;
1216                 break;
1217                 case 422:
1218                         eXosip_default_action(ev);
1219                         return TRUE;
1220                 break;
1221                 case 480:
1222                         error=SalErrorFailure;
1223                         sr=SalReasonTemporarilyUnavailable;
1224                 case 486:
1225                         error=SalErrorFailure;
1226                         sr=SalReasonBusy;
1227                 break;
1228                 case 487:
1229                 break;
1230                 case 600:
1231                         error=SalErrorFailure;
1232                         sr=SalReasonDoNotDisturb;
1233                 break;
1234                 case 603:
1235                         error=SalErrorFailure;
1236                         sr=SalReasonDeclined;
1237                 break;
1238                 default:
1239                         if (code>0){
1240                                 error=SalErrorFailure;
1241                                 sr=SalReasonUnknown;
1242                         }else error=SalErrorNoResponse;
1243         }
1244         sal->callbacks.call_failure(op,error,sr,reason,code);
1245         if (computedReason != NULL){
1246                 ms_free(computedReason);
1247         }
1248         return TRUE;
1249 }
1250
1251 /* Request remote side to send us VFU */
1252 void sal_call_send_vfu_request(SalOp *h){
1253         osip_message_t *msg=NULL;
1254         char info_body[] =
1255                         "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1256                          "<media_control>"
1257                          "  <vc_primitive>"
1258                          "    <to_encoder>"
1259                          "      <picture_fast_update></picture_fast_update>"
1260                          "    </to_encoder>"
1261                          "  </vc_primitive>"
1262                          "</media_control>";
1263
1264         char clen[10];
1265
1266         eXosip_lock();
1267         eXosip_call_build_info(h->did,&msg);
1268         if (msg){
1269                 osip_message_set_body(msg,info_body,strlen(info_body));
1270                 osip_message_set_content_type(msg,"application/media_control+xml");
1271                 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1272                 osip_message_set_content_length(msg,clen);
1273                 eXosip_call_send_request(h->did,msg);
1274                 ms_message("Sending VFU request !");
1275         }
1276         eXosip_unlock();
1277 }
1278
1279 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1280         SalOp *op=find_op(sal,ev);
1281         osip_body_t *body=NULL;
1282
1283         if (op==NULL){
1284                 ms_warning("media control xml received without operation context!");
1285                 return ;
1286         }
1287         
1288         osip_message_get_body(ev->request,0,&body);
1289         if (body && body->body!=NULL &&
1290                 strstr(body->body,"picture_fast_update")){
1291                 osip_message_t *ans=NULL;
1292                 ms_message("Receiving VFU request !");
1293                 if (sal->callbacks.vfu_request){
1294                         sal->callbacks.vfu_request(op);
1295                         eXosip_call_build_answer(ev->tid,200,&ans);
1296                         if (ans)
1297                                 eXosip_call_send_answer(ev->tid,200,ans);
1298                         return;
1299                 }
1300         }
1301         /*in all other cases we must say it is not implemented.*/
1302         {
1303                 osip_message_t *ans=NULL;
1304                 eXosip_lock();
1305                 eXosip_call_build_answer(ev->tid,501,&ans);
1306                 if (ans)
1307                         eXosip_call_send_answer(ev->tid,501,ans);
1308                 eXosip_unlock();
1309         }
1310 }
1311
1312 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1313         SalOp *op=find_op(sal,ev);
1314         osip_body_t *body=NULL;
1315
1316         if (op==NULL){
1317                 ms_warning("media dtmf relay received without operation context!");
1318                 return ;
1319         }
1320         
1321         osip_message_get_body(ev->request,0,&body);
1322         if (body && body->body!=NULL){
1323                 osip_message_t *ans=NULL;
1324                 const char *name=strstr(body->body,"Signal");
1325                 if (name==NULL) name=strstr(body->body,"signal");
1326                 if (name==NULL) {
1327                         ms_warning("Could not extract the dtmf name from the SIP INFO.");
1328                 }else{
1329                         char tmp[2];
1330                         name+=strlen("signal");
1331                         if (sscanf(name," = %1s",tmp)==1){
1332                                 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1333                                 if (sal->callbacks.dtmf_received != NULL)
1334                                         sal->callbacks.dtmf_received(op, tmp[0]);
1335                         }
1336                 }
1337                 eXosip_call_build_answer(ev->tid,200,&ans);
1338                 if (ans)
1339                         eXosip_call_send_answer(ev->tid,200,ans);
1340         }
1341 }
1342
1343 static void fill_options_answer(osip_message_t *options){
1344         osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1345         osip_message_set_accept(options,"application/sdp");
1346 }
1347
1348 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1349         osip_header_t *h=NULL;
1350         osip_message_t *ans=NULL;
1351         ms_message("Receiving REFER request !");
1352         osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1353
1354         if (h){
1355                 osip_from_t *from=NULL;
1356                 char *tmp;
1357                 osip_from_init(&from);
1358         
1359                 if (osip_from_parse(from,h->hvalue)==0){
1360                         if (op ){
1361                                 osip_uri_header_t *uh=NULL;
1362                                 osip_header_t *referred_by=NULL;
1363                                 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1364                                 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1365                                         ms_message("Found replaces in Refer-To");
1366                                         if (op->replaces){
1367                                                 ms_free(op->replaces);
1368                                         }
1369                                         op->replaces=ms_strdup(uh->gvalue);
1370                                 }
1371                                 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1372                                 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1373                                         if (op->referred_by)
1374                                                 ms_free(op->referred_by);
1375                                         op->referred_by=ms_strdup(referred_by->hvalue);
1376                                 }
1377                         }
1378                         osip_uri_header_freelist(&from->url->url_headers);
1379                         osip_from_to_str(from,&tmp);
1380                         sal->callbacks.refer_received(sal,op,tmp);
1381                         osip_free(tmp);
1382                         osip_from_free(from);
1383                 }
1384                 eXosip_lock();
1385                 eXosip_call_build_answer(ev->tid,202,&ans);
1386                 if (ans)
1387                         eXosip_call_send_answer(ev->tid,202,ans);
1388                 eXosip_unlock();
1389         }
1390         else
1391         {
1392                 ms_warning("cannot do anything with the refer without destination\n");
1393         }
1394 }
1395
1396 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1397         osip_message_t *ans=NULL;
1398         if (ev->request){
1399                 if (MSG_IS_INFO(ev->request)){
1400                         osip_content_type_t *ct;
1401                         ct=osip_message_get_content_type(ev->request);
1402                         if (ct && ct->subtype){
1403                                 if (strcmp(ct->subtype,"media_control+xml")==0)
1404                                         process_media_control_xml(sal,ev);
1405                                 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1406                                         process_dtmf_relay(sal,ev);
1407                                 else {
1408                                         ms_message("Unhandled SIP INFO.");
1409                                         /*send an "Not implemented" answer*/
1410                                         eXosip_lock();
1411                                         eXosip_call_build_answer(ev->tid,501,&ans);
1412                                         if (ans)
1413                                                 eXosip_call_send_answer(ev->tid,501,ans);
1414                                         eXosip_unlock();
1415                                 }
1416                         }else{
1417                                 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1418                                 eXosip_lock();
1419                                 eXosip_call_build_answer(ev->tid,200,&ans);
1420                                 if (ans)
1421                                         eXosip_call_send_answer(ev->tid,200,ans);
1422                                 eXosip_unlock();
1423                         }
1424                 }else if(MSG_IS_MESSAGE(ev->request)){
1425                         /* SIP messages could be received into call */
1426                         text_received(sal, ev);
1427                         eXosip_lock();
1428                         eXosip_call_build_answer(ev->tid,200,&ans);
1429                         if (ans)
1430                                 eXosip_call_send_answer(ev->tid,200,ans);
1431                         eXosip_unlock();
1432                 }else if(MSG_IS_REFER(ev->request)){
1433                         SalOp *op=find_op(sal,ev);
1434                         
1435                         ms_message("Receiving REFER request !");
1436                         process_refer(sal,op,ev);
1437                 }else if(MSG_IS_NOTIFY(ev->request)){
1438                         osip_header_t *h=NULL;
1439                         char *from=NULL;
1440                         SalOp *op=find_op(sal,ev);
1441
1442                         ms_message("Receiving NOTIFY request !");
1443                         osip_from_to_str(ev->request->from,&from);
1444                         osip_message_header_get_byname(ev->request,"Event",0,&h);
1445                         if(h)
1446                                 sal->callbacks.notify(op,from,h->hvalue);
1447                         /*answer that we received the notify*/
1448                         eXosip_lock();
1449                         eXosip_call_build_answer(ev->tid,200,&ans);
1450                         if (ans)
1451                                 eXosip_call_send_answer(ev->tid,200,ans);
1452                         eXosip_unlock();
1453                         osip_free(from);
1454                 }else if (MSG_IS_OPTIONS(ev->request)){
1455                         eXosip_lock();
1456                         eXosip_call_build_answer(ev->tid,200,&ans);
1457                         if (ans){
1458                                 fill_options_answer(ans);
1459                                 eXosip_call_send_answer(ev->tid,200,ans);
1460                         }
1461                         eXosip_unlock();
1462                 }
1463         }else ms_warning("call_message_new: No request ?");
1464 }
1465
1466 static void inc_update(Sal *sal, eXosip_event_t *ev){
1467         osip_message_t *msg=NULL;
1468         ms_message("Processing incoming UPDATE");
1469         eXosip_lock();
1470         eXosip_message_build_answer(ev->tid,200,&msg);
1471         if (msg!=NULL)
1472                 eXosip_message_send_answer(ev->tid,200,msg);
1473         eXosip_unlock();
1474 }
1475
1476 static bool_t comes_from_local_if(osip_message_t *msg){
1477         osip_via_t *via=NULL;
1478         osip_message_get_via(msg,0,&via);
1479         if (via){
1480                 const char *host;
1481                 host=osip_via_get_host(via);
1482                 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1483                         osip_generic_param_t *param=NULL;
1484                         osip_via_param_get_byname(via,"received",&param);
1485                         if (param==NULL) return TRUE;
1486                         if (param->gvalue &&
1487                                 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1488                                 return TRUE;
1489                         }
1490                 }
1491         }
1492         return FALSE;
1493 }
1494
1495 static void text_received(Sal *sal, eXosip_event_t *ev){
1496         osip_body_t *body=NULL;
1497         char *from=NULL,*msg;
1498         
1499         osip_message_get_body(ev->request,0,&body);
1500         if (body==NULL){
1501                 ms_error("Could not get text message from SIP body");
1502                 return;
1503         }
1504         msg=body->body;
1505         osip_from_to_str(ev->request->from,&from);
1506         sal->callbacks.text_received(sal,from,msg);
1507         osip_free(from);
1508 }
1509
1510
1511
1512 static void other_request(Sal *sal, eXosip_event_t *ev){
1513         ms_message("in other_request");
1514         if (ev->request==NULL) return;
1515         if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1516                 text_received(sal,ev);
1517                 eXosip_message_send_answer(ev->tid,200,NULL);
1518         }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1519                 osip_message_t *options=NULL;
1520                 eXosip_options_build_answer(ev->tid,200,&options);
1521                 fill_options_answer(options);
1522                 eXosip_options_send_answer(ev->tid,200,options);
1523         }else if (strcmp(ev->request->sip_method,"WAKEUP")==0
1524                 && comes_from_local_if(ev->request)) {
1525                 eXosip_message_send_answer(ev->tid,200,NULL);
1526                 ms_message("Receiving WAKEUP request !");
1527                 sal->callbacks.internal_message(sal,"WAKEUP");
1528         }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1529                 ms_message("Receiving REFER request !");
1530                 if (comes_from_local_if(ev->request)) {
1531                         process_refer(sal,NULL,ev);
1532                 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1533         }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1534                 inc_update(sal,ev);
1535     }else {
1536                 char *tmp=NULL;
1537                 size_t msglen=0;
1538                 osip_message_to_str(ev->request,&tmp,&msglen);
1539                 if (tmp){
1540                         ms_message("Unsupported request received:\n%s",tmp);
1541                         osip_free(tmp);
1542                 }
1543                 /*answer with a 501 Not implemented*/
1544                 eXosip_message_send_answer(ev->tid,501,NULL);
1545         }
1546 }
1547
1548 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1549         osip_via_t *via=NULL;
1550         osip_message_get_via(msg,0,&via);
1551         if (via){
1552                 osip_free(via->port);
1553                 via->port=osip_strdup(port);
1554                 osip_free(via->host);
1555                 via->host=osip_strdup(ip);
1556         }
1557 }
1558
1559 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1560         osip_message_t *msg;
1561         const char *received;
1562         int rport;
1563         osip_contact_t *ctt=NULL;
1564         char *tmp;
1565         char port[20];
1566         SalAddress *addr;
1567         Sal *sal=op->base.root;
1568
1569         if (sal->double_reg==FALSE) return FALSE;
1570         
1571         if (extract_received_rport(last_answer,&received,&rport)==-1) return FALSE;
1572         osip_message_get_contact(orig_request,0,&ctt);
1573         if (strcmp(ctt->url->host,received)==0){
1574                 /*ip address matches, check ports*/
1575                 const char *contact_port=ctt->url->port;
1576                 if (contact_port==NULL || contact_port[0]=='\0')
1577                         contact_port="5060";
1578                 if (atoi(contact_port)==rport){
1579                         ms_message("Register has up to date contact, doing nothing.");
1580                         return FALSE;
1581                 }else ms_message("ports do not match, need to update the register (%s <> %i)", contact_port,rport);
1582         }
1583         eXosip_lock();
1584         msg=NULL;
1585         eXosip_register_build_register(op->rid,op->expires,&msg);
1586         if (msg==NULL){
1587                 eXosip_unlock();
1588                 ms_warning("Fail to create a contact updated register.");
1589                 return FALSE;
1590         }
1591         osip_message_get_contact(msg,0,&ctt);
1592         if (ctt->url->host!=NULL){
1593                 osip_free(ctt->url->host);
1594         }
1595         ctt->url->host=osip_strdup(received);
1596         if (ctt->url->port!=NULL){
1597                 osip_free(ctt->url->port);
1598         }
1599         snprintf(port,sizeof(port),"%i",rport);
1600         ctt->url->port=osip_strdup(port);
1601         if (op->masquerade_via) masquerade_via(msg,received,port);
1602         eXosip_register_send_register(op->rid,msg);
1603         eXosip_unlock();
1604         osip_contact_to_str(ctt,&tmp);
1605         addr=sal_address_new(tmp);
1606         osip_free(tmp);
1607         sal_address_clean(addr);
1608         tmp=sal_address_as_string(addr);
1609         sal_op_set_contact(op,tmp);
1610         sal_address_destroy(addr);
1611         ms_message("Resending new register with updated contact %s",tmp);
1612         ms_free(tmp);
1613         return TRUE;
1614 }
1615
1616 static void registration_success(Sal *sal, eXosip_event_t *ev){
1617         SalOp *op=sal_find_register(sal,ev->rid);
1618         osip_header_t *h=NULL;
1619         bool_t registered;
1620         if (op==NULL){
1621                 ms_error("Receiving register response for unknown operation");
1622                 return;
1623         }
1624         osip_message_get_expires(ev->request,0,&h);
1625         if (h!=NULL && atoi(h->hvalue)!=0){
1626                 registered=TRUE;
1627                 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1628                         sal->callbacks.register_success(op,registered);
1629                 }
1630         }else {
1631                 sal->callbacks.register_success(op,FALSE);
1632         }
1633 }
1634
1635 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1636         int status_code=0;
1637         const char *reason=NULL;
1638         SalOp *op=sal_find_register(sal,ev->rid);
1639         SalReason sr=SalReasonUnknown;
1640         SalError se=SalErrorUnknown;
1641         
1642         if (op==NULL){
1643                 ms_error("Receiving register failure for unknown operation");
1644                 return TRUE;
1645         }
1646         if (ev->response){
1647                 status_code=osip_message_get_status_code(ev->response);
1648                 reason=osip_message_get_reason_phrase(ev->response);
1649         }
1650         switch(status_code){
1651                 case 401:
1652                 case 407:
1653                         return process_authentication(sal,ev);
1654                         break;
1655                 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1656                                  in vias, such as ekiga.net 
1657                                  On the opposite, freephonie.net bugs when via are masqueraded.
1658                                  */
1659                         op->masquerade_via=TRUE;
1660                 default:
1661                         /* if contact is up to date, process the failure, otherwise resend a new register with
1662                                 updated contact first, just in case the faillure is due to incorrect contact */
1663                         if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1664                                 return TRUE; /*we are retrying with an updated contact*/
1665                         if (status_code==403){
1666                                 se=SalErrorFailure;
1667                                 sr=SalReasonForbidden;
1668                         }else if (status_code==0){
1669                                 se=SalErrorNoResponse;
1670                         }
1671                         sal->callbacks.register_failure(op,se,sr,reason);
1672         }
1673         return TRUE;
1674 }
1675
1676 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1677         SalOp *op=find_op(sal,ev);
1678
1679         if (op==NULL){
1680                 ms_warning("other_request_reply(): Receiving response to unknown request.");
1681                 return;
1682         }
1683         if (ev->response){
1684                 update_contact_from_response(op,ev->response);
1685                 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
1686                         sal->callbacks.ping_reply(op);
1687         }
1688 }
1689
1690 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
1691         ms_message("linphone process event get a message %d\n",ev->type);
1692         switch(ev->type){
1693                 case EXOSIP_CALL_ANSWERED:
1694                         ms_message("CALL_ANSWERED\n");
1695                         call_accepted(sal,ev);
1696                         authentication_ok(sal,ev);
1697                         break;
1698                 case EXOSIP_CALL_CLOSED:
1699                 case EXOSIP_CALL_CANCELLED:
1700                         ms_message("CALL_CLOSED or CANCELLED\n");
1701                         call_terminated(sal,ev);
1702                         break;
1703                 case EXOSIP_CALL_TIMEOUT:
1704                 case EXOSIP_CALL_NOANSWER:
1705                         ms_message("CALL_TIMEOUT or NOANSWER\n");
1706                         return call_failure(sal,ev);
1707                         break;
1708                 case EXOSIP_CALL_REQUESTFAILURE:
1709                 case EXOSIP_CALL_GLOBALFAILURE:
1710                 case EXOSIP_CALL_SERVERFAILURE:
1711                         ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
1712                         return call_failure(sal,ev);
1713                         break;
1714                 case EXOSIP_CALL_RELEASED:
1715                         ms_message("CALL_RELEASED\n");
1716                         call_released(sal, ev);
1717                         break;
1718                 case EXOSIP_CALL_INVITE:
1719                         ms_message("CALL_NEW\n");
1720                         inc_new_call(sal,ev);
1721                         break;
1722                 case EXOSIP_CALL_REINVITE:
1723                         handle_reinvite(sal,ev);
1724                         break;
1725                 case EXOSIP_CALL_ACK:
1726                         ms_message("CALL_ACK");
1727                         handle_ack(sal,ev);
1728                         break;
1729                 case EXOSIP_CALL_REDIRECTED:
1730                         ms_message("CALL_REDIRECTED");
1731                         eXosip_default_action(ev);
1732                         break;
1733                 case EXOSIP_CALL_PROCEEDING:
1734                         ms_message("CALL_PROCEEDING");
1735                         call_proceeding(sal,ev);
1736                         break;
1737                 case EXOSIP_CALL_RINGING:
1738                         ms_message("CALL_RINGING");
1739                         call_ringing(sal,ev);
1740                         break;
1741                 case EXOSIP_CALL_MESSAGE_NEW:
1742                         ms_message("EXOSIP_CALL_MESSAGE_NEW");
1743                         call_message_new(sal,ev);
1744                         break;
1745                 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
1746                         if (ev->response &&
1747                                 (ev->response->status_code==407 || ev->response->status_code==401)){
1748                                  return process_authentication(sal,ev);
1749                         }
1750                         break;
1751                 case EXOSIP_IN_SUBSCRIPTION_NEW:
1752                         ms_message("CALL_IN_SUBSCRIPTION_NEW ");
1753                         sal_exosip_subscription_recv(sal,ev);
1754                         break;
1755                 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
1756                         ms_message("CALL_SUBSCRIPTION_NEW ");
1757                         sal_exosip_in_subscription_closed(sal,ev);
1758                         break;
1759                 case EXOSIP_SUBSCRIPTION_UPDATE:
1760                         ms_message("CALL_SUBSCRIPTION_UPDATE");
1761                         break;
1762                 case EXOSIP_SUBSCRIPTION_NOTIFY:
1763                         ms_message("CALL_SUBSCRIPTION_NOTIFY");
1764                         sal_exosip_notify_recv(sal,ev);
1765                         break;
1766                 case EXOSIP_SUBSCRIPTION_ANSWERED:
1767                         ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
1768                         sal_exosip_subscription_answered(sal,ev);
1769                         break;
1770                 case EXOSIP_SUBSCRIPTION_CLOSED:
1771                         ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
1772                         sal_exosip_subscription_closed(sal,ev);
1773                         break;
1774                 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE:   /**< announce a request failure      */
1775                         if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
1776                                 return process_authentication(sal,ev);
1777                         }
1778         case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
1779                 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
1780                         sal_exosip_subscription_closed(sal,ev);
1781                         break;
1782                 case EXOSIP_REGISTRATION_FAILURE:
1783                         ms_message("REGISTRATION_FAILURE\n");
1784                         return registration_failure(sal,ev);
1785                         break;
1786                 case EXOSIP_REGISTRATION_SUCCESS:
1787                         authentication_ok(sal,ev);
1788                         registration_success(sal,ev);
1789                         break;
1790                 case EXOSIP_MESSAGE_NEW:
1791                         other_request(sal,ev);
1792                         break;
1793                 case EXOSIP_MESSAGE_PROCEEDING:
1794                 case EXOSIP_MESSAGE_ANSWERED:
1795                 case EXOSIP_MESSAGE_REDIRECTED:
1796                 case EXOSIP_MESSAGE_SERVERFAILURE:
1797                 case EXOSIP_MESSAGE_GLOBALFAILURE:
1798                         other_request_reply(sal,ev);
1799                         break;
1800                 case EXOSIP_MESSAGE_REQUESTFAILURE:
1801                 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
1802                         if (ev->response) {
1803                                 switch (ev->response->status_code) {
1804                                         case 407:
1805                                         case 401:
1806                                                 return process_authentication(sal,ev);
1807                                         case 412: {
1808                                                 eXosip_automatic_action ();
1809                                                 return 1;
1810                                         }
1811                                 }
1812                         }
1813                         other_request_reply(sal,ev);
1814                         break;
1815                 default:
1816                         ms_message("Unhandled exosip event ! %i",ev->type);
1817                         break;
1818         }
1819         return TRUE;
1820 }
1821
1822 int sal_iterate(Sal *sal){
1823         eXosip_event_t *ev;
1824         while((ev=eXosip_event_wait(0,0))!=NULL){
1825                 if (process_event(sal,ev))
1826                         eXosip_event_free(ev);
1827         }
1828         eXosip_lock();
1829         eXosip_automatic_refresh();
1830         eXosip_unlock();
1831         return 0;
1832 }
1833
1834 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
1835         osip_message_t *msg;
1836         sal_op_set_route(h,proxy);
1837         if (h->rid==-1){
1838                 eXosip_lock();
1839                 h->rid=eXosip_register_build_initial_register(from,proxy,sal_op_get_contact(h),expires,&msg);
1840                 sal_add_register(h->base.root,h);
1841         }else{
1842                 eXosip_lock();
1843                 eXosip_register_build_register(h->rid,expires,&msg);    
1844         }
1845         eXosip_register_send_register(h->rid,msg);
1846         eXosip_unlock();
1847         h->expires=expires;
1848         return 0;
1849 }
1850
1851 int sal_unregister(SalOp *h){
1852         osip_message_t *msg=NULL;
1853         eXosip_lock();
1854         eXosip_register_build_register(h->rid,0,&msg);
1855         if (msg) eXosip_register_send_register(h->rid,msg);
1856         else ms_warning("Could not build unREGISTER !");
1857         eXosip_unlock();
1858         return 0;
1859 }
1860
1861 SalAddress * sal_address_new(const char *uri){
1862         osip_from_t *from;
1863         osip_from_init(&from);
1864         if (osip_from_parse(from,uri)!=0){
1865                 osip_from_free(from);
1866                 return NULL;
1867         }
1868         if (from->displayname!=NULL && from->displayname[0]=='"'){
1869                 char *unquoted=osip_strdup_without_quote(from->displayname);
1870                 osip_free(from->displayname);
1871                 from->displayname=unquoted;
1872         }
1873         return (SalAddress*)from;
1874 }
1875
1876 SalAddress * sal_address_clone(const SalAddress *addr){
1877         osip_from_t *ret=NULL;
1878         osip_from_clone((osip_from_t*)addr,&ret);
1879         return (SalAddress*)ret;
1880 }
1881
1882 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
1883
1884 const char *sal_address_get_scheme(const SalAddress *addr){
1885         const osip_from_t *u=(const osip_from_t*)addr;
1886         return null_if_empty(u->url->scheme);
1887 }
1888
1889 const char *sal_address_get_display_name(const SalAddress* addr){
1890         const osip_from_t *u=(const osip_from_t*)addr;
1891         return null_if_empty(u->displayname);
1892 }
1893
1894 const char *sal_address_get_username(const SalAddress *addr){
1895         const osip_from_t *u=(const osip_from_t*)addr;
1896         return null_if_empty(u->url->username);
1897 }
1898
1899 const char *sal_address_get_domain(const SalAddress *addr){
1900         const osip_from_t *u=(const osip_from_t*)addr;
1901         return null_if_empty(u->url->host);
1902 }
1903
1904 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
1905         osip_from_t *u=(osip_from_t*)addr;
1906         if (u->displayname!=NULL){
1907                 osip_free(u->displayname);
1908                 u->displayname=NULL;
1909         }
1910         if (display_name!=NULL && display_name[0]!='\0'){
1911                 u->displayname=osip_strdup(display_name);
1912         }
1913 }
1914
1915 void sal_address_set_username(SalAddress *addr, const char *username){
1916         osip_from_t *uri=(osip_from_t*)addr;
1917         if (uri->url->username!=NULL){
1918                 osip_free(uri->url->username);
1919                 uri->url->username=NULL;
1920         }
1921         if (username)
1922                 uri->url->username=osip_strdup(username);
1923 }
1924
1925 void sal_address_set_domain(SalAddress *addr, const char *host){
1926         osip_from_t *uri=(osip_from_t*)addr;
1927         if (uri->url->host!=NULL){
1928                 osip_free(uri->url->host);
1929                 uri->url->host=NULL;
1930         }
1931         if (host)
1932                 uri->url->host=osip_strdup(host);
1933 }
1934
1935 void sal_address_set_port(SalAddress *addr, const char *port){
1936         osip_from_t *uri=(osip_from_t*)addr;
1937         if (uri->url->port!=NULL){
1938                 osip_free(uri->url->port);
1939                 uri->url->port=NULL;
1940         }
1941         if (port)
1942                 uri->url->port=osip_strdup(port);
1943 }
1944
1945 void sal_address_set_port_int(SalAddress *uri, int port){
1946         char tmp[12];
1947         if (port==5060){
1948                 /*this is the default, special case to leave the port field blank*/
1949                 sal_address_set_port(uri,NULL);
1950                 return;
1951         }
1952         snprintf(tmp,sizeof(tmp),"%i",port);
1953         sal_address_set_port(uri,tmp);
1954 }
1955
1956 void sal_address_clean(SalAddress *addr){
1957         osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
1958         osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
1959 }
1960
1961 char *sal_address_as_string(const SalAddress *u){
1962         char *tmp,*ret;
1963         osip_from_t *from=(osip_from_t *)u;
1964         char *old_displayname=NULL;
1965         /* hack to force use of quotes around the displayname*/
1966         if (from->displayname!=NULL
1967             && from->displayname[0]!='"'){
1968                 old_displayname=from->displayname;
1969                 from->displayname=osip_enquote(from->displayname);
1970         }
1971         osip_from_to_str(from,&tmp);
1972         if (old_displayname!=NULL){
1973                 ms_free(from->displayname);
1974                 from->displayname=old_displayname;
1975         }
1976         ret=ms_strdup(tmp);
1977         osip_free(tmp);
1978         return ret;
1979 }
1980
1981 char *sal_address_as_string_uri_only(const SalAddress *u){
1982         char *tmp=NULL,*ret;
1983         osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
1984         ret=ms_strdup(tmp);
1985         osip_free(tmp);
1986         return ret;
1987 }
1988 void sal_address_add_param(SalAddress *u,const char* name,const char* value) {
1989         osip_uri_uparam_add     (((osip_from_t*)u)->url,ms_strdup(name),ms_strdup(value));
1990 }
1991
1992 void sal_address_destroy(SalAddress *u){
1993         osip_from_free((osip_from_t*)u);
1994 }
1995
1996 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
1997         ctx->keepalive_period=value;
1998         eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
1999 }
2000 unsigned int sal_get_keepalive_period(Sal *ctx) {
2001         return ctx->keepalive_period;
2002 }
2003
2004 const char * sal_address_get_port(const SalAddress *addr) {
2005         const osip_from_t *u=(const osip_from_t*)addr;
2006         return null_if_empty(u->url->port);
2007 }
2008
2009 int sal_address_get_port_int(const SalAddress *uri) {
2010         const char* port = sal_address_get_port(uri);
2011         if (port != NULL) {
2012                 return atoi(port);
2013         } else {
2014                 return 5060;
2015         }
2016 }
2017
2018 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2019 int sal_call_update(SalOp *h, const char *subject){
2020         int err=0;
2021         osip_message_t *reinvite=NULL;
2022
2023         eXosip_lock();
2024         if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != OSIP_SUCCESS || reinvite==NULL){
2025                 eXosip_unlock();
2026                 return -1;
2027         }
2028         eXosip_unlock();
2029         osip_message_set_subject(reinvite,subject);
2030         osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2031         if (h->base.root->session_expires!=0){
2032                 osip_message_set_header(reinvite, "Session-expires", "200");
2033                 osip_message_set_supported(reinvite, "timer");
2034         }
2035         if (h->base.local_media){
2036                 h->sdp_offering=TRUE;
2037                 set_sdp_from_desc(reinvite,h->base.local_media);
2038         }else h->sdp_offering=FALSE;
2039         eXosip_lock();
2040         err = eXosip_call_send_request(h->did, reinvite);
2041         eXosip_unlock();
2042         return err;
2043 }