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"
25 static SalOp * sal_find_register(Sal *sal, int rid){
28 for(elem=sal->registers;elem!=NULL;elem=elem->next){
29 op=(SalOp*)elem->data;
30 if (op->rid==rid) return op;
35 static void sal_add_register(Sal *sal, SalOp *op){
36 sal->registers=ms_list_append(sal->registers,op);
39 static void sal_remove_register(Sal *sal, int rid){
42 for(elem=sal->registers;elem!=NULL;elem=elem->next){
43 op=(SalOp*)elem->data;
45 sal->registers=ms_list_remove_link(sal->registers,elem);
51 SalOp * sal_op_new(Sal *sal){
52 SalOp *op=ms_new(SalOp,1);
53 __sal_op_init(op,sal);
54 op->cid=op->did=op->tid=op->rid=op->nid=op->sid-1;
55 op->supports_session_timers=FALSE;
56 op->sdp_offering=TRUE;
57 op->pending_auth=NULL;
63 void sal_op_release(SalOp *op){
65 sdp_message_free(op->sdp_answer);
67 eXosip_event_free(op->pending_auth);
69 sal_remove_register(op->base.root,op->rid);
76 return ms_new0(Sal,1);
79 void sal_uninit(Sal* sal){
84 static void unimplemented_stub(){
85 ms_warning("Unimplemented SAL callback");
88 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
89 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
90 if (ctx->callbacks.call_received==NULL)
91 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
92 if (ctx->callbacks.call_ringing==NULL)
93 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
94 if (ctx->callbacks.call_accepted==NULL)
95 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
96 if (ctx->callbacks.call_failure==NULL)
97 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
98 if (ctx->callbacks.call_terminated==NULL)
99 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
100 if (ctx->callbacks.call_updated==NULL)
101 ctx->callbacks.call_updated=(SalOnCallUpdated)unimplemented_stub;
102 if (ctx->callbacks.auth_requested==NULL)
103 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
104 if (ctx->callbacks.auth_success==NULL)
105 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
106 if (ctx->callbacks.register_success==NULL)
107 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
108 if (ctx->callbacks.register_failure==NULL)
109 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
110 if (ctx->callbacks.dtmf_received==NULL)
111 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
112 if (ctx->callbacks.presence_changed==NULL)
113 ctx->callbacks.presence_changed=(SalOnPresenceChanged)unimplemented_stub;
114 if (ctx->callbacks.subscribe_received==NULL)
115 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
116 if (ctx->callbacks.text_received==NULL)
117 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
118 if (ctx->callbacks.internal_message==NULL)
119 ctx->callbacks.internal_message=(SalOnInternalMsg)unimplemented_stub;
122 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
125 int proto=IPPROTO_UDP;
127 if (ctx->running) eXosip_quit();
130 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
131 version of eXosip, which is not the case*/
132 /*see if it looks like an IPv6 address*/
133 ipv6=strchr(addr,':')!=NULL;
134 eXosip_enable_ipv6(ipv6);
136 if (tr!=SAL_TRANSPORT_DATAGRAM || is_secure){
137 ms_fatal("SIP over TCP or TLS or DTLS is not supported yet.");
141 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, 0);
145 void sal_set_user_agent(Sal *ctx, const char *user_agent){
146 eXosip_set_user_agent(user_agent);
149 void sal_use_session_timers(Sal *ctx, int expires){
150 ctx->session_expires=expires;
154 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
158 sdp_message_to_str(msg,&sdp);
160 snprintf(clen,sizeof(clen),"%i",sdplen);
161 osip_message_set_body(sip,sdp,sdplen);
162 osip_message_set_content_type(sip,"application/sdp");
163 osip_message_set_content_length(sip,clen);
167 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
168 sdp_message_t *msg=media_description_to_sdp(desc);
170 ms_error("Fail to print sdp message !");
174 sdp_message_free(msg);
177 static void sdp_process(SalOp *h){
179 sal_media_description_destroy(h->result);
181 h->result=sal_media_description_new();
182 if (h->sdp_offering){
183 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
186 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result);
187 h->sdp_answer=media_description_to_sdp(h->result);
188 strcpy(h->result->addr,h->base.remote_media->addr);
189 for(i=0;i<h->result->nstreams;++i){
190 if (h->result->streams[i].port>0){
191 strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr);
192 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
193 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
194 h->result->streams[i].port=h->base.remote_media->streams[i].port;
201 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
202 h->base.local_media=desc;
206 int sal_call(SalOp *h, const char *from, const char *to){
208 osip_message_t *invite=NULL;
209 sal_op_set_from(h,from);
211 err=eXosip_call_build_initial_invite(&invite,to,from,h->base.route,"Phone call");
213 ms_error("Could not create call.");
217 osip_message_set_contact(invite,h->base.contact);
218 if (h->base.root->session_expires!=0){
219 osip_message_set_header(invite, "Session-expires", "200");
220 osip_message_set_supported(invite, "timer");
222 if (h->base.local_media){
223 h->sdp_offering=TRUE;
224 set_sdp_from_desc(invite,h->base.local_media);
225 }else h->sdp_offering=FALSE;
227 err=eXosip_call_send_initial_invite(invite);
231 ms_error("Fail to send invite !");
234 eXosip_call_set_reference(h->cid,h);
239 int sal_call_accept(SalOp * h){
242 int err=eXosip_call_build_answer(h->tid,200,&msg);
243 if (err<0 || msg==NULL){
244 ms_error("Fail to build answer for call: err=%i",err);
247 if (h->base.root->session_expires!=0){
248 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
251 if (h->base.local_media){
252 /*this is the case where we received an invite without SDP*/
253 if (h->sdp_offering) {
254 set_sdp_from_desc(msg,h->base.local_media);
257 set_sdp(msg,h->sdp_answer);
260 ms_error("You are accepting a call but not defined any media capabilities !");
262 eXosip_call_send_answer(h->tid,200,msg);
266 const SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
267 if (h->base.local_media && h->base.remote_media && !h->result){
273 int sal_call_terminate(SalOp *h){
275 eXosip_call_terminate(h->cid,h->did);
277 eXosip_call_set_reference(h->cid,NULL);
281 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
282 if (h->pending_auth){
284 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
285 else userid=info->userid;
287 eXosip_add_authentication_info (info->username,userid,
288 info->password, NULL,info->realm);
289 eXosip_default_action(h->pending_auth);
291 eXosip_event_free(h->pending_auth);
292 h->pending_auth=NULL;
296 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
297 SalOp *op=sal_op_new(sal);
298 osip_from_t *from,*to;
300 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
302 op->base.remote_media=sal_media_description_new();
303 sdp_to_media_description(sdp,op->base.remote_media);
304 sdp_message_free(sdp);
305 }else op->sdp_offering=TRUE;
307 from=osip_message_get_from(ev->request);
308 to=osip_message_get_to(ev->request);
309 osip_from_to_str(from,&tmp);
310 sal_op_set_from(op,tmp);
312 osip_from_to_str(to,&tmp);
313 sal_op_set_to(op,tmp);
320 eXosip_call_set_reference(op->cid,op);
321 sal->callbacks.call_received(op);
324 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
325 SalOp *op=(SalOp*)ev->external_reference;
327 osip_message_t *msg=NULL;
330 ms_warning("Reinvite for non-existing operation !");
335 sdp=eXosip_get_sdp_info(ev->request);
336 if (op->base.remote_media){
337 sal_media_description_destroy(op->base.remote_media);
338 op->base.remote_media=NULL;
341 eXosip_call_build_answer(ev->tid,200,&msg);
343 if (msg==NULL) return;
344 if (op->base.root->session_expires!=0){
345 if (op->supports_session_timers) osip_message_set_supported(msg, "timer");
348 op->sdp_offering=FALSE;
349 op->base.remote_media=sal_media_description_new();
350 sdp_to_media_description(sdp,op->base.remote_media);
351 sdp_message_free(sdp);
353 set_sdp(msg,op->sdp_answer);
355 op->sdp_offering=TRUE;
356 set_sdp_from_desc(msg,op->base.local_media);
359 eXosip_call_send_answer(ev->tid,200,msg);
363 static void handle_ack(Sal *sal, eXosip_event_t *ev){
364 SalOp *op=(SalOp*)ev->external_reference;
368 ms_warning("ack for non-existing call !");
371 sdp=eXosip_get_sdp_info(ev->ack);
373 op->base.remote_media=sal_media_description_new();
374 sdp_to_media_description(sdp,op->base.remote_media);
376 sdp_message_free(sdp);
379 sal->callbacks.call_updated(op);
382 sal->callbacks.call_ack(op);
386 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
387 SalOp *op=(SalOp*)ev->external_reference;
389 ms_warning("This call has been canceled.");
391 eXosip_call_terminate(ev->cid,ev->did);
400 static void call_ringing(Sal *sal, eXosip_event_t *ev){
403 if (call_proceeding(sal, ev)==-1) return;
404 op=(SalOp*)ev->external_reference;
405 sdp=eXosip_get_sdp_info(ev->response);
407 op->base.remote_media=sal_media_description_new();
408 sdp_to_media_description(sdp,op->base.remote_media);
409 sdp_message_free(sdp);
410 if (op->base.local_media) sdp_process(op);
412 sal->callbacks.call_ringing(op);
415 static void call_accepted(Sal *sal, eXosip_event_t *ev){
417 osip_message_t *msg=NULL;
419 op=(SalOp*)ev->external_reference;
421 ms_error("A closed call is accepted ?");
424 sdp=eXosip_get_sdp_info(ev->response);
426 op->base.remote_media=sal_media_description_new();
427 sdp_to_media_description(sdp,op->base.remote_media);
428 sdp_message_free(sdp);
429 if (op->base.local_media) sdp_process(op);
431 eXosip_call_build_ack(ev->did,&msg);
433 set_sdp(msg,op->sdp_answer);
434 eXosip_call_send_ack(ev->did,msg);
435 sal->callbacks.call_accepted(op);
438 static void call_terminated(Sal *sal, eXosip_event_t *ev){
440 op=(SalOp*)ev->external_reference;
442 ms_warning("Call terminated for already closed call ?");
445 eXosip_call_set_reference(ev->cid,NULL);
446 sal->callbacks.call_terminated(op);
449 static void call_released(Sal *sal, eXosip_event_t *ev){
451 op=(SalOp*)ev->external_reference;
455 eXosip_call_set_reference(ev->cid,NULL);
456 sal->callbacks.call_terminated(op);
459 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
460 const char *prx_realm=NULL,*www_realm=NULL;
461 osip_proxy_authenticate_t *prx_auth;
462 osip_www_authenticate_t *www_auth;
463 osip_message_t *resp=ev->response;
465 *username=osip_uri_get_username(resp->from->url);
466 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
467 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
469 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
471 www_realm=osip_www_authenticate_get_realm(www_auth);
475 }else if (www_realm){
483 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
485 const char *username,*realm;
486 op=(SalOp*)ev->external_reference;
488 ms_warning("No operation associated with this authentication !");
491 if (get_auth_data(ev,&realm,&username)==0){
492 if (op->pending_auth!=NULL)
493 eXosip_event_free(op->pending_auth);
495 sal->callbacks.auth_requested(op,realm,username);
501 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
503 const char *username,*realm;
504 op=(SalOp*)ev->external_reference;
506 ms_warning("No operation associated with this authentication_ok!");
509 if (get_auth_data(ev,&realm,&username)==0){
510 sal->callbacks.auth_success(op,realm,username);
514 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
517 const char *reason=NULL;
518 SalError error=SalErrorUnknown;
519 SalReason sr=SalReasonUnknown;
521 op=(SalOp*)ev->external_reference;
524 ms_warning("Call failure reported for a closed call, ignored.");
529 code=osip_message_get_status_code(ev->response);
530 reason=osip_message_get_reason_phrase(ev->response);
536 return process_authentication(sal,ev);
539 error=SalErrorUnknown;
542 error=SalErrorFailure;
543 sr=SalReasonNotFound;
549 eXosip_default_action(ev);
553 error=SalErrorFailure;
554 sr=SalReasonTemporarilyUnavailable;
556 error=SalErrorFailure;
562 error=SalErrorFailure;
563 sr=SalReasonDoNotDisturb;
566 error=SalErrorFailure;
567 sr=SalReasonDeclined;
571 error=SalErrorFailure;
573 }else error=SalErrorNoResponse;
575 sal->callbacks.call_failure(op,error,sr,reason);
580 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
581 SalOp *op=(SalOp*)ev->external_reference;
582 osip_body_t *body=NULL;
585 ms_warning("media control xml received without operation context!");
589 osip_message_get_body(ev->request,0,&body);
590 if (body && body->body!=NULL &&
591 strstr(body->body,"picture_fast_update")){
592 osip_message_t *ans=NULL;
593 ms_message("Receiving VFU request !");
594 if (sal->callbacks.vfu_request){
595 sal->callbacks.vfu_request(op);
596 eXosip_call_build_answer(ev->tid,200,&ans);
598 eXosip_call_send_answer(ev->tid,200,ans);
603 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
604 SalOp *op=(SalOp*)ev->external_reference;
605 osip_body_t *body=NULL;
608 ms_warning("media dtmf relay received without operation context!");
612 osip_message_get_body(ev->request,0,&body);
613 if (body && body->body!=NULL){
614 osip_message_t *ans=NULL;
615 const char *name=strstr(body->body,"Signal");
616 if (name==NULL) name=strstr(body->body,"signal");
618 ms_warning("Could not extract the dtmf name from the SIP INFO.");
621 name+=strlen("signal");
622 if (sscanf(name," = %1s",tmp)==1){
623 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
624 if (sal->callbacks.dtmf_received != NULL)
625 sal->callbacks.dtmf_received(op, tmp[0]);
628 eXosip_call_build_answer(ev->tid,200,&ans);
630 eXosip_call_send_answer(ev->tid,200,ans);
634 static void call_message_new(Sal *sal, eXosip_event_t *ev){
635 osip_message_t *ans=NULL;
637 if (MSG_IS_INFO(ev->request)){
638 osip_content_type_t *ct;
639 ct=osip_message_get_content_type(ev->request);
640 if (ct && ct->subtype){
641 if (strcmp(ct->subtype,"media_control+xml")==0)
642 process_media_control_xml(sal,ev);
643 else if (strcmp(ct->subtype,"dtmf-relay")==0)
644 process_dtmf_relay(sal,ev);
646 ms_message("Unhandled SIP INFO.");
647 /*send an "Not implemented" answer*/
649 eXosip_call_build_answer(ev->tid,501,&ans);
651 eXosip_call_send_answer(ev->tid,501,ans);
655 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
657 eXosip_call_build_answer(ev->tid,200,&ans);
659 eXosip_call_send_answer(ev->tid,200,ans);
663 }else ms_warning("call_message_new: No request ?");
666 static void inc_update(Sal *sal, eXosip_event_t *ev){
667 osip_message_t *msg=NULL;
668 ms_message("Processing incoming UPDATE");
670 eXosip_message_build_answer(ev->tid,200,&msg);
672 eXosip_message_send_answer(ev->tid,200,msg);
676 static bool_t comes_from_local_if(osip_message_t *msg){
677 osip_via_t *via=NULL;
678 osip_message_get_via(msg,0,&via);
681 host=osip_via_get_host(via);
682 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
683 osip_generic_param_t *param=NULL;
684 osip_via_param_get_byname(via,"received",¶m);
685 if (param==NULL) return TRUE;
687 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
695 static void text_received(Sal *sal, eXosip_event_t *ev){
696 osip_body_t *body=NULL;
697 char *from=NULL,*msg;
699 osip_message_get_body(ev->request,0,&body);
701 ms_error("Could not get text message from SIP body");
705 osip_from_to_str(ev->request->from,&from);
706 sal->callbacks.text_received(sal,from,msg);
710 static void other_request(Sal *sal, eXosip_event_t *ev){
711 ms_message("in other_request");
712 if (ev->request==NULL) return;
713 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
714 text_received(sal,ev);
715 eXosip_message_send_answer(ev->tid,200,NULL);
716 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
717 osip_message_t *options=NULL;
718 eXosip_options_build_answer(ev->tid,200,&options);
719 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
720 osip_message_set_accept(options,"application/sdp");
721 eXosip_options_send_answer(ev->tid,200,options);
722 }else if (strcmp(ev->request->sip_method,"WAKEUP")==0
723 && comes_from_local_if(ev->request)) {
724 eXosip_message_send_answer(ev->tid,200,NULL);
725 ms_message("Receiving WAKEUP request !");
726 sal->callbacks.internal_message(sal,"WAKEUP");
727 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
728 ms_message("Receiving REFER request !");
729 if (comes_from_local_if(ev->request)) {
730 osip_header_t *h=NULL;
731 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
732 eXosip_message_send_answer(ev->tid,200,NULL);
734 sal->callbacks.refer_received(sal,NULL,h->hvalue);
736 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
737 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
742 osip_message_to_str(ev->request,&tmp,&msglen);
744 ms_message("Unsupported request received:\n%s",tmp);
747 /*answer with a 501 Not implemented*/
748 eXosip_message_send_answer(ev->tid,501,NULL);
752 static void update_contact(SalOp *op, const char *received, const char *rport){
753 SalAddress *addr=sal_address_new(sal_op_get_contact(op));
755 sal_address_set_domain(addr,received);
756 sal_address_set_port(addr,rport);
757 tmp=sal_address_as_string(addr);
758 sal_op_set_contact(op,tmp);
762 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
764 const char *rport,*received;
765 osip_via_t *via=NULL;
766 osip_generic_param_t *param=NULL;
767 osip_contact_t *ctt=NULL;
768 osip_message_get_via(last_answer,0,&via);
769 if (!via) return FALSE;
770 osip_via_param_get_byname(via,"rport",¶m);
771 if (param) rport=param->gvalue;
774 osip_via_param_get_byname(via,"received",¶m);
775 if (param) received=param->gvalue;
777 osip_message_get_contact(orig_request,0,&ctt);
778 if (strcmp(ctt->url->host,received)==0){
779 /*ip address matches, check ports*/
780 const char *contact_port=ctt->url->port;
781 const char *via_rport=rport;
782 if (via_rport==NULL || strlen(via_rport)>0)
784 if (contact_port==NULL || strlen(contact_port)>0)
786 if (strcmp(contact_port,via_rport)==0){
787 ms_message("Register has up to date contact, doing nothing.");
789 }else ms_message("ports do not match, need to update the register (%s <> %s)", contact_port,via_rport);
793 eXosip_register_build_register(op->rid,op->expires,&msg);
796 ms_warning("Fail to create a contact updated register.");
799 osip_message_get_contact(msg,0,&ctt);
800 if (ctt->url->host!=NULL){
801 osip_free(ctt->url->host);
803 ctt->url->host=osip_strdup(received);
804 if (ctt->url->port!=NULL){
805 osip_free(ctt->url->port);
807 ctt->url->port=osip_strdup(rport);
808 eXosip_register_send_register(op->rid,msg);
810 update_contact(op,received,rport);
811 ms_message("Resending new register with updated contact %s:%s",received,rport);
815 static void registration_success(Sal *sal, eXosip_event_t *ev){
816 SalOp *op=sal_find_register(sal,ev->rid);
817 osip_header_t *h=NULL;
820 ms_error("Receiving register response for unknown operation");
823 osip_message_get_expires(ev->request,0,&h);
824 if (h!=NULL && atoi(h->hvalue)!=0){
826 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
827 sal->callbacks.register_success(op,registered);
829 }else registered=FALSE;
832 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
834 const char *reason=NULL;
835 SalOp *op=sal_find_register(sal,ev->rid);
836 SalReason sr=SalReasonUnknown;
837 SalError se=SalErrorUnknown;
840 ms_error("Receiving register failure for unknown operation");
844 status_code=osip_message_get_status_code(ev->response);
845 reason=osip_message_get_reason_phrase(ev->response);
850 return process_authentication(sal,ev);
853 /* if contact is up to date, process the failure, otherwise resend a new register with
854 updated contact first, just in case the faillure is due to incorrect contact */
855 if (register_again_with_updated_contact(op,ev->request,ev->response))
856 return TRUE; /*we are retrying with an updated contact*/
857 if (status_code==403){
859 sr=SalReasonForbidden;
860 }else if (status_code==0){
861 se=SalErrorNoResponse;
863 sal->callbacks.register_failure(op,se,sr,reason);
868 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
870 case EXOSIP_CALL_ANSWERED:
871 ms_message("CALL_ANSWERED\n");
872 call_accepted(sal,ev);
873 authentication_ok(sal,ev);
875 case EXOSIP_CALL_CLOSED:
876 case EXOSIP_CALL_CANCELLED:
877 ms_message("CALL_CLOSED or CANCELLED\n");
878 call_terminated(sal,ev);
880 case EXOSIP_CALL_TIMEOUT:
881 case EXOSIP_CALL_NOANSWER:
882 ms_message("CALL_TIMEOUT or NOANSWER\n");
883 return call_failure(sal,ev);
885 case EXOSIP_CALL_REQUESTFAILURE:
886 case EXOSIP_CALL_GLOBALFAILURE:
887 case EXOSIP_CALL_SERVERFAILURE:
888 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
889 return call_failure(sal,ev);
891 case EXOSIP_CALL_INVITE:
892 ms_message("CALL_NEW\n");
893 inc_new_call(sal,ev);
895 case EXOSIP_CALL_REINVITE:
896 handle_reinvite(sal,ev);
898 case EXOSIP_CALL_ACK:
899 ms_message("CALL_ACK");
902 case EXOSIP_CALL_REDIRECTED:
903 ms_message("CALL_REDIRECTED");
904 eXosip_default_action(ev);
906 case EXOSIP_CALL_PROCEEDING:
907 ms_message("CALL_PROCEEDING");
908 call_proceeding(sal,ev);
910 case EXOSIP_CALL_RINGING:
911 ms_message("CALL_RINGING");
912 call_ringing(sal,ev);
914 case EXOSIP_CALL_MESSAGE_NEW:
915 ms_message("EXOSIP_CALL_MESSAGE_NEW");
916 call_message_new(sal,ev);
918 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
919 if (ev->did<0 && ev->response &&
920 (ev->response->status_code==407 || ev->response->status_code==401)){
921 return process_authentication(sal,ev);
924 case EXOSIP_IN_SUBSCRIPTION_NEW:
925 ms_message("CALL_SUBSCRIPTION_NEW ");
926 sal_exosip_subscription_recv(sal,ev);
928 case EXOSIP_SUBSCRIPTION_UPDATE:
929 ms_message("CALL_SUBSCRIPTION_UPDATE");
931 case EXOSIP_SUBSCRIPTION_NOTIFY:
932 ms_message("CALL_SUBSCRIPTION_NOTIFY");
933 sal_exosip_notify_recv(sal,ev);
935 case EXOSIP_SUBSCRIPTION_ANSWERED:
936 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i\n",ev->sid);
937 sal_exosip_subscription_answered(sal,ev);
939 case EXOSIP_SUBSCRIPTION_CLOSED:
940 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
941 sal_exosip_subscription_closed(sal,ev);
943 case EXOSIP_CALL_RELEASED:
944 ms_message("CALL_RELEASED\n");
945 call_released(sal, ev);
947 case EXOSIP_REGISTRATION_FAILURE:
948 ms_message("REGISTRATION_FAILURE\n");
949 return registration_failure(sal,ev);
951 case EXOSIP_REGISTRATION_SUCCESS:
952 authentication_ok(sal,ev);
953 registration_success(sal,ev);
955 case EXOSIP_MESSAGE_NEW:
956 other_request(sal,ev);
958 case EXOSIP_MESSAGE_REQUESTFAILURE:
959 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
960 return process_authentication(sal,ev);
964 ms_message("Unhandled exosip event !");
970 int sal_iterate(Sal *sal){
973 while((ev=eXosip_event_wait(0,0))!=NULL){
974 if (process_event(sal,ev))
975 eXosip_event_free(ev);
977 if (sal->automatic_action==0) {
979 eXosip_automatic_refresh();
986 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
990 h->rid=eXosip_register_build_initial_register(from,proxy,sal_op_get_contact(h),expires,&msg);
991 sal_add_register(h->base.root,h);
994 eXosip_register_build_register(h->rid,expires,&msg);
996 eXosip_register_send_register(h->rid,msg);
1004 SalAddress * sal_address_new(const char *uri){
1006 osip_from_init(&from);
1007 if (osip_from_parse(from,uri)!=0){
1008 osip_from_free(from);
1011 return (SalAddress*)from;
1014 SalAddress * sal_address_clone(const SalAddress *addr){
1015 osip_from_t *ret=NULL;
1016 osip_from_clone((osip_from_t*)addr,&ret);
1017 return (SalAddress*)ret;
1020 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
1022 const char *sal_address_get_scheme(const SalAddress *addr){
1023 const osip_from_t *u=(const osip_from_t*)addr;
1024 return null_if_empty(u->url->scheme);
1027 const char *sal_address_get_display_name(const SalAddress* addr){
1028 const osip_from_t *u=(const osip_from_t*)addr;
1029 return null_if_empty(u->displayname);
1032 const char *sal_address_get_username(const SalAddress *addr){
1033 const osip_from_t *u=(const osip_from_t*)addr;
1034 return null_if_empty(u->url->username);
1037 const char *sal_address_get_domain(const SalAddress *addr){
1038 const osip_from_t *u=(const osip_from_t*)addr;
1039 return null_if_empty(u->url->host);
1042 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
1043 osip_from_t *u=(osip_from_t*)addr;
1044 if (u->displayname!=NULL){
1045 osip_free(u->displayname);
1046 u->displayname=NULL;
1048 if (display_name!=NULL)
1049 u->displayname=osip_strdup(display_name);
1052 void sal_address_set_username(SalAddress *addr, const char *username){
1053 osip_from_t *uri=(osip_from_t*)addr;
1054 if (uri->url->username!=NULL){
1055 osip_free(uri->url->username);
1056 uri->url->username=NULL;
1059 uri->url->username=osip_strdup(username);
1062 void sal_address_set_domain(SalAddress *addr, const char *host){
1063 osip_from_t *uri=(osip_from_t*)addr;
1064 if (uri->url->host!=NULL){
1065 osip_free(uri->url->host);
1066 uri->url->host=NULL;
1069 uri->url->host=osip_strdup(host);
1072 void sal_address_set_port(SalAddress *addr, const char *port){
1073 osip_from_t *uri=(osip_from_t*)addr;
1074 if (uri->url->port!=NULL){
1075 osip_free(uri->url->port);
1076 uri->url->port=NULL;
1079 uri->url->port=osip_strdup(port);
1082 void sal_address_set_port_int(SalAddress *uri, int port){
1085 /*this is the default, special case to leave the port field blank*/
1086 sal_address_set_port(uri,NULL);
1089 snprintf(tmp,sizeof(tmp),"%i",port);
1090 sal_address_set_port(uri,tmp);
1093 void sal_address_clean(SalAddress *addr){
1094 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
1097 char *sal_address_as_string(const SalAddress *u){
1099 osip_from_to_str((osip_from_t*)u,&tmp);
1105 char *sal_address_as_string_uri_only(const SalAddress *u){
1106 char *tmp=NULL,*ret;
1107 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
1113 void sal_address_destroy(SalAddress *u){
1114 osip_from_free((osip_from_t*)u);