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.
20 #include "sal_eXosip2.h"
22 #include "offeranswer.h"
24 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
25 if (eXosip_guess_localip(address_family,ip,iplen)<0){
26 /*default to something */
27 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
28 ms_error("Could not find default routable ip address !");
32 static SalOp * sal_find_register(Sal *sal, int rid){
35 for(elem=sal->registers;elem!=NULL;elem=elem->next){
36 op=(SalOp*)elem->data;
37 if (op->rid==rid) return op;
42 static void sal_add_register(Sal *sal, SalOp *op){
43 sal->registers=ms_list_append(sal->registers,op);
46 static void sal_remove_register(Sal *sal, int rid){
49 for(elem=sal->registers;elem!=NULL;elem=elem->next){
50 op=(SalOp*)elem->data;
52 sal->registers=ms_list_remove_link(sal->registers,elem);
58 SalOp * sal_op_new(Sal *sal){
59 SalOp *op=ms_new(SalOp,1);
60 __sal_op_init(op,sal);
61 op->cid=op->did=op->tid=op->rid=op->nid=op->sid-1;
62 op->supports_session_timers=FALSE;
63 op->sdp_offering=TRUE;
64 op->pending_auth=NULL;
70 void sal_op_release(SalOp *op){
72 sdp_message_free(op->sdp_answer);
74 eXosip_event_free(op->pending_auth);
76 sal_remove_register(op->base.root,op->rid);
79 eXosip_call_set_reference(op->cid,NULL);
84 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
85 int ortp_level=ORTP_DEBUG;
91 ortp_level=ORTP_MESSAGE;
94 ortp_level=ORTP_WARNING;
98 ortp_level=ORTP_ERROR;
101 ortp_level=ORTP_FATAL;
103 case END_TRACE_LEVEL:
106 if (ortp_log_level_enabled(level)){
107 int len=strlen(chfr);
108 char *chfrdup=ortp_strdup(chfr);
109 /*need to remove endline*/
111 if (chfrdup[len-1]=='\n')
113 if (chfrdup[len-2]=='\r')
116 ortp_logv(ortp_level,chfrdup,ap);
123 static bool_t firsttime=TRUE;
125 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
129 return ms_new0(Sal,1);
132 void sal_uninit(Sal* sal){
137 static void unimplemented_stub(){
138 ms_warning("Unimplemented SAL callback");
141 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
142 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
143 if (ctx->callbacks.call_received==NULL)
144 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
145 if (ctx->callbacks.call_ringing==NULL)
146 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
147 if (ctx->callbacks.call_accepted==NULL)
148 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
149 if (ctx->callbacks.call_failure==NULL)
150 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
151 if (ctx->callbacks.call_terminated==NULL)
152 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
153 if (ctx->callbacks.call_updated==NULL)
154 ctx->callbacks.call_updated=(SalOnCallUpdated)unimplemented_stub;
155 if (ctx->callbacks.auth_requested==NULL)
156 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
157 if (ctx->callbacks.auth_success==NULL)
158 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
159 if (ctx->callbacks.register_success==NULL)
160 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
161 if (ctx->callbacks.register_failure==NULL)
162 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
163 if (ctx->callbacks.dtmf_received==NULL)
164 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
165 if (ctx->callbacks.presence_changed==NULL)
166 ctx->callbacks.presence_changed=(SalOnPresenceChanged)unimplemented_stub;
167 if (ctx->callbacks.subscribe_received==NULL)
168 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
169 if (ctx->callbacks.text_received==NULL)
170 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
171 if (ctx->callbacks.internal_message==NULL)
172 ctx->callbacks.internal_message=(SalOnInternalMsg)unimplemented_stub;
175 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
178 int proto=IPPROTO_UDP;
180 if (ctx->running) eXosip_quit();
183 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
184 version of eXosip, which is not the case*/
185 /*see if it looks like an IPv6 address*/
186 ipv6=strchr(addr,':')!=NULL;
187 eXosip_enable_ipv6(ipv6);
189 if (tr!=SalTransportDatagram || is_secure){
190 ms_fatal("SIP over TCP or TLS or DTLS is not supported yet.");
194 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, 0);
198 void sal_set_user_agent(Sal *ctx, const char *user_agent){
199 eXosip_set_user_agent(user_agent);
202 void sal_use_session_timers(Sal *ctx, int expires){
203 ctx->session_expires=expires;
207 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
211 sdp_message_to_str(msg,&sdp);
213 snprintf(clen,sizeof(clen),"%i",sdplen);
214 osip_message_set_body(sip,sdp,sdplen);
215 osip_message_set_content_type(sip,"application/sdp");
216 osip_message_set_content_length(sip,clen);
220 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
221 sdp_message_t *msg=media_description_to_sdp(desc);
223 ms_error("Fail to print sdp message !");
227 sdp_message_free(msg);
230 static void sdp_process(SalOp *h){
232 sal_media_description_unref(h->result);
234 h->result=sal_media_description_new();
235 if (h->sdp_offering){
236 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
239 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result);
240 h->sdp_answer=media_description_to_sdp(h->result);
241 strcpy(h->result->addr,h->base.remote_media->addr);
242 for(i=0;i<h->result->nstreams;++i){
243 if (h->result->streams[i].port>0){
244 strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr);
245 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
246 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
247 h->result->streams[i].port=h->base.remote_media->streams[i].port;
254 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
256 sal_media_description_ref(desc);
257 if (h->base.local_media)
258 sal_media_description_unref(h->base.local_media);
259 h->base.local_media=desc;
263 int sal_call(SalOp *h, const char *from, const char *to){
265 osip_message_t *invite=NULL;
266 sal_op_set_from(h,from);
268 err=eXosip_call_build_initial_invite(&invite,to,from,h->base.route,"Phone call");
270 ms_error("Could not create call.");
274 osip_message_set_contact(invite,h->base.contact);
275 if (h->base.root->session_expires!=0){
276 osip_message_set_header(invite, "Session-expires", "200");
277 osip_message_set_supported(invite, "timer");
279 if (h->base.local_media){
280 h->sdp_offering=TRUE;
281 set_sdp_from_desc(invite,h->base.local_media);
282 }else h->sdp_offering=FALSE;
284 err=eXosip_call_send_initial_invite(invite);
288 ms_error("Fail to send invite !");
291 eXosip_call_set_reference(h->cid,h);
296 int sal_call_accept(SalOp * h){
299 int err=eXosip_call_build_answer(h->tid,200,&msg);
300 if (err<0 || msg==NULL){
301 ms_error("Fail to build answer for call: err=%i",err);
304 if (h->base.root->session_expires!=0){
305 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
308 if (h->base.local_media){
309 /*this is the case where we received an invite without SDP*/
310 if (h->sdp_offering) {
311 set_sdp_from_desc(msg,h->base.local_media);
314 set_sdp(msg,h->sdp_answer);
317 ms_error("You are accepting a call but not defined any media capabilities !");
319 eXosip_call_send_answer(h->tid,200,msg);
323 const SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
324 if (h->base.local_media && h->base.remote_media && !h->result){
330 int sal_call_terminate(SalOp *h){
332 eXosip_call_terminate(h->cid,h->did);
334 eXosip_call_set_reference(h->cid,NULL);
338 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
339 if (h->pending_auth){
341 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
342 else userid=info->userid;
344 eXosip_add_authentication_info (info->username,userid,
345 info->password, NULL,info->realm);
346 eXosip_default_action(h->pending_auth);
348 eXosip_event_free(h->pending_auth);
349 h->pending_auth=NULL;
353 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
354 SalOp *op=sal_op_new(sal);
355 osip_from_t *from,*to;
357 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
359 op->base.remote_media=sal_media_description_new();
360 sdp_to_media_description(sdp,op->base.remote_media);
361 sdp_message_free(sdp);
362 }else op->sdp_offering=TRUE;
364 from=osip_message_get_from(ev->request);
365 to=osip_message_get_to(ev->request);
366 osip_from_to_str(from,&tmp);
367 sal_op_set_from(op,tmp);
369 osip_from_to_str(to,&tmp);
370 sal_op_set_to(op,tmp);
377 eXosip_call_set_reference(op->cid,op);
378 sal->callbacks.call_received(op);
381 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
382 SalOp *op=(SalOp*)ev->external_reference;
384 osip_message_t *msg=NULL;
387 ms_warning("Reinvite for non-existing operation !");
392 sdp=eXosip_get_sdp_info(ev->request);
393 if (op->base.remote_media){
394 sal_media_description_unref(op->base.remote_media);
395 op->base.remote_media=NULL;
398 eXosip_call_build_answer(ev->tid,200,&msg);
400 if (msg==NULL) return;
401 if (op->base.root->session_expires!=0){
402 if (op->supports_session_timers) osip_message_set_supported(msg, "timer");
405 op->sdp_offering=FALSE;
406 op->base.remote_media=sal_media_description_new();
407 sdp_to_media_description(sdp,op->base.remote_media);
408 sdp_message_free(sdp);
410 set_sdp(msg,op->sdp_answer);
412 op->sdp_offering=TRUE;
413 set_sdp_from_desc(msg,op->base.local_media);
416 eXosip_call_send_answer(ev->tid,200,msg);
420 static void handle_ack(Sal *sal, eXosip_event_t *ev){
421 SalOp *op=(SalOp*)ev->external_reference;
425 ms_warning("ack for non-existing call !");
428 sdp=eXosip_get_sdp_info(ev->ack);
430 op->base.remote_media=sal_media_description_new();
431 sdp_to_media_description(sdp,op->base.remote_media);
433 sdp_message_free(sdp);
436 sal->callbacks.call_updated(op);
439 sal->callbacks.call_ack(op);
443 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
444 SalOp *op=(SalOp*)ev->external_reference;
446 ms_warning("This call has been canceled.");
448 eXosip_call_terminate(ev->cid,ev->did);
457 static void call_ringing(Sal *sal, eXosip_event_t *ev){
460 if (call_proceeding(sal, ev)==-1) return;
461 op=(SalOp*)ev->external_reference;
462 sdp=eXosip_get_sdp_info(ev->response);
464 op->base.remote_media=sal_media_description_new();
465 sdp_to_media_description(sdp,op->base.remote_media);
466 sdp_message_free(sdp);
467 if (op->base.local_media) sdp_process(op);
469 sal->callbacks.call_ringing(op);
472 static void call_accepted(Sal *sal, eXosip_event_t *ev){
474 osip_message_t *msg=NULL;
476 op=(SalOp*)ev->external_reference;
478 ms_error("A closed call is accepted ?");
481 sdp=eXosip_get_sdp_info(ev->response);
483 op->base.remote_media=sal_media_description_new();
484 sdp_to_media_description(sdp,op->base.remote_media);
485 sdp_message_free(sdp);
486 if (op->base.local_media) sdp_process(op);
488 eXosip_call_build_ack(ev->did,&msg);
490 set_sdp(msg,op->sdp_answer);
491 eXosip_call_send_ack(ev->did,msg);
492 sal->callbacks.call_accepted(op);
495 static void call_terminated(Sal *sal, eXosip_event_t *ev){
497 op=(SalOp*)ev->external_reference;
499 ms_warning("Call terminated for already closed call ?");
502 eXosip_call_set_reference(ev->cid,NULL);
503 sal->callbacks.call_terminated(op);
506 static void call_released(Sal *sal, eXosip_event_t *ev){
508 op=(SalOp*)ev->external_reference;
512 eXosip_call_set_reference(ev->cid,NULL);
513 sal->callbacks.call_terminated(op);
516 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
517 const char *prx_realm=NULL,*www_realm=NULL;
518 osip_proxy_authenticate_t *prx_auth;
519 osip_www_authenticate_t *www_auth;
520 osip_message_t *resp=ev->response;
522 *username=osip_uri_get_username(resp->from->url);
523 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
524 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
526 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
528 www_realm=osip_www_authenticate_get_realm(www_auth);
532 }else if (www_realm){
540 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
542 const char *username,*realm;
543 op=(SalOp*)ev->external_reference;
545 ms_warning("No operation associated with this authentication !");
548 if (get_auth_data(ev,&realm,&username)==0){
549 if (op->pending_auth!=NULL)
550 eXosip_event_free(op->pending_auth);
552 sal->callbacks.auth_requested(op,realm,username);
558 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
560 const char *username,*realm;
561 op=(SalOp*)ev->external_reference;
563 ms_warning("No operation associated with this authentication_ok!");
566 if (get_auth_data(ev,&realm,&username)==0){
567 sal->callbacks.auth_success(op,realm,username);
571 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
574 const char *reason=NULL;
575 SalError error=SalErrorUnknown;
576 SalReason sr=SalReasonUnknown;
578 op=(SalOp*)ev->external_reference;
581 ms_warning("Call failure reported for a closed call, ignored.");
586 code=osip_message_get_status_code(ev->response);
587 reason=osip_message_get_reason_phrase(ev->response);
593 return process_authentication(sal,ev);
596 error=SalErrorUnknown;
599 error=SalErrorFailure;
600 sr=SalReasonNotFound;
606 eXosip_default_action(ev);
610 error=SalErrorFailure;
611 sr=SalReasonTemporarilyUnavailable;
613 error=SalErrorFailure;
619 error=SalErrorFailure;
620 sr=SalReasonDoNotDisturb;
623 error=SalErrorFailure;
624 sr=SalReasonDeclined;
628 error=SalErrorFailure;
630 }else error=SalErrorNoResponse;
632 if (code!=487) sal->callbacks.call_failure(op,error,sr,reason);
637 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
638 SalOp *op=(SalOp*)ev->external_reference;
639 osip_body_t *body=NULL;
642 ms_warning("media control xml received without operation context!");
646 osip_message_get_body(ev->request,0,&body);
647 if (body && body->body!=NULL &&
648 strstr(body->body,"picture_fast_update")){
649 osip_message_t *ans=NULL;
650 ms_message("Receiving VFU request !");
651 if (sal->callbacks.vfu_request){
652 sal->callbacks.vfu_request(op);
653 eXosip_call_build_answer(ev->tid,200,&ans);
655 eXosip_call_send_answer(ev->tid,200,ans);
660 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
661 SalOp *op=(SalOp*)ev->external_reference;
662 osip_body_t *body=NULL;
665 ms_warning("media dtmf relay received without operation context!");
669 osip_message_get_body(ev->request,0,&body);
670 if (body && body->body!=NULL){
671 osip_message_t *ans=NULL;
672 const char *name=strstr(body->body,"Signal");
673 if (name==NULL) name=strstr(body->body,"signal");
675 ms_warning("Could not extract the dtmf name from the SIP INFO.");
678 name+=strlen("signal");
679 if (sscanf(name," = %1s",tmp)==1){
680 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
681 if (sal->callbacks.dtmf_received != NULL)
682 sal->callbacks.dtmf_received(op, tmp[0]);
685 eXosip_call_build_answer(ev->tid,200,&ans);
687 eXosip_call_send_answer(ev->tid,200,ans);
691 static void call_message_new(Sal *sal, eXosip_event_t *ev){
692 osip_message_t *ans=NULL;
694 if (MSG_IS_INFO(ev->request)){
695 osip_content_type_t *ct;
696 ct=osip_message_get_content_type(ev->request);
697 if (ct && ct->subtype){
698 if (strcmp(ct->subtype,"media_control+xml")==0)
699 process_media_control_xml(sal,ev);
700 else if (strcmp(ct->subtype,"dtmf-relay")==0)
701 process_dtmf_relay(sal,ev);
703 ms_message("Unhandled SIP INFO.");
704 /*send an "Not implemented" answer*/
706 eXosip_call_build_answer(ev->tid,501,&ans);
708 eXosip_call_send_answer(ev->tid,501,ans);
712 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
714 eXosip_call_build_answer(ev->tid,200,&ans);
716 eXosip_call_send_answer(ev->tid,200,ans);
720 }else ms_warning("call_message_new: No request ?");
723 static void inc_update(Sal *sal, eXosip_event_t *ev){
724 osip_message_t *msg=NULL;
725 ms_message("Processing incoming UPDATE");
727 eXosip_message_build_answer(ev->tid,200,&msg);
729 eXosip_message_send_answer(ev->tid,200,msg);
733 static bool_t comes_from_local_if(osip_message_t *msg){
734 osip_via_t *via=NULL;
735 osip_message_get_via(msg,0,&via);
738 host=osip_via_get_host(via);
739 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
740 osip_generic_param_t *param=NULL;
741 osip_via_param_get_byname(via,"received",¶m);
742 if (param==NULL) return TRUE;
744 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
752 static void text_received(Sal *sal, eXosip_event_t *ev){
753 osip_body_t *body=NULL;
754 char *from=NULL,*msg;
756 osip_message_get_body(ev->request,0,&body);
758 ms_error("Could not get text message from SIP body");
762 osip_from_to_str(ev->request->from,&from);
763 sal->callbacks.text_received(sal,from,msg);
767 static void other_request(Sal *sal, eXosip_event_t *ev){
768 ms_message("in other_request");
769 if (ev->request==NULL) return;
770 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
771 text_received(sal,ev);
772 eXosip_message_send_answer(ev->tid,200,NULL);
773 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
774 osip_message_t *options=NULL;
775 eXosip_options_build_answer(ev->tid,200,&options);
776 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
777 osip_message_set_accept(options,"application/sdp");
778 eXosip_options_send_answer(ev->tid,200,options);
779 }else if (strcmp(ev->request->sip_method,"WAKEUP")==0
780 && comes_from_local_if(ev->request)) {
781 eXosip_message_send_answer(ev->tid,200,NULL);
782 ms_message("Receiving WAKEUP request !");
783 sal->callbacks.internal_message(sal,"WAKEUP");
784 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
785 ms_message("Receiving REFER request !");
786 if (comes_from_local_if(ev->request)) {
787 osip_header_t *h=NULL;
788 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
789 eXosip_message_send_answer(ev->tid,200,NULL);
791 sal->callbacks.refer_received(sal,NULL,h->hvalue);
793 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
794 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
799 osip_message_to_str(ev->request,&tmp,&msglen);
801 ms_message("Unsupported request received:\n%s",tmp);
804 /*answer with a 501 Not implemented*/
805 eXosip_message_send_answer(ev->tid,501,NULL);
809 static void update_contact(SalOp *op, const char *received, const char *rport){
810 SalAddress *addr=sal_address_new(sal_op_get_contact(op));
812 sal_address_set_domain(addr,received);
813 sal_address_set_port(addr,rport);
814 tmp=sal_address_as_string(addr);
815 sal_op_set_contact(op,tmp);
819 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
821 const char *rport,*received;
822 osip_via_t *via=NULL;
823 osip_generic_param_t *param=NULL;
824 osip_contact_t *ctt=NULL;
825 osip_message_get_via(last_answer,0,&via);
826 if (!via) return FALSE;
827 osip_via_param_get_byname(via,"rport",¶m);
828 if (param) rport=param->gvalue;
831 osip_via_param_get_byname(via,"received",¶m);
832 if (param) received=param->gvalue;
834 osip_message_get_contact(orig_request,0,&ctt);
835 if (strcmp(ctt->url->host,received)==0){
836 /*ip address matches, check ports*/
837 const char *contact_port=ctt->url->port;
838 const char *via_rport=rport;
839 if (via_rport==NULL || strlen(via_rport)>0)
841 if (contact_port==NULL || strlen(contact_port)>0)
843 if (strcmp(contact_port,via_rport)==0){
844 ms_message("Register has up to date contact, doing nothing.");
846 }else ms_message("ports do not match, need to update the register (%s <> %s)", contact_port,via_rport);
850 eXosip_register_build_register(op->rid,op->expires,&msg);
853 ms_warning("Fail to create a contact updated register.");
856 osip_message_get_contact(msg,0,&ctt);
857 if (ctt->url->host!=NULL){
858 osip_free(ctt->url->host);
860 ctt->url->host=osip_strdup(received);
861 if (ctt->url->port!=NULL){
862 osip_free(ctt->url->port);
864 ctt->url->port=osip_strdup(rport);
865 eXosip_register_send_register(op->rid,msg);
867 update_contact(op,received,rport);
868 ms_message("Resending new register with updated contact %s:%s",received,rport);
872 static void registration_success(Sal *sal, eXosip_event_t *ev){
873 SalOp *op=sal_find_register(sal,ev->rid);
874 osip_header_t *h=NULL;
877 ms_error("Receiving register response for unknown operation");
880 osip_message_get_expires(ev->request,0,&h);
881 if (h!=NULL && atoi(h->hvalue)!=0){
883 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
884 sal->callbacks.register_success(op,registered);
886 }else registered=FALSE;
889 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
891 const char *reason=NULL;
892 SalOp *op=sal_find_register(sal,ev->rid);
893 SalReason sr=SalReasonUnknown;
894 SalError se=SalErrorUnknown;
897 ms_error("Receiving register failure for unknown operation");
901 status_code=osip_message_get_status_code(ev->response);
902 reason=osip_message_get_reason_phrase(ev->response);
907 return process_authentication(sal,ev);
910 /* if contact is up to date, process the failure, otherwise resend a new register with
911 updated contact first, just in case the faillure is due to incorrect contact */
912 if (register_again_with_updated_contact(op,ev->request,ev->response))
913 return TRUE; /*we are retrying with an updated contact*/
914 if (status_code==403){
916 sr=SalReasonForbidden;
917 }else if (status_code==0){
918 se=SalErrorNoResponse;
920 sal->callbacks.register_failure(op,se,sr,reason);
925 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
927 case EXOSIP_CALL_ANSWERED:
928 ms_message("CALL_ANSWERED\n");
929 call_accepted(sal,ev);
930 authentication_ok(sal,ev);
932 case EXOSIP_CALL_CLOSED:
933 case EXOSIP_CALL_CANCELLED:
934 ms_message("CALL_CLOSED or CANCELLED\n");
935 call_terminated(sal,ev);
937 case EXOSIP_CALL_TIMEOUT:
938 case EXOSIP_CALL_NOANSWER:
939 ms_message("CALL_TIMEOUT or NOANSWER\n");
940 return call_failure(sal,ev);
942 case EXOSIP_CALL_REQUESTFAILURE:
943 case EXOSIP_CALL_GLOBALFAILURE:
944 case EXOSIP_CALL_SERVERFAILURE:
945 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
946 return call_failure(sal,ev);
948 case EXOSIP_CALL_INVITE:
949 ms_message("CALL_NEW\n");
950 inc_new_call(sal,ev);
952 case EXOSIP_CALL_REINVITE:
953 handle_reinvite(sal,ev);
955 case EXOSIP_CALL_ACK:
956 ms_message("CALL_ACK");
959 case EXOSIP_CALL_REDIRECTED:
960 ms_message("CALL_REDIRECTED");
961 eXosip_default_action(ev);
963 case EXOSIP_CALL_PROCEEDING:
964 ms_message("CALL_PROCEEDING");
965 call_proceeding(sal,ev);
967 case EXOSIP_CALL_RINGING:
968 ms_message("CALL_RINGING");
969 call_ringing(sal,ev);
971 case EXOSIP_CALL_MESSAGE_NEW:
972 ms_message("EXOSIP_CALL_MESSAGE_NEW");
973 call_message_new(sal,ev);
975 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
976 if (ev->did<0 && ev->response &&
977 (ev->response->status_code==407 || ev->response->status_code==401)){
978 return process_authentication(sal,ev);
981 case EXOSIP_IN_SUBSCRIPTION_NEW:
982 ms_message("CALL_SUBSCRIPTION_NEW ");
983 sal_exosip_subscription_recv(sal,ev);
985 case EXOSIP_SUBSCRIPTION_UPDATE:
986 ms_message("CALL_SUBSCRIPTION_UPDATE");
988 case EXOSIP_SUBSCRIPTION_NOTIFY:
989 ms_message("CALL_SUBSCRIPTION_NOTIFY");
990 sal_exosip_notify_recv(sal,ev);
992 case EXOSIP_SUBSCRIPTION_ANSWERED:
993 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i\n",ev->sid);
994 sal_exosip_subscription_answered(sal,ev);
996 case EXOSIP_SUBSCRIPTION_CLOSED:
997 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
998 sal_exosip_subscription_closed(sal,ev);
1000 case EXOSIP_CALL_RELEASED:
1001 ms_message("CALL_RELEASED\n");
1002 call_released(sal, ev);
1004 case EXOSIP_REGISTRATION_FAILURE:
1005 ms_message("REGISTRATION_FAILURE\n");
1006 return registration_failure(sal,ev);
1008 case EXOSIP_REGISTRATION_SUCCESS:
1009 authentication_ok(sal,ev);
1010 registration_success(sal,ev);
1012 case EXOSIP_MESSAGE_NEW:
1013 other_request(sal,ev);
1015 case EXOSIP_MESSAGE_REQUESTFAILURE:
1016 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
1017 return process_authentication(sal,ev);
1021 ms_message("Unhandled exosip event !");
1027 int sal_iterate(Sal *sal){
1030 while((ev=eXosip_event_wait(0,0))!=NULL){
1031 if (process_event(sal,ev))
1032 eXosip_event_free(ev);
1034 if (sal->automatic_action==0) {
1036 eXosip_automatic_refresh();
1043 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
1044 osip_message_t *msg;
1047 h->rid=eXosip_register_build_initial_register(from,proxy,sal_op_get_contact(h),expires,&msg);
1048 sal_add_register(h->base.root,h);
1051 eXosip_register_build_register(h->rid,expires,&msg);
1053 eXosip_register_send_register(h->rid,msg);
1061 SalAddress * sal_address_new(const char *uri){
1063 osip_from_init(&from);
1064 if (osip_from_parse(from,uri)!=0){
1065 osip_from_free(from);
1068 return (SalAddress*)from;
1071 SalAddress * sal_address_clone(const SalAddress *addr){
1072 osip_from_t *ret=NULL;
1073 osip_from_clone((osip_from_t*)addr,&ret);
1074 return (SalAddress*)ret;
1077 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
1079 const char *sal_address_get_scheme(const SalAddress *addr){
1080 const osip_from_t *u=(const osip_from_t*)addr;
1081 return null_if_empty(u->url->scheme);
1084 const char *sal_address_get_display_name(const SalAddress* addr){
1085 const osip_from_t *u=(const osip_from_t*)addr;
1086 return null_if_empty(u->displayname);
1089 const char *sal_address_get_username(const SalAddress *addr){
1090 const osip_from_t *u=(const osip_from_t*)addr;
1091 return null_if_empty(u->url->username);
1094 const char *sal_address_get_domain(const SalAddress *addr){
1095 const osip_from_t *u=(const osip_from_t*)addr;
1096 return null_if_empty(u->url->host);
1099 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
1100 osip_from_t *u=(osip_from_t*)addr;
1101 if (u->displayname!=NULL){
1102 osip_free(u->displayname);
1103 u->displayname=NULL;
1105 if (display_name!=NULL)
1106 u->displayname=osip_strdup(display_name);
1109 void sal_address_set_username(SalAddress *addr, const char *username){
1110 osip_from_t *uri=(osip_from_t*)addr;
1111 if (uri->url->username!=NULL){
1112 osip_free(uri->url->username);
1113 uri->url->username=NULL;
1116 uri->url->username=osip_strdup(username);
1119 void sal_address_set_domain(SalAddress *addr, const char *host){
1120 osip_from_t *uri=(osip_from_t*)addr;
1121 if (uri->url->host!=NULL){
1122 osip_free(uri->url->host);
1123 uri->url->host=NULL;
1126 uri->url->host=osip_strdup(host);
1129 void sal_address_set_port(SalAddress *addr, const char *port){
1130 osip_from_t *uri=(osip_from_t*)addr;
1131 if (uri->url->port!=NULL){
1132 osip_free(uri->url->port);
1133 uri->url->port=NULL;
1136 uri->url->port=osip_strdup(port);
1139 void sal_address_set_port_int(SalAddress *uri, int port){
1142 /*this is the default, special case to leave the port field blank*/
1143 sal_address_set_port(uri,NULL);
1146 snprintf(tmp,sizeof(tmp),"%i",port);
1147 sal_address_set_port(uri,tmp);
1150 void sal_address_clean(SalAddress *addr){
1151 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
1154 char *sal_address_as_string(const SalAddress *u){
1156 osip_from_to_str((osip_from_t*)u,&tmp);
1162 char *sal_address_as_string_uri_only(const SalAddress *u){
1163 char *tmp=NULL,*ret;
1164 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
1170 void sal_address_destroy(SalAddress *u){
1171 osip_from_free((osip_from_t*)u);