3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
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.
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.
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.
23 #include "sal_eXosip2.h"
25 #include "offeranswer.h"
26 /*this function is not declared in some versions of eXosip*/
27 extern void *eXosip_call_get_reference(int cid);
29 static void text_received(Sal *sal, eXosip_event_t *ev);
31 static void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
33 while((data=osip_list_get(l,0))!=NULL){
34 osip_list_remove(l,0);
39 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
40 if (eXosip_guess_localip(address_family,ip,iplen)<0){
41 /*default to something */
42 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
43 ms_error("Could not find default routable ip address !");
47 static SalOp * sal_find_register(Sal *sal, int rid){
50 for(elem=sal->registers;elem!=NULL;elem=elem->next){
51 op=(SalOp*)elem->data;
52 if (op->rid==rid) return op;
57 static void sal_add_register(Sal *sal, SalOp *op){
58 sal->registers=ms_list_append(sal->registers,op);
61 static void sal_remove_register(Sal *sal, int rid){
64 for(elem=sal->registers;elem!=NULL;elem=elem->next){
65 op=(SalOp*)elem->data;
67 sal->registers=ms_list_remove_link(sal->registers,elem);
73 static SalOp * sal_find_other(Sal *sal, osip_message_t *response){
76 osip_call_id_t *callid=osip_message_get_call_id(response);
78 ms_error("There is no call-id in this response !");
81 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
82 op=(SalOp*)elem->data;
83 if (osip_call_id_match(callid,op->call_id)==0) return op;
88 static void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
89 osip_call_id_t *callid=osip_message_get_call_id(request);
91 ms_error("There is no call id in the request !");
94 osip_call_id_clone(callid,&op->call_id);
95 sal->other_transactions=ms_list_append(sal->other_transactions,op);
98 static void sal_remove_other(Sal *sal, SalOp *op){
99 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
103 static void sal_add_pending_auth(Sal *sal, SalOp *op){
104 sal->pending_auths=ms_list_append(sal->pending_auths,op);
108 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
109 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
112 void sal_exosip_fix_route(SalOp *op){
113 if (sal_op_get_route(op)!=NULL){
114 osip_route_t *rt=NULL;
115 osip_uri_param_t *lr_param=NULL;
117 osip_route_init(&rt);
118 if (osip_route_parse(rt,sal_op_get_route(op))<0){
119 ms_warning("Bad route %s!",sal_op_get_route(op));
120 sal_op_set_route(op,NULL);
122 /* check if the lr parameter is set , if not add it */
123 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
126 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
127 osip_route_to_str(rt,&tmproute);
128 sal_op_set_route(op,tmproute);
136 SalOp * sal_op_new(Sal *sal){
137 SalOp *op=ms_new(SalOp,1);
138 __sal_op_init(op,sal);
139 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
141 op->supports_session_timers=FALSE;
142 op->sdp_offering=TRUE;
143 op->pending_auth=NULL;
147 op->masquerade_via=FALSE;
148 op->auto_answer_asked=FALSE;
152 bool_t sal_call_autoanswer_asked(SalOp *op)
154 return op->auto_answer_asked;
157 void sal_op_release(SalOp *op){
159 sdp_message_free(op->sdp_answer);
160 if (op->pending_auth)
161 eXosip_event_free(op->pending_auth);
163 sal_remove_register(op->base.root,op->rid);
166 ms_message("Cleaning cid %i",op->cid);
167 eXosip_call_set_reference(op->cid,NULL);
170 sal_remove_out_subscribe(op->base.root,op);
173 sal_remove_in_subscribe(op->base.root,op);
175 osip_call_id_free(op->call_id);
178 if (op->pending_auth){
179 sal_remove_pending_auth(op->base.root,op);
182 sal_media_description_unref(op->result);
184 sal_remove_other(op->base.root,op);
185 osip_call_id_free(op->call_id);
190 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
191 int ortp_level=ORTP_DEBUG;
197 ortp_level=ORTP_MESSAGE;
200 ortp_level=ORTP_WARNING;
204 ortp_level=ORTP_ERROR;
207 ortp_level=ORTP_FATAL;
209 case END_TRACE_LEVEL:
212 if (ortp_log_level_enabled(level)){
213 int len=strlen(chfr);
214 char *chfrdup=ortp_strdup(chfr);
215 /*need to remove endline*/
217 if (chfrdup[len-1]=='\n')
219 if (chfrdup[len-2]=='\r')
222 ortp_logv(ortp_level,chfrdup,ap);
229 static bool_t firsttime=TRUE;
232 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
241 void sal_uninit(Sal* sal){
246 void sal_set_user_pointer(Sal *sal, void *user_data){
250 void *sal_get_user_pointer(const Sal *sal){
254 static void unimplemented_stub(){
255 ms_warning("Unimplemented SAL callback");
258 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
259 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
260 if (ctx->callbacks.call_received==NULL)
261 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
262 if (ctx->callbacks.call_ringing==NULL)
263 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
264 if (ctx->callbacks.call_accepted==NULL)
265 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
266 if (ctx->callbacks.call_failure==NULL)
267 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
268 if (ctx->callbacks.call_terminated==NULL)
269 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
270 if (ctx->callbacks.call_updated==NULL)
271 ctx->callbacks.call_updated=(SalOnCallUpdated)unimplemented_stub;
272 if (ctx->callbacks.auth_requested==NULL)
273 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
274 if (ctx->callbacks.auth_success==NULL)
275 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
276 if (ctx->callbacks.register_success==NULL)
277 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
278 if (ctx->callbacks.register_failure==NULL)
279 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
280 if (ctx->callbacks.dtmf_received==NULL)
281 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
282 if (ctx->callbacks.notify==NULL)
283 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
284 if (ctx->callbacks.notify_presence==NULL)
285 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
286 if (ctx->callbacks.subscribe_received==NULL)
287 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
288 if (ctx->callbacks.text_received==NULL)
289 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
290 if (ctx->callbacks.internal_message==NULL)
291 ctx->callbacks.internal_message=(SalOnInternalMsg)unimplemented_stub;
292 if (ctx->callbacks.ping_reply==NULL)
293 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
297 static ortp_socket_t create_socket(int pf, int proto, const char *addr, int local_port){
298 struct addrinfo hints;
299 struct addrinfo *res=NULL;
305 sock=socket(pf,(proto==IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM,0);
307 ms_error("Fail to create socket");
310 snprintf(tmp,sizeof(tmp)-1,"%i",local_port);
311 memset (&hints,0,sizeof(hints));
312 hints.ai_family=(pf==PF_INET) ? AF_INET : AF_INET6;
313 hints.ai_socktype=(proto==IPPROTO_UDP) ? SOCK_DGRAM : SOCK_STREAM;
315 if ((err=getaddrinfo(addr,
318 ms_error("create_socket: getaddrinfo() failed: %s",gai_strerror(err));
322 if (bind(sock,(struct sockaddr*)res->ai_addr,res->ai_addrlen)<0){
323 ms_error("Bind socket to localhost:%i failed: %s",local_port,getSocketError());
330 if (setsockopt (sock, SOL_SOCKET, SO_REUSEADDR,
331 (SOCKET_OPTION_VALUE)&optval, sizeof (optval))<0){
332 ms_warning("Fail to set SO_REUSEADDR");
334 /*set_non_blocking_socket(sock);*/
339 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
342 int proto=IPPROTO_UDP;
349 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
350 version of eXosip, which is not the case*/
351 /*see if it looks like an IPv6 address*/
352 ipv6=strchr(addr,':')!=NULL;
353 eXosip_enable_ipv6(ipv6);
355 if (tr!=SalTransportDatagram || is_secure){
356 ms_fatal("SIP over TCP or TLS or DTLS is not supported yet.");
359 ctx->sock=create_socket(ipv6 ? PF_INET6 : PF_INET, proto, addr, port);
360 if (ctx->sock==-1) return -1;
361 ms_message("Exosip is given socket %i",ctx->sock);
362 eXosip_set_socket(proto,ctx->sock,port);
364 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, 0);
370 ortp_socket_t sal_get_socket(Sal *ctx){
374 void sal_set_user_agent(Sal *ctx, const char *user_agent){
375 eXosip_set_user_agent(user_agent);
378 void sal_use_session_timers(Sal *ctx, int expires){
379 ctx->session_expires=expires;
382 MSList *sal_get_pending_auths(Sal *sal){
383 return ms_list_copy(sal->pending_auths);
386 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval){
387 osip_via_t *via=NULL;
388 osip_generic_param_t *param=NULL;
391 osip_message_get_via(msg,0,&via);
393 osip_via_param_get_byname(via,"rport",¶m);
396 if (rport && rport[0]!='\0') *rportval=atoi(rport);
400 osip_via_param_get_byname(via,"received",¶m);
401 if (param) *received=param->gvalue;
406 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
410 sdp_message_to_str(msg,&sdp);
412 snprintf(clen,sizeof(clen),"%i",sdplen);
413 osip_message_set_body(sip,sdp,sdplen);
414 osip_message_set_content_type(sip,"application/sdp");
415 osip_message_set_content_length(sip,clen);
419 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
420 sdp_message_t *msg=media_description_to_sdp(desc);
422 ms_error("Fail to print sdp message !");
426 sdp_message_free(msg);
429 static void sdp_process(SalOp *h){
430 ms_message("Doing SDP offer/answer process");
432 sal_media_description_unref(h->result);
434 h->result=sal_media_description_new();
435 if (h->sdp_offering){
436 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
439 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result);
440 h->sdp_answer=media_description_to_sdp(h->result);
441 strcpy(h->result->addr,h->base.remote_media->addr);
442 h->result->bandwidth=h->base.remote_media->bandwidth;
443 for(i=0;i<h->result->nstreams;++i){
444 if (h->result->streams[i].port>0){
445 strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr);
446 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
447 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
448 h->result->streams[i].port=h->base.remote_media->streams[i].port;
455 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
457 sal_media_description_ref(desc);
458 if (h->base.local_media)
459 sal_media_description_unref(h->base.local_media);
460 h->base.local_media=desc;
464 int sal_call(SalOp *h, const char *from, const char *to){
466 osip_message_t *invite=NULL;
467 sal_op_set_from(h,from);
469 sal_exosip_fix_route(h);
470 err=eXosip_call_build_initial_invite(&invite,to,from,sal_op_get_route(h),"Phone call");
472 ms_error("Could not create call.");
475 if (h->base.contact){
476 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
477 osip_message_set_contact(invite,h->base.contact);
479 if (h->base.root->session_expires!=0){
480 osip_message_set_header(invite, "Session-expires", "200");
481 osip_message_set_supported(invite, "timer");
483 if (h->base.local_media){
484 h->sdp_offering=TRUE;
485 set_sdp_from_desc(invite,h->base.local_media);
486 }else h->sdp_offering=FALSE;
488 err=eXosip_call_send_initial_invite(invite);
492 ms_error("Fail to send invite !");
495 eXosip_call_set_reference(h->cid,h);
500 int sal_call_notify_ringing(SalOp *h){
502 eXosip_call_send_answer(h->tid,180,NULL);
507 int sal_call_accept(SalOp * h){
509 const char *contact=sal_op_get_contact(h);
511 int err=eXosip_call_build_answer(h->tid,200,&msg);
512 if (err<0 || msg==NULL){
513 ms_error("Fail to build answer for call: err=%i",err);
516 if (h->base.root->session_expires!=0){
517 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
521 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
522 osip_message_set_contact(msg,contact);
525 if (h->base.local_media){
526 /*this is the case where we received an invite without SDP*/
527 if (h->sdp_offering) {
528 set_sdp_from_desc(msg,h->base.local_media);
531 set_sdp(msg,h->sdp_answer);
534 ms_error("You are accepting a call but not defined any media capabilities !");
536 eXosip_call_send_answer(h->tid,200,msg);
540 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
541 if (reason==SalReasonBusy){
543 eXosip_call_send_answer(h->tid,486,NULL);
546 else if (reason==SalReasonTemporarilyUnavailable){
548 eXosip_call_send_answer(h->tid,480,NULL);
550 }else if (reason==SalReasonDoNotDisturb){
552 eXosip_call_send_answer(h->tid,600,NULL);
554 }else if (reason==SalReasonMedia){
556 eXosip_call_send_answer(h->tid,415,NULL);
558 }else if (redirect!=NULL && reason==SalReasonRedirect){
561 if (strstr(redirect,"sip:")!=0) code=302;
564 eXosip_call_build_answer(h->tid,code,&msg);
565 osip_message_set_contact(msg,redirect);
566 eXosip_call_send_answer(h->tid,code,msg);
568 }else sal_call_terminate(h);
572 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
573 if (h->base.local_media && h->base.remote_media && !h->result){
579 int sal_ping(SalOp *op, const char *from, const char *to){
580 osip_message_t *options=NULL;
582 sal_op_set_from(op,from);
583 sal_op_set_to(op,to);
584 eXosip_options_build_request (&options, sal_op_get_to(op),
585 sal_op_get_from(op),sal_op_get_route(op));
587 if (op->base.root->session_expires!=0){
588 osip_message_set_header(options, "Session-expires", "200");
589 osip_message_set_supported(options, "timer");
591 sal_add_other(sal_op_get_sal(op),op,options);
592 return eXosip_options_send_request(options);
597 int sal_refer_accept(SalOp *op){
598 osip_message_t *msg=NULL;
601 err = eXosip_call_build_notify(op->did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
604 osip_message_set_header(msg,(const char *)"event","refer");
605 osip_message_set_content_type(msg,"message/sipfrag");
606 osip_message_set_body(msg,"SIP/2.0 100 Trying",sizeof("SIP/2.0 100 Trying"));
607 eXosip_call_send_request(op->did,msg);
611 ms_error("could not get a notify built\n");
617 int sal_refer(SalOp *h, const char *refer_to){
618 osip_message_t *msg=NULL;
621 eXosip_call_build_refer(h->did,refer_to, &msg);
622 if (msg) err=eXosip_call_send_request(h->did, msg);
628 int sal_call_send_dtmf(SalOp *h, char dtmf){
629 osip_message_t *msg=NULL;
634 eXosip_call_build_info(h->did,&msg);
636 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
637 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
638 osip_message_set_content_type(msg,"application/dtmf-relay");
639 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
640 osip_message_set_content_length(msg,clen);
641 eXosip_call_send_request(h->did,msg);
647 int sal_call_terminate(SalOp *h){
649 eXosip_call_terminate(h->cid,h->did);
650 eXosip_call_set_reference(h->cid,NULL);
655 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
656 if (h->pending_auth){
658 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
659 else userid=info->userid;
660 ms_message("Authentication info for %s %s added to eXosip", info->username,info->realm);
661 eXosip_add_authentication_info (info->username,userid,
662 info->password, NULL,info->realm);
664 eXosip_default_action(h->pending_auth);
666 ms_message("eXosip_default_action() done");
667 eXosip_clear_authentication_info();
668 eXosip_event_free(h->pending_auth);
669 sal_remove_pending_auth(sal_op_get_sal(h),h);
670 h->pending_auth=NULL;
674 static void set_network_origin(SalOp *op, osip_message_t *req){
675 const char *received=NULL;
678 if (extract_received_rport(req,&received,&rport)!=0){
679 osip_via_t *via=NULL;
681 osip_message_get_via(req,0,&via);
682 received=osip_via_get_host(via);
683 tmp=osip_via_get_port(via);
684 if (tmp) rport=atoi(tmp);
686 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
687 __sal_op_set_network_origin(op,origin);
690 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
692 #ifdef HAVE_EXOSIP_GET_REF
693 return (SalOp*)eXosip_call_get_ref(ev->cid);
695 return (SalOp*)eXosip_call_get_reference(ev->cid);
699 return sal_find_register(sal,ev->rid);
701 if (ev->response) return sal_find_other(sal,ev->response);
705 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
706 SalOp *op=sal_op_new(sal);
707 osip_from_t *from,*to;
708 osip_call_info_t *call_info;
710 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
712 set_network_origin(op,ev->request);
715 op->sdp_offering=FALSE;
716 op->base.remote_media=sal_media_description_new();
717 sdp_to_media_description(sdp,op->base.remote_media);
718 sdp_message_free(sdp);
719 }else op->sdp_offering=TRUE;
721 from=osip_message_get_from(ev->request);
722 to=osip_message_get_to(ev->request);
723 osip_from_to_str(from,&tmp);
724 sal_op_set_from(op,tmp);
726 osip_from_to_str(to,&tmp);
727 sal_op_set_to(op,tmp);
730 osip_message_get_call_info(ev->request,0,&call_info);
733 osip_call_info_to_str(call_info,&tmp);
734 if( strstr(tmp,"answer-after=") != NULL)
736 op->auto_answer_asked=TRUE;
737 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
746 eXosip_call_set_reference(op->cid,op);
747 sal->callbacks.call_received(op);
750 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
751 SalOp *op=find_op(sal,ev);
753 osip_message_t *msg=NULL;
756 ms_warning("Reinvite for non-existing operation !");
761 sdp=eXosip_get_sdp_info(ev->request);
762 if (op->base.remote_media){
763 sal_media_description_unref(op->base.remote_media);
764 op->base.remote_media=NULL;
767 eXosip_call_build_answer(ev->tid,200,&msg);
769 if (msg==NULL) return;
770 if (op->base.root->session_expires!=0){
771 if (op->supports_session_timers) osip_message_set_supported(msg, "timer");
773 if (op->base.contact){
774 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
775 osip_message_set_contact(msg,op->base.contact);
778 op->sdp_offering=FALSE;
779 op->base.remote_media=sal_media_description_new();
780 sdp_to_media_description(sdp,op->base.remote_media);
781 sdp_message_free(sdp);
783 set_sdp(msg,op->sdp_answer);
785 op->sdp_offering=TRUE;
786 set_sdp_from_desc(msg,op->base.local_media);
789 eXosip_call_send_answer(ev->tid,200,msg);
793 static void handle_ack(Sal *sal, eXosip_event_t *ev){
794 SalOp *op=find_op(sal,ev);
798 ms_warning("ack for non-existing call !");
801 sdp=eXosip_get_sdp_info(ev->ack);
803 op->base.remote_media=sal_media_description_new();
804 sdp_to_media_description(sdp,op->base.remote_media);
806 sdp_message_free(sdp);
809 sal->callbacks.call_updated(op);
812 sal->callbacks.call_ack(op);
816 static void update_contact_from_response(SalOp *op, osip_message_t *response){
817 const char *received;
819 if (extract_received_rport(response,&received,&rport)==0){
820 const char *contact=sal_op_get_contact(op);
822 /*no contact given yet, use from instead*/
823 contact=sal_op_get_from(op);
826 SalAddress *addr=sal_address_new(contact);
828 sal_address_set_domain(addr,received);
829 sal_address_set_port_int(addr,rport);
830 tmp=sal_address_as_string(addr);
831 ms_message("Contact address updated to %s for this dialog",tmp);
832 sal_op_set_contact(op,tmp);
838 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
839 SalOp *op=find_op(sal,ev);
842 ms_warning("This call has been canceled.");
844 eXosip_call_terminate(ev->cid,ev->did);
851 /* update contact if received and rport are set by the server
852 note: will only be used by remote for next INVITE, if any...*/
853 update_contact_from_response(op,ev->response);
857 static void call_ringing(Sal *sal, eXosip_event_t *ev){
860 if (call_proceeding(sal, ev)==-1) return;
861 op=(SalOp*)ev->external_reference;
862 sdp=eXosip_get_sdp_info(ev->response);
864 op->base.remote_media=sal_media_description_new();
865 sdp_to_media_description(sdp,op->base.remote_media);
866 sdp_message_free(sdp);
867 if (op->base.local_media) sdp_process(op);
869 sal->callbacks.call_ringing(op);
872 static void call_accepted(Sal *sal, eXosip_event_t *ev){
874 osip_message_t *msg=NULL;
875 SalOp *op=find_op(sal,ev);
879 ms_error("A closed call is accepted ?");
882 sdp=eXosip_get_sdp_info(ev->response);
884 op->base.remote_media=sal_media_description_new();
885 sdp_to_media_description(sdp,op->base.remote_media);
886 sdp_message_free(sdp);
887 if (op->base.local_media) sdp_process(op);
889 eXosip_call_build_ack(ev->did,&msg);
890 contact=sal_op_get_contact(op);
892 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
893 osip_message_set_contact(msg,contact);
896 set_sdp(msg,op->sdp_answer);
897 eXosip_call_send_ack(ev->did,msg);
898 sal->callbacks.call_accepted(op);
901 static void call_terminated(Sal *sal, eXosip_event_t *ev){
903 SalOp *op=find_op(sal,ev);
905 ms_warning("Call terminated for already closed call ?");
908 osip_from_to_str(ev->request->from,&from);
909 eXosip_call_set_reference(ev->cid,NULL);
911 sal->callbacks.call_terminated(op,from);
915 static void call_released(Sal *sal, eXosip_event_t *ev){
916 SalOp *op=find_op(sal,ev);
922 sal->callbacks.call_failure(op,SalErrorNoResponse,SalReasonUnknown,NULL);
925 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
926 const char *prx_realm=NULL,*www_realm=NULL;
927 osip_proxy_authenticate_t *prx_auth;
928 osip_www_authenticate_t *www_auth;
930 *username=osip_uri_get_username(resp->from->url);
931 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
932 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
934 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
936 www_realm=osip_www_authenticate_get_realm(www_auth);
940 }else if (www_realm){
948 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
949 osip_authorization_t *auth=NULL;
950 osip_proxy_authorization_t *prx_auth=NULL;
952 *username=osip_uri_get_username(msg->from->url);
953 osip_message_get_authorization(msg, 0, &auth);
955 *realm=osip_authorization_get_realm(auth);
958 osip_message_get_proxy_authorization(msg,0,&prx_auth);
960 *realm=osip_proxy_authorization_get_realm(prx_auth);
966 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
967 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
968 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
972 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
973 if (op->pending_auth){
974 return get_auth_data(op->pending_auth,realm,username);
979 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
981 const char *username,*realm;
984 ms_warning("No operation associated with this authentication !");
987 if (get_auth_data(ev,&realm,&username)==0){
988 if (op->pending_auth!=NULL)
989 eXosip_event_free(op->pending_auth);
991 sal_add_pending_auth (sal,op);
992 sal->callbacks.auth_requested(op,realm,username);
998 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1000 const char *username,*realm;
1003 ms_warning("No operation associated with this authentication_ok!");
1006 if (get_auth_data(ev,&realm,&username)==0){
1007 sal->callbacks.auth_success(op,realm,username);
1011 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1014 const char *reason=NULL;
1015 SalError error=SalErrorUnknown;
1016 SalReason sr=SalReasonUnknown;
1018 op=(SalOp*)find_op(sal,ev);
1021 ms_warning("Call failure reported for a closed call, ignored.");
1026 code=osip_message_get_status_code(ev->response);
1027 reason=osip_message_get_reason_phrase(ev->response);
1033 return process_authentication(sal,ev);
1036 error=SalErrorUnknown;
1039 error=SalErrorFailure;
1040 sr=SalReasonNotFound;
1043 error=SalErrorFailure;
1047 eXosip_default_action(ev);
1051 error=SalErrorFailure;
1052 sr=SalReasonTemporarilyUnavailable;
1054 error=SalErrorFailure;
1060 error=SalErrorFailure;
1061 sr=SalReasonDoNotDisturb;
1064 error=SalErrorFailure;
1065 sr=SalReasonDeclined;
1069 error=SalErrorFailure;
1070 sr=SalReasonUnknown;
1071 }else error=SalErrorNoResponse;
1073 sal->callbacks.call_failure(op,error,sr,reason);
1078 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1079 SalOp *op=find_op(sal,ev);
1080 osip_body_t *body=NULL;
1083 ms_warning("media control xml received without operation context!");
1087 osip_message_get_body(ev->request,0,&body);
1088 if (body && body->body!=NULL &&
1089 strstr(body->body,"picture_fast_update")){
1090 osip_message_t *ans=NULL;
1091 ms_message("Receiving VFU request !");
1092 if (sal->callbacks.vfu_request){
1093 sal->callbacks.vfu_request(op);
1094 eXosip_call_build_answer(ev->tid,200,&ans);
1096 eXosip_call_send_answer(ev->tid,200,ans);
1101 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1102 SalOp *op=find_op(sal,ev);
1103 osip_body_t *body=NULL;
1106 ms_warning("media dtmf relay received without operation context!");
1110 osip_message_get_body(ev->request,0,&body);
1111 if (body && body->body!=NULL){
1112 osip_message_t *ans=NULL;
1113 const char *name=strstr(body->body,"Signal");
1114 if (name==NULL) name=strstr(body->body,"signal");
1116 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1119 name+=strlen("signal");
1120 if (sscanf(name," = %1s",tmp)==1){
1121 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1122 if (sal->callbacks.dtmf_received != NULL)
1123 sal->callbacks.dtmf_received(op, tmp[0]);
1126 eXosip_call_build_answer(ev->tid,200,&ans);
1128 eXosip_call_send_answer(ev->tid,200,ans);
1132 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1133 osip_message_t *ans=NULL;
1135 if (MSG_IS_INFO(ev->request)){
1136 osip_content_type_t *ct;
1137 ct=osip_message_get_content_type(ev->request);
1138 if (ct && ct->subtype){
1139 if (strcmp(ct->subtype,"media_control+xml")==0)
1140 process_media_control_xml(sal,ev);
1141 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1142 process_dtmf_relay(sal,ev);
1144 ms_message("Unhandled SIP INFO.");
1145 /*send an "Not implemented" answer*/
1147 eXosip_call_build_answer(ev->tid,501,&ans);
1149 eXosip_call_send_answer(ev->tid,501,ans);
1153 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1155 eXosip_call_build_answer(ev->tid,200,&ans);
1157 eXosip_call_send_answer(ev->tid,200,ans);
1161 if(MSG_IS_MESSAGE(ev->request)){
1162 /* SIP messages could be received into call */
1163 text_received(sal, ev);
1165 eXosip_call_build_answer(ev->tid,200,&ans);
1167 eXosip_call_send_answer(ev->tid,200,ans);
1170 if(MSG_IS_REFER(ev->request)){
1171 osip_header_t *h=NULL;
1172 SalOp *op=find_op(sal,ev);
1174 ms_message("Receiving REFER request !");
1175 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1177 eXosip_call_build_answer(ev->tid,202,&ans);
1179 eXosip_call_send_answer(ev->tid,202,ans);
1182 sal->callbacks.refer_received(sal,op,h->hvalue);
1186 ms_warning("cannot do anything with the refer without destination\n");
1189 if(MSG_IS_NOTIFY(ev->request)){
1190 osip_header_t *h=NULL;
1192 SalOp *op=find_op(sal,ev);
1194 ms_message("Receiving NOTIFY request !");
1195 osip_from_to_str(ev->request->from,&from);
1196 osip_message_header_get_byname(ev->request,"Event",0,&h);
1198 sal->callbacks.notify(op,from,h->hvalue);
1199 /*answer that we received the notify*/
1201 eXosip_call_build_answer(ev->tid,200,&ans);
1203 eXosip_call_send_answer(ev->tid,200,ans);
1207 }else ms_warning("call_message_new: No request ?");
1210 static void inc_update(Sal *sal, eXosip_event_t *ev){
1211 osip_message_t *msg=NULL;
1212 ms_message("Processing incoming UPDATE");
1214 eXosip_message_build_answer(ev->tid,200,&msg);
1216 eXosip_message_send_answer(ev->tid,200,msg);
1220 static bool_t comes_from_local_if(osip_message_t *msg){
1221 osip_via_t *via=NULL;
1222 osip_message_get_via(msg,0,&via);
1225 host=osip_via_get_host(via);
1226 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1227 osip_generic_param_t *param=NULL;
1228 osip_via_param_get_byname(via,"received",¶m);
1229 if (param==NULL) return TRUE;
1230 if (param->gvalue &&
1231 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1239 static void text_received(Sal *sal, eXosip_event_t *ev){
1240 osip_body_t *body=NULL;
1241 char *from=NULL,*msg;
1243 osip_message_get_body(ev->request,0,&body);
1245 ms_error("Could not get text message from SIP body");
1249 osip_from_to_str(ev->request->from,&from);
1250 sal->callbacks.text_received(sal,from,msg);
1254 static void other_request(Sal *sal, eXosip_event_t *ev){
1255 ms_message("in other_request");
1256 if (ev->request==NULL) return;
1257 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1258 text_received(sal,ev);
1259 eXosip_message_send_answer(ev->tid,200,NULL);
1260 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1261 osip_message_t *options=NULL;
1262 eXosip_options_build_answer(ev->tid,200,&options);
1263 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1264 osip_message_set_accept(options,"application/sdp");
1265 eXosip_options_send_answer(ev->tid,200,options);
1266 }else if (strcmp(ev->request->sip_method,"WAKEUP")==0
1267 && comes_from_local_if(ev->request)) {
1268 eXosip_message_send_answer(ev->tid,200,NULL);
1269 ms_message("Receiving WAKEUP request !");
1270 sal->callbacks.internal_message(sal,"WAKEUP");
1271 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1272 ms_message("Receiving REFER request !");
1273 if (comes_from_local_if(ev->request)) {
1274 osip_header_t *h=NULL;
1275 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1276 eXosip_message_send_answer(ev->tid,200,NULL);
1278 sal->callbacks.refer_received(sal,NULL,h->hvalue);
1280 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1281 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1286 osip_message_to_str(ev->request,&tmp,&msglen);
1288 ms_message("Unsupported request received:\n%s",tmp);
1291 /*answer with a 501 Not implemented*/
1292 eXosip_message_send_answer(ev->tid,501,NULL);
1296 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1297 osip_via_t *via=NULL;
1298 osip_message_get_via(msg,0,&via);
1300 osip_free(via->port);
1301 via->port=osip_strdup(port);
1302 osip_free(via->host);
1303 via->host=osip_strdup(ip);
1307 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1308 osip_message_t *msg;
1309 const char *received;
1311 osip_contact_t *ctt=NULL;
1316 if (extract_received_rport(last_answer,&received,&rport)==-1) return FALSE;
1317 osip_message_get_contact(orig_request,0,&ctt);
1318 if (strcmp(ctt->url->host,received)==0){
1319 /*ip address matches, check ports*/
1320 const char *contact_port=ctt->url->port;
1321 if (contact_port==NULL || contact_port[0]=='\0')
1322 contact_port="5060";
1323 if (atoi(contact_port)==rport){
1324 ms_message("Register has up to date contact, doing nothing.");
1326 }else ms_message("ports do not match, need to update the register (%s <> %i)", contact_port,rport);
1330 eXosip_register_build_register(op->rid,op->expires,&msg);
1333 ms_warning("Fail to create a contact updated register.");
1336 osip_message_get_contact(msg,0,&ctt);
1337 if (ctt->url->host!=NULL){
1338 osip_free(ctt->url->host);
1340 ctt->url->host=osip_strdup(received);
1341 if (ctt->url->port!=NULL){
1342 osip_free(ctt->url->port);
1344 snprintf(port,sizeof(port),"%i",rport);
1345 ctt->url->port=osip_strdup(port);
1346 if (op->masquerade_via) masquerade_via(msg,received,port);
1347 eXosip_register_send_register(op->rid,msg);
1349 osip_contact_to_str(ctt,&tmp);
1350 addr=sal_address_new(tmp);
1352 sal_address_clean(addr);
1353 tmp=sal_address_as_string(addr);
1354 sal_op_set_contact(op,tmp);
1355 sal_address_destroy(addr);
1356 ms_message("Resending new register with updated contact %s",tmp);
1361 static void registration_success(Sal *sal, eXosip_event_t *ev){
1362 SalOp *op=sal_find_register(sal,ev->rid);
1363 osip_header_t *h=NULL;
1366 ms_error("Receiving register response for unknown operation");
1369 osip_message_get_expires(ev->request,0,&h);
1370 if (h!=NULL && atoi(h->hvalue)!=0){
1372 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1373 sal->callbacks.register_success(op,registered);
1375 }else registered=FALSE;
1378 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1380 const char *reason=NULL;
1381 SalOp *op=sal_find_register(sal,ev->rid);
1382 SalReason sr=SalReasonUnknown;
1383 SalError se=SalErrorUnknown;
1386 ms_error("Receiving register failure for unknown operation");
1390 status_code=osip_message_get_status_code(ev->response);
1391 reason=osip_message_get_reason_phrase(ev->response);
1393 switch(status_code){
1396 return process_authentication(sal,ev);
1398 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1399 in vias, such as ekiga.net
1400 On the opposite, freephonie.net bugs when via are masqueraded.
1402 op->masquerade_via=TRUE;
1404 /* if contact is up to date, process the failure, otherwise resend a new register with
1405 updated contact first, just in case the faillure is due to incorrect contact */
1406 if (register_again_with_updated_contact(op,ev->request,ev->response))
1407 return TRUE; /*we are retrying with an updated contact*/
1408 if (status_code==403){
1410 sr=SalReasonForbidden;
1411 }else if (status_code==0){
1412 se=SalErrorNoResponse;
1414 sal->callbacks.register_failure(op,se,sr,reason);
1419 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1420 SalOp *op=find_op(sal,ev);
1423 ms_warning("other_request_reply(): Receiving response to unknown request.");
1427 update_contact_from_response(op,ev->response);
1428 sal->callbacks.ping_reply(op);
1432 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
1433 ms_message("linphone process event get a message %d\n",ev->type);
1435 case EXOSIP_CALL_ANSWERED:
1436 ms_message("CALL_ANSWERED\n");
1437 call_accepted(sal,ev);
1438 authentication_ok(sal,ev);
1440 case EXOSIP_CALL_CLOSED:
1441 case EXOSIP_CALL_CANCELLED:
1442 ms_message("CALL_CLOSED or CANCELLED\n");
1443 call_terminated(sal,ev);
1445 case EXOSIP_CALL_TIMEOUT:
1446 case EXOSIP_CALL_NOANSWER:
1447 ms_message("CALL_TIMEOUT or NOANSWER\n");
1448 return call_failure(sal,ev);
1450 case EXOSIP_CALL_REQUESTFAILURE:
1451 case EXOSIP_CALL_GLOBALFAILURE:
1452 case EXOSIP_CALL_SERVERFAILURE:
1453 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
1454 return call_failure(sal,ev);
1456 case EXOSIP_CALL_INVITE:
1457 ms_message("CALL_NEW\n");
1458 inc_new_call(sal,ev);
1460 case EXOSIP_CALL_REINVITE:
1461 handle_reinvite(sal,ev);
1463 case EXOSIP_CALL_ACK:
1464 ms_message("CALL_ACK");
1467 case EXOSIP_CALL_REDIRECTED:
1468 ms_message("CALL_REDIRECTED");
1469 eXosip_default_action(ev);
1471 case EXOSIP_CALL_PROCEEDING:
1472 ms_message("CALL_PROCEEDING");
1473 call_proceeding(sal,ev);
1475 case EXOSIP_CALL_RINGING:
1476 ms_message("CALL_RINGING");
1477 call_ringing(sal,ev);
1479 case EXOSIP_CALL_MESSAGE_NEW:
1480 ms_message("EXOSIP_CALL_MESSAGE_NEW");
1481 call_message_new(sal,ev);
1483 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
1484 if (ev->did<0 && ev->response &&
1485 (ev->response->status_code==407 || ev->response->status_code==401)){
1486 return process_authentication(sal,ev);
1489 case EXOSIP_IN_SUBSCRIPTION_NEW:
1490 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
1491 sal_exosip_subscription_recv(sal,ev);
1493 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
1494 ms_message("CALL_SUBSCRIPTION_NEW ");
1495 sal_exosip_in_subscription_closed(sal,ev);
1497 case EXOSIP_SUBSCRIPTION_UPDATE:
1498 ms_message("CALL_SUBSCRIPTION_UPDATE");
1500 case EXOSIP_SUBSCRIPTION_NOTIFY:
1501 ms_message("CALL_SUBSCRIPTION_NOTIFY");
1502 sal_exosip_notify_recv(sal,ev);
1504 case EXOSIP_SUBSCRIPTION_ANSWERED:
1505 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
1506 sal_exosip_subscription_answered(sal,ev);
1508 case EXOSIP_SUBSCRIPTION_CLOSED:
1509 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
1510 sal_exosip_subscription_closed(sal,ev);
1512 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
1513 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
1514 return process_authentication(sal,ev);
1516 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
1517 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
1518 sal_exosip_subscription_closed(sal,ev);
1520 case EXOSIP_CALL_RELEASED:
1521 ms_message("CALL_RELEASED\n");
1522 call_released(sal, ev);
1524 case EXOSIP_REGISTRATION_FAILURE:
1525 ms_message("REGISTRATION_FAILURE\n");
1526 return registration_failure(sal,ev);
1528 case EXOSIP_REGISTRATION_SUCCESS:
1529 authentication_ok(sal,ev);
1530 registration_success(sal,ev);
1532 case EXOSIP_MESSAGE_NEW:
1533 other_request(sal,ev);
1535 case EXOSIP_MESSAGE_PROCEEDING:
1536 case EXOSIP_MESSAGE_ANSWERED:
1537 case EXOSIP_MESSAGE_REDIRECTED:
1538 case EXOSIP_MESSAGE_SERVERFAILURE:
1539 case EXOSIP_MESSAGE_GLOBALFAILURE:
1540 other_request_reply(sal,ev);
1542 case EXOSIP_MESSAGE_REQUESTFAILURE:
1543 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
1544 return process_authentication(sal,ev);
1548 ms_message("Unhandled exosip event ! %i",ev->type);
1554 int sal_iterate(Sal *sal){
1556 while((ev=eXosip_event_wait(0,0))!=NULL){
1557 if (process_event(sal,ev))
1558 eXosip_event_free(ev);
1561 eXosip_automatic_refresh();
1566 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
1567 osip_message_t *msg;
1568 sal_op_set_route(h,proxy);
1571 h->rid=eXosip_register_build_initial_register(from,proxy,sal_op_get_contact(h),expires,&msg);
1572 sal_add_register(h->base.root,h);
1575 eXosip_register_build_register(h->rid,expires,&msg);
1577 eXosip_register_send_register(h->rid,msg);
1583 int sal_unregister(SalOp *h){
1584 osip_message_t *msg=NULL;
1586 eXosip_register_build_register(h->rid,0,&msg);
1587 if (msg) eXosip_register_send_register(h->rid,msg);
1588 else ms_warning("Could not build unREGISTER !");
1595 SalAddress * sal_address_new(const char *uri){
1597 osip_from_init(&from);
1598 if (osip_from_parse(from,uri)!=0){
1599 osip_from_free(from);
1602 return (SalAddress*)from;
1605 SalAddress * sal_address_clone(const SalAddress *addr){
1606 osip_from_t *ret=NULL;
1607 osip_from_clone((osip_from_t*)addr,&ret);
1608 return (SalAddress*)ret;
1611 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
1613 const char *sal_address_get_scheme(const SalAddress *addr){
1614 const osip_from_t *u=(const osip_from_t*)addr;
1615 return null_if_empty(u->url->scheme);
1618 const char *sal_address_get_display_name(const SalAddress* addr){
1619 const osip_from_t *u=(const osip_from_t*)addr;
1620 return null_if_empty(u->displayname);
1623 const char *sal_address_get_username(const SalAddress *addr){
1624 const osip_from_t *u=(const osip_from_t*)addr;
1625 return null_if_empty(u->url->username);
1628 const char *sal_address_get_domain(const SalAddress *addr){
1629 const osip_from_t *u=(const osip_from_t*)addr;
1630 return null_if_empty(u->url->host);
1633 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
1634 osip_from_t *u=(osip_from_t*)addr;
1635 if (u->displayname!=NULL){
1636 osip_free(u->displayname);
1637 u->displayname=NULL;
1639 if (display_name!=NULL)
1640 u->displayname=osip_strdup(display_name);
1643 void sal_address_set_username(SalAddress *addr, const char *username){
1644 osip_from_t *uri=(osip_from_t*)addr;
1645 if (uri->url->username!=NULL){
1646 osip_free(uri->url->username);
1647 uri->url->username=NULL;
1650 uri->url->username=osip_strdup(username);
1653 void sal_address_set_domain(SalAddress *addr, const char *host){
1654 osip_from_t *uri=(osip_from_t*)addr;
1655 if (uri->url->host!=NULL){
1656 osip_free(uri->url->host);
1657 uri->url->host=NULL;
1660 uri->url->host=osip_strdup(host);
1663 void sal_address_set_port(SalAddress *addr, const char *port){
1664 osip_from_t *uri=(osip_from_t*)addr;
1665 if (uri->url->port!=NULL){
1666 osip_free(uri->url->port);
1667 uri->url->port=NULL;
1670 uri->url->port=osip_strdup(port);
1673 void sal_address_set_port_int(SalAddress *uri, int port){
1676 /*this is the default, special case to leave the port field blank*/
1677 sal_address_set_port(uri,NULL);
1680 snprintf(tmp,sizeof(tmp),"%i",port);
1681 sal_address_set_port(uri,tmp);
1684 void sal_address_clean(SalAddress *addr){
1685 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
1686 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
1689 char *sal_address_as_string(const SalAddress *u){
1691 osip_from_to_str((osip_from_t*)u,&tmp);
1697 char *sal_address_as_string_uri_only(const SalAddress *u){
1698 char *tmp=NULL,*ret;
1699 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
1705 void sal_address_destroy(SalAddress *u){
1706 osip_from_free((osip_from_t*)u);