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"
28 // Necessary to make it linked
29 static void for_linker() { eXosip_transport_hook_register(NULL); }
31 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
33 static void text_received(Sal *sal, eXosip_event_t *ev);
35 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
36 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer);
37 static void update_contact_from_response(SalOp *op, osip_message_t *response);
39 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
41 while(!osip_list_eol(l,0)) {
42 data=osip_list_get(l,0);
43 osip_list_remove(l,0);
44 if (data) freefunc(data);
48 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
49 if (eXosip_guess_localip(address_family,ip,iplen)<0){
50 /*default to something */
51 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
52 ms_error("Could not find default routable ip address !");
57 static SalOp * sal_find_call(Sal *sal, int cid){
60 for(elem=sal->calls;elem!=NULL;elem=elem->next){
61 op=(SalOp*)elem->data;
62 if (op->cid==cid) return op;
67 static void sal_add_call(Sal *sal, SalOp *op){
68 sal->calls=ms_list_append(sal->calls,op);
71 static void sal_remove_call(Sal *sal, SalOp *op){
72 sal->calls=ms_list_remove(sal->calls, op);
75 static SalOp * sal_find_register(Sal *sal, int rid){
78 for(elem=sal->registers;elem!=NULL;elem=elem->next){
79 op=(SalOp*)elem->data;
80 if (op->rid==rid) return op;
85 static void sal_add_register(Sal *sal, SalOp *op){
86 sal->registers=ms_list_append(sal->registers,op);
89 static void sal_remove_register(Sal *sal, int rid){
92 for(elem=sal->registers;elem!=NULL;elem=elem->next){
93 op=(SalOp*)elem->data;
95 sal->registers=ms_list_remove_link(sal->registers,elem);
101 static SalOp * sal_find_other(Sal *sal, osip_message_t *response){
104 osip_call_id_t *callid=osip_message_get_call_id(response);
106 ms_error("There is no call-id in this response !");
109 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
110 op=(SalOp*)elem->data;
111 if (osip_call_id_match(callid,op->call_id)==0) return op;
116 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
117 osip_call_id_t *callid=osip_message_get_call_id(request);
119 ms_error("There is no call id in the request !");
122 osip_call_id_clone(callid,&op->call_id);
123 sal->other_transactions=ms_list_append(sal->other_transactions,op);
126 static void sal_remove_other(Sal *sal, SalOp *op){
127 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
131 static void sal_add_pending_auth(Sal *sal, SalOp *op){
132 sal->pending_auths=ms_list_append(sal->pending_auths,op);
136 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
137 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
140 void sal_exosip_fix_route(SalOp *op){
141 if (sal_op_get_route(op)!=NULL){
142 osip_route_t *rt=NULL;
143 osip_uri_param_t *lr_param=NULL;
145 osip_route_init(&rt);
146 if (osip_route_parse(rt,sal_op_get_route(op))<0){
147 ms_warning("Bad route %s!",sal_op_get_route(op));
148 sal_op_set_route(op,NULL);
150 /* check if the lr parameter is set , if not add it */
151 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
154 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
155 osip_route_to_str(rt,&tmproute);
156 sal_op_set_route(op,tmproute);
164 SalOp * sal_op_new(Sal *sal){
165 SalOp *op=ms_new(SalOp,1);
166 __sal_op_init(op,sal);
167 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
169 op->supports_session_timers=FALSE;
170 op->sdp_offering=TRUE;
171 op->pending_auth=NULL;
176 op->referred_by=NULL;
177 op->masquerade_via=FALSE;
178 op->auto_answer_asked=FALSE;
180 op->terminated=FALSE;
184 bool_t sal_call_autoanswer_asked(SalOp *op)
186 return op->auto_answer_asked;
189 void sal_op_release(SalOp *op){
191 sdp_message_free(op->sdp_answer);
192 if (op->pending_auth)
193 eXosip_event_free(op->pending_auth);
195 sal_remove_register(op->base.root,op->rid);
196 eXosip_register_remove(op->rid);
199 ms_message("Cleaning cid %i",op->cid);
200 sal_remove_call(op->base.root,op);
203 sal_remove_out_subscribe(op->base.root,op);
206 sal_remove_in_subscribe(op->base.root,op);
208 osip_call_id_free(op->call_id);
211 if (op->pending_auth){
212 sal_remove_pending_auth(op->base.root,op);
215 sal_media_description_unref(op->result);
217 sal_remove_other(op->base.root,op);
218 osip_call_id_free(op->call_id);
221 ms_free(op->replaces);
223 if (op->referred_by){
224 ms_free(op->referred_by);
227 sal_auth_info_delete(op->auth_info);
232 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
233 int ortp_level=ORTP_DEBUG;
239 ortp_level=ORTP_MESSAGE;
242 ortp_level=ORTP_WARNING;
246 ortp_level=ORTP_ERROR;
249 ortp_level=ORTP_FATAL;
251 case END_TRACE_LEVEL:
254 if (ortp_log_level_enabled(level)){
255 int len=strlen(chfr);
256 char *chfrdup=ortp_strdup(chfr);
257 /*need to remove endline*/
259 if (chfrdup[len-1]=='\n')
261 if (chfrdup[len-2]=='\r')
264 ortp_logv(ortp_level,chfrdup,ap);
271 static bool_t firsttime=TRUE;
274 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
279 sal->keepalive_period=30;
280 sal->double_reg=TRUE;
281 sal->use_rports=TRUE;
283 sal->reuse_authorization=FALSE;
285 sal->verify_server_certs=TRUE;
289 void sal_uninit(Sal* sal){
292 ms_free(sal->rootCa);
296 void sal_set_user_pointer(Sal *sal, void *user_data){
300 void *sal_get_user_pointer(const Sal *sal){
304 static void unimplemented_stub(){
305 ms_warning("Unimplemented SAL callback");
308 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
309 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
310 if (ctx->callbacks.call_received==NULL)
311 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
312 if (ctx->callbacks.call_ringing==NULL)
313 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
314 if (ctx->callbacks.call_accepted==NULL)
315 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
316 if (ctx->callbacks.call_failure==NULL)
317 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
318 if (ctx->callbacks.call_terminated==NULL)
319 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
320 if (ctx->callbacks.call_released==NULL)
321 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
322 if (ctx->callbacks.call_updating==NULL)
323 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
324 if (ctx->callbacks.auth_requested==NULL)
325 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
326 if (ctx->callbacks.auth_success==NULL)
327 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
328 if (ctx->callbacks.register_success==NULL)
329 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
330 if (ctx->callbacks.register_failure==NULL)
331 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
332 if (ctx->callbacks.dtmf_received==NULL)
333 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
334 if (ctx->callbacks.notify==NULL)
335 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
336 if (ctx->callbacks.notify_presence==NULL)
337 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
338 if (ctx->callbacks.subscribe_received==NULL)
339 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
340 if (ctx->callbacks.text_received==NULL)
341 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
342 if (ctx->callbacks.ping_reply==NULL)
343 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
346 int sal_unlisten_ports(Sal *ctx){
355 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
358 int proto=IPPROTO_UDP;
359 int keepalive = ctx->keepalive_period;
362 case SalTransportUDP:
364 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
366 case SalTransportTCP:
367 case SalTransportTLS:
370 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
373 eXosip_tls_ctx_t tlsCtx;
374 memset(&tlsCtx, 0, sizeof(tlsCtx));
375 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
376 eXosip_set_tls_ctx(&tlsCtx);
378 eXosip_tls_verify_certificate(ctx->verify_server_certs);
381 ms_warning("unexpected proto, using datagram");
385 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
386 version of eXosip, which is not the case*/
387 /*see if it looks like an IPv6 address*/
388 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
389 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
390 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
391 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
393 ipv6=strchr(addr,':')!=NULL;
394 eXosip_enable_ipv6(ipv6);
396 if (is_secure && tr == SalTransportUDP){
397 ms_fatal("SIP over DTLS is not supported yet.");
400 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
401 #ifdef HAVE_EXOSIP_GET_SOCKET
402 ms_message("Exosip has socket number %i",eXosip_get_socket(proto));
409 ortp_socket_t sal_get_socket(Sal *ctx){
410 #ifdef HAVE_EXOSIP_GET_SOCKET
411 return eXosip_get_socket(IPPROTO_UDP);
413 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
418 void sal_set_user_agent(Sal *ctx, const char *user_agent){
419 eXosip_set_user_agent(user_agent);
422 void sal_use_session_timers(Sal *ctx, int expires){
423 ctx->session_expires=expires;
426 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
427 ctx->one_matching_codec=one_matching_codec;
430 MSList *sal_get_pending_auths(Sal *sal){
431 return ms_list_copy(sal->pending_auths);
434 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
435 ctx->double_reg=enabled;
438 void sal_use_rport(Sal *ctx, bool_t use_rports){
439 ctx->use_rports=use_rports;
441 void sal_use_101(Sal *ctx, bool_t use_101){
442 ctx->use_101=use_101;
445 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
447 ms_free(ctx->rootCa);
448 ctx->rootCa = ms_strdup(rootCa);
451 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
452 ctx->verify_server_certs=verify;
453 eXosip_tls_verify_certificate(verify);
456 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
457 osip_via_t *via=NULL;
458 osip_generic_param_t *param=NULL;
459 const char *rport=NULL;
463 osip_message_get_via(msg,0,&via);
465 ms_warning("extract_received_rport(): no via.");
469 *transport = sal_transport_parse(via->protocol);
471 if (via->port && via->port[0]!='\0')
472 *rportval=atoi(via->port);
474 osip_via_param_get_byname(via,"rport",¶m);
477 if (rport && rport[0]!='\0') *rportval=atoi(rport);
481 osip_via_param_get_byname(via,"received",¶m);
482 if (param) *received=param->gvalue;
484 if (rport==NULL && *received==NULL){
485 ms_warning("extract_received_rport(): no rport and no received parameters.");
491 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
495 sdp_message_to_str(msg,&sdp);
497 snprintf(clen,sizeof(clen),"%i",sdplen);
498 osip_message_set_body(sip,sdp,sdplen);
499 osip_message_set_content_type(sip,"application/sdp");
500 osip_message_set_content_length(sip,clen);
504 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
505 sdp_message_t *msg=media_description_to_sdp(desc);
507 ms_error("Fail to print sdp message !");
511 sdp_message_free(msg);
514 static void sdp_process(SalOp *h){
515 ms_message("Doing SDP offer/answer process");
517 sal_media_description_unref(h->result);
519 h->result=sal_media_description_new();
520 if (h->sdp_offering){
521 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
524 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
525 h->sdp_answer=media_description_to_sdp(h->result);
526 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
527 It should contains media parameters constraint from the remote offer, not our response*/
528 strcpy(h->result->addr,h->base.remote_media->addr);
529 h->result->bandwidth=h->base.remote_media->bandwidth;
531 for(i=0;i<h->result->nstreams;++i){
532 if (h->result->streams[i].port>0){
533 strcpy(h->result->streams[i].addr,h->base.remote_media->streams[i].addr);
534 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
535 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
536 h->result->streams[i].port=h->base.remote_media->streams[i].port;
538 if (h->result->streams[i].proto == SalProtoRtpSavp) {
539 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
547 int sal_call_is_offerer(const SalOp *h){
548 return h->sdp_offering;
551 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
553 sal_media_description_ref(desc);
554 if (h->base.local_media)
555 sal_media_description_unref(h->base.local_media);
556 h->base.local_media=desc;
560 int sal_call(SalOp *h, const char *from, const char *to){
563 osip_message_t *invite=NULL;
564 sal_op_set_from(h,from);
566 sal_exosip_fix_route(h);
568 h->terminated = FALSE;
570 route = sal_op_get_route(h);
571 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
573 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
574 err, from, to, route);
577 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
578 if (h->base.contact){
579 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
580 osip_message_set_contact(invite,h->base.contact);
582 if (h->base.root->session_expires!=0){
583 osip_message_set_header(invite, "Session-expires", "200");
584 osip_message_set_supported(invite, "timer");
586 if (h->base.local_media){
587 h->sdp_offering=TRUE;
588 set_sdp_from_desc(invite,h->base.local_media);
589 }else h->sdp_offering=FALSE;
591 osip_message_set_header(invite,"Replaces",h->replaces);
593 osip_message_set_header(invite,"Referred-By",h->referred_by);
597 err=eXosip_call_send_initial_invite(invite);
601 ms_error("Fail to send invite ! Error code %d", err);
604 sal_add_call(h->base.root,h);
609 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
612 /*if early media send also 180 and 183 */
613 if (early_media && h->sdp_answer){
616 eXosip_call_build_answer(h->tid,180,&msg);
618 set_sdp(msg,h->sdp_answer);
619 eXosip_call_send_answer(h->tid,180,msg);
622 eXosip_call_build_answer(h->tid,183,&msg);
624 set_sdp(msg,h->sdp_answer);
625 eXosip_call_send_answer(h->tid,183,msg);
630 eXosip_call_send_answer(h->tid,180,NULL);
636 int sal_call_accept(SalOp * h){
638 const char *contact=sal_op_get_contact(h);
640 int err=eXosip_call_build_answer(h->tid,200,&msg);
641 if (err<0 || msg==NULL){
642 ms_error("Fail to build answer for call: err=%i",err);
645 if (h->base.root->session_expires!=0){
646 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
650 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
651 osip_message_set_contact(msg,contact);
654 if (h->base.local_media){
655 /*this is the case where we received an invite without SDP*/
656 if (h->sdp_offering) {
657 set_sdp_from_desc(msg,h->base.local_media);
660 set_sdp(msg,h->sdp_answer);
661 sdp_message_free(h->sdp_answer);
666 ms_error("You are accepting a call but not defined any media capabilities !");
668 eXosip_call_send_answer(h->tid,200,msg);
672 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
673 if (reason==SalReasonBusy){
675 eXosip_call_send_answer(h->tid,486,NULL);
678 else if (reason==SalReasonTemporarilyUnavailable){
680 eXosip_call_send_answer(h->tid,480,NULL);
682 }else if (reason==SalReasonDoNotDisturb){
684 eXosip_call_send_answer(h->tid,600,NULL);
686 }else if (reason==SalReasonMedia){
688 eXosip_call_send_answer(h->tid,415,NULL);
690 }else if (redirect!=NULL && reason==SalReasonRedirect){
693 if (strstr(redirect,"sip:")!=0) code=302;
696 eXosip_call_build_answer(h->tid,code,&msg);
697 osip_message_set_contact(msg,redirect);
698 eXosip_call_send_answer(h->tid,code,msg);
700 }else sal_call_terminate(h);
704 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
705 if (h->base.local_media && h->base.remote_media && !h->result){
711 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
712 if (refered_call->replaces)
713 h->replaces=ms_strdup(refered_call->replaces);
714 if (refered_call->referred_by)
715 h->referred_by=ms_strdup(refered_call->referred_by);
719 int sal_ping(SalOp *op, const char *from, const char *to){
720 osip_message_t *options=NULL;
722 sal_op_set_from(op,from);
723 sal_op_set_to(op,to);
724 /*bug here: eXosip2 does not honor the route argument*/
725 eXosip_options_build_request (&options, sal_op_get_to(op),
726 sal_op_get_from(op),sal_op_get_route(op));
728 if (op->base.root->session_expires!=0){
729 osip_message_set_header(options, "Session-expires", "200");
730 osip_message_set_supported(options, "timer");
732 sal_add_other(sal_op_get_sal(op),op,options);
733 return eXosip_options_send_request(options);
738 int sal_call_accept_refer(SalOp *op){
739 osip_message_t *msg=NULL;
742 err = eXosip_call_build_notify(op->did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
745 osip_message_set_header(msg,(const char *)"event","refer");
746 osip_message_set_content_type(msg,"message/sipfrag");
747 osip_message_set_body(msg,"SIP/2.0 100 Trying",sizeof("SIP/2.0 100 Trying"));
748 eXosip_call_send_request(op->did,msg);
752 ms_error("could not get a notify built\n");
758 int sal_call_refer(SalOp *h, const char *refer_to){
759 osip_message_t *msg=NULL;
762 eXosip_call_build_refer(h->did,refer_to, &msg);
763 if (msg) err=eXosip_call_send_request(h->did, msg);
769 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
770 osip_message_t *msg=NULL;
771 char referto[256]={0};
774 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
775 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
779 eXosip_call_build_refer(h->did,referto, &msg);
780 osip_message_set_header(msg,"Referred-By",h->base.from);
781 if (msg) err=eXosip_call_send_request(h->did, msg);
787 SalOp *sal_call_get_replaces(SalOp *h){
788 if (h!=NULL && h->replaces!=NULL){
791 cid=eXosip_call_find_by_replaces(h->replaces);
794 SalOp *ret=sal_find_call(h->base.root,cid);
801 int sal_call_send_dtmf(SalOp *h, char dtmf){
802 osip_message_t *msg=NULL;
807 eXosip_call_build_info(h->did,&msg);
809 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
810 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
811 osip_message_set_content_type(msg,"application/dtmf-relay");
812 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
813 osip_message_set_content_length(msg,clen);
814 eXosip_call_send_request(h->did,msg);
820 static void push_auth_to_exosip(const SalAuthInfo *info){
822 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
823 else userid=info->userid;
824 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
825 eXosip_add_authentication_info (info->username,userid,
826 info->password, NULL,info->realm);
829 * Just for symmetry ;-)
831 static void pop_auth_from_exosip() {
832 eXosip_clear_authentication_info();
835 int sal_call_terminate(SalOp *h){
837 if (h == NULL) return -1;
838 if (h->auth_info) push_auth_to_exosip(h->auth_info);
840 err=eXosip_call_terminate(h->cid,h->did);
842 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
844 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
850 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
851 if (h->pending_auth){
852 push_auth_to_exosip(info);
854 /*FIXME exosip does not take into account this update register message*/
856 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
860 update_contact_from_response(h,h->pending_auth->response);
862 eXosip_default_action(h->pending_auth);
864 ms_message("eXosip_default_action() done");
865 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
867 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
868 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
871 void sal_op_cancel_authentication(SalOp *h) {
873 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure"));
874 } else if (h->cid >0) {
875 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,_("Authentication failure"),0);
877 ms_warning("Auth failure not handled");
881 static void set_network_origin(SalOp *op, osip_message_t *req){
882 const char *received=NULL;
885 SalTransport transport;
886 if (extract_received_rport(req,&received,&rport,&transport)!=0){
887 osip_via_t *via=NULL;
889 osip_message_get_via(req,0,&via);
890 received=osip_via_get_host(via);
891 tmp=osip_via_get_port(via);
892 if (tmp) rport=atoi(tmp);
894 if (transport != SalTransportUDP) {
895 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
897 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
899 __sal_op_set_network_origin(op,origin);
902 static void set_remote_ua(SalOp* op, osip_message_t *req){
903 if (op->base.remote_ua==NULL){
904 osip_header_t *h=NULL;
905 osip_message_get_user_agent(req,0,&h);
907 op->base.remote_ua=ms_strdup(h->hvalue);
912 static void set_replaces(SalOp *op, osip_message_t *req){
913 osip_header_t *h=NULL;
916 ms_free(op->replaces);
919 osip_message_header_get_byname(req,"replaces",0,&h);
921 if (h->hvalue && h->hvalue[0]!='\0'){
922 op->replaces=ms_strdup(h->hvalue);
927 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
929 return sal_find_call(sal,ev->cid);
932 return sal_find_register(sal,ev->rid);
935 return sal_find_out_subscribe(sal,ev->sid);
938 return sal_find_in_subscribe(sal,ev->nid);
940 if (ev->response) return sal_find_other(sal,ev->response);
944 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
945 SalOp *op=sal_op_new(sal);
946 osip_from_t *from,*to;
947 osip_call_info_t *call_info;
949 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
951 set_network_origin(op,ev->request);
952 set_remote_ua(op,ev->request);
953 set_replaces(op,ev->request);
956 op->sdp_offering=FALSE;
957 op->base.remote_media=sal_media_description_new();
958 sdp_to_media_description(sdp,op->base.remote_media);
959 sdp_message_free(sdp);
960 }else op->sdp_offering=TRUE;
962 from=osip_message_get_from(ev->request);
963 to=osip_message_get_to(ev->request);
964 osip_from_to_str(from,&tmp);
965 sal_op_set_from(op,tmp);
967 osip_from_to_str(to,&tmp);
968 sal_op_set_to(op,tmp);
971 osip_message_get_call_info(ev->request,0,&call_info);
974 osip_call_info_to_str(call_info,&tmp);
975 if( strstr(tmp,"answer-after=") != NULL)
977 op->auto_answer_asked=TRUE;
978 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
987 sal_add_call(op->base.root,op);
988 sal->callbacks.call_received(op);
991 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
992 SalOp *op=find_op(sal,ev);
994 osip_message_t *msg=NULL;
997 ms_warning("Reinvite for non-existing operation !");
1002 sdp=eXosip_get_sdp_info(ev->request);
1003 if (op->base.remote_media){
1004 sal_media_description_unref(op->base.remote_media);
1005 op->base.remote_media=NULL;
1008 sal_media_description_unref(op->result);
1012 op->sdp_offering=FALSE;
1013 op->base.remote_media=sal_media_description_new();
1014 sdp_to_media_description(sdp,op->base.remote_media);
1015 sdp_message_free(sdp);
1016 sal->callbacks.call_updating(op);
1018 op->sdp_offering=TRUE;
1020 eXosip_call_build_answer(ev->tid,200,&msg);
1022 set_sdp_from_desc(msg,op->base.local_media);
1023 eXosip_call_send_answer(ev->tid,200,msg);
1030 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1031 SalOp *op=find_op(sal,ev);
1035 ms_warning("ack for non-existing call !");
1038 sdp=eXosip_get_sdp_info(ev->ack);
1040 op->base.remote_media=sal_media_description_new();
1041 sdp_to_media_description(sdp,op->base.remote_media);
1043 sdp_message_free(sdp);
1046 if (sdp) sal->callbacks.call_updating(op);
1049 sal->callbacks.call_ack(op);
1053 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1054 const char *received;
1056 SalTransport transport;
1057 if (extract_received_rport(response,&received,&rport,&transport)==0){
1058 const char *contact=sal_op_get_contact(op);
1060 /*no contact given yet, use from instead*/
1061 contact=sal_op_get_from(op);
1064 SalAddress *addr=sal_address_new(contact);
1066 sal_address_set_domain(addr,received);
1067 sal_address_set_port_int(addr,rport);
1068 if (transport!=SalTransportUDP)
1069 sal_address_set_transport(addr,transport);
1070 tmp=sal_address_as_string(addr);
1071 ms_message("Contact address updated to %s",tmp);
1072 sal_op_set_contact(op,tmp);
1073 sal_address_destroy(addr);
1079 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1080 SalOp *op=find_op(sal,ev);
1082 if (op==NULL || op->terminated==TRUE) {
1083 ms_warning("This call has been canceled.");
1085 eXosip_call_terminate(ev->cid,ev->did);
1093 /* update contact if received and rport are set by the server
1094 note: will only be used by remote for next INVITE, if any...*/
1095 update_contact_from_response(op,ev->response);
1099 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1101 SalOp *op=find_op(sal,ev);
1102 if (call_proceeding(sal, ev)==-1) return;
1104 set_remote_ua(op,ev->response);
1105 sdp=eXosip_get_sdp_info(ev->response);
1107 op->base.remote_media=sal_media_description_new();
1108 sdp_to_media_description(sdp,op->base.remote_media);
1109 sdp_message_free(sdp);
1110 if (op->base.local_media) sdp_process(op);
1112 sal->callbacks.call_ringing(op);
1115 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1117 osip_message_t *msg=NULL;
1118 SalOp *op=find_op(sal,ev);
1119 const char *contact;
1121 if (op==NULL || op->terminated==TRUE) {
1122 ms_warning("This call has been already terminated.");
1124 eXosip_call_terminate(ev->cid,ev->did);
1130 set_remote_ua(op,ev->response);
1132 sdp=eXosip_get_sdp_info(ev->response);
1134 op->base.remote_media=sal_media_description_new();
1135 sdp_to_media_description(sdp,op->base.remote_media);
1136 sdp_message_free(sdp);
1137 if (op->base.local_media) sdp_process(op);
1139 eXosip_call_build_ack(ev->did,&msg);
1141 ms_warning("This call has been already terminated.");
1143 eXosip_call_terminate(ev->cid,ev->did);
1147 contact=sal_op_get_contact(op);
1149 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1150 osip_message_set_contact(msg,contact);
1152 if (op->sdp_answer){
1153 set_sdp(msg,op->sdp_answer);
1154 sdp_message_free(op->sdp_answer);
1155 op->sdp_answer=NULL;
1157 eXosip_call_send_ack(ev->did,msg);
1158 sal->callbacks.call_accepted(op);
1161 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1163 SalOp *op=find_op(sal,ev);
1165 ms_warning("Call terminated for already closed call ?");
1169 osip_from_to_str(ev->request->from,&from);
1171 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1172 if (from) osip_free(from);
1173 op->terminated=TRUE;
1176 static void call_released(Sal *sal, eXosip_event_t *ev){
1177 SalOp *op=find_op(sal,ev);
1179 ms_warning("No op associated to this call_released()");
1182 if (!op->terminated){
1183 /* no response received so far */
1184 call_failure(sal,ev);
1186 sal->callbacks.call_released(op);
1189 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1190 const char *prx_realm=NULL,*www_realm=NULL;
1191 osip_proxy_authenticate_t *prx_auth;
1192 osip_www_authenticate_t *www_auth;
1194 *username=osip_uri_get_username(resp->from->url);
1195 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1196 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1198 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1200 www_realm=osip_www_authenticate_get_realm(www_auth);
1204 }else if (www_realm){
1212 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1213 osip_authorization_t *auth=NULL;
1214 osip_proxy_authorization_t *prx_auth=NULL;
1216 *username=osip_uri_get_username(msg->from->url);
1217 osip_message_get_authorization(msg, 0, &auth);
1219 *realm=osip_authorization_get_realm(auth);
1222 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1224 *realm=osip_proxy_authorization_get_realm(prx_auth);
1230 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1231 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1232 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1236 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1237 if (op->pending_auth){
1238 return get_auth_data(op->pending_auth,realm,username);
1243 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1245 const char *username,*realm;
1248 ms_warning("No operation associated with this authentication !");
1251 if (get_auth_data(ev,&realm,&username)==0){
1252 if (op->pending_auth!=NULL){
1253 eXosip_event_free(op->pending_auth);
1254 op->pending_auth=ev;
1256 op->pending_auth=ev;
1257 sal_add_pending_auth(sal,op);
1260 sal->callbacks.auth_requested(op,realm,username);
1266 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1268 const char *username,*realm;
1271 ms_warning("No operation associated with this authentication_ok!");
1274 if (op->pending_auth){
1275 eXosip_event_free(op->pending_auth);
1276 sal_remove_pending_auth(sal,op);
1277 op->pending_auth=NULL;
1279 if (get_auth_data(ev,&realm,&username)==0){
1280 sal->callbacks.auth_success(op,realm,username);
1284 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1287 char* computedReason=NULL;
1288 const char *reason=NULL;
1289 SalError error=SalErrorUnknown;
1290 SalReason sr=SalReasonUnknown;
1293 op=(SalOp*)find_op(sal,ev);
1296 ms_warning("Call failure reported for a closed call, ignored.");
1301 code=osip_message_get_status_code(ev->response);
1302 reason=osip_message_get_reason_phrase(ev->response);
1303 osip_header_t *h=NULL;
1304 if (!osip_message_header_get_byname( ev->response
1308 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1309 reason = computedReason;
1317 return process_authentication(sal,ev);
1320 error=SalErrorUnknown;
1323 error=SalErrorFailure;
1324 sr=SalReasonNotFound;
1327 error=SalErrorFailure;
1331 eXosip_default_action(ev);
1335 error=SalErrorFailure;
1336 sr=SalReasonTemporarilyUnavailable;
1338 error=SalErrorFailure;
1344 error=SalErrorFailure;
1345 sr=SalReasonDoNotDisturb;
1348 error=SalErrorFailure;
1349 sr=SalReasonDeclined;
1353 error=SalErrorFailure;
1354 sr=SalReasonUnknown;
1355 }else error=SalErrorNoResponse;
1357 op->terminated=TRUE;
1358 sal->callbacks.call_failure(op,error,sr,reason,code);
1359 if (computedReason != NULL){
1360 ms_free(computedReason);
1365 /* Request remote side to send us VFU */
1366 void sal_call_send_vfu_request(SalOp *h){
1367 osip_message_t *msg=NULL;
1369 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1373 " <picture_fast_update></picture_fast_update>"
1381 eXosip_call_build_info(h->did,&msg);
1383 osip_message_set_body(msg,info_body,strlen(info_body));
1384 osip_message_set_content_type(msg,"application/media_control+xml");
1385 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1386 osip_message_set_content_length(msg,clen);
1387 eXosip_call_send_request(h->did,msg);
1388 ms_message("Sending VFU request !");
1393 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1394 SalOp *op=find_op(sal,ev);
1395 osip_body_t *body=NULL;
1398 ms_warning("media control xml received without operation context!");
1402 osip_message_get_body(ev->request,0,&body);
1403 if (body && body->body!=NULL &&
1404 strstr(body->body,"picture_fast_update")){
1405 osip_message_t *ans=NULL;
1406 ms_message("Receiving VFU request !");
1407 if (sal->callbacks.vfu_request){
1408 sal->callbacks.vfu_request(op);
1409 eXosip_call_build_answer(ev->tid,200,&ans);
1411 eXosip_call_send_answer(ev->tid,200,ans);
1415 /*in all other cases we must say it is not implemented.*/
1417 osip_message_t *ans=NULL;
1419 eXosip_call_build_answer(ev->tid,501,&ans);
1421 eXosip_call_send_answer(ev->tid,501,ans);
1426 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1427 SalOp *op=find_op(sal,ev);
1428 osip_body_t *body=NULL;
1431 ms_warning("media dtmf relay received without operation context!");
1435 osip_message_get_body(ev->request,0,&body);
1436 if (body && body->body!=NULL){
1437 osip_message_t *ans=NULL;
1438 const char *name=strstr(body->body,"Signal");
1439 if (name==NULL) name=strstr(body->body,"signal");
1441 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1444 name+=strlen("signal");
1445 if (sscanf(name," = %1s",tmp)==1){
1446 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1447 if (sal->callbacks.dtmf_received != NULL)
1448 sal->callbacks.dtmf_received(op, tmp[0]);
1452 eXosip_call_build_answer(ev->tid,200,&ans);
1454 eXosip_call_send_answer(ev->tid,200,ans);
1459 static void fill_options_answer(osip_message_t *options){
1460 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1461 osip_message_set_accept(options,"application/sdp");
1464 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1465 osip_header_t *h=NULL;
1466 osip_message_t *ans=NULL;
1467 ms_message("Receiving REFER request !");
1468 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1471 osip_from_t *from=NULL;
1473 osip_from_init(&from);
1475 if (osip_from_parse(from,h->hvalue)==0){
1477 osip_uri_header_t *uh=NULL;
1478 osip_header_t *referred_by=NULL;
1479 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1480 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1481 ms_message("Found replaces in Refer-To");
1483 ms_free(op->replaces);
1485 op->replaces=ms_strdup(uh->gvalue);
1487 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1488 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1489 if (op->referred_by)
1490 ms_free(op->referred_by);
1491 op->referred_by=ms_strdup(referred_by->hvalue);
1494 osip_uri_header_freelist(&from->url->url_headers);
1495 osip_from_to_str(from,&tmp);
1496 sal->callbacks.refer_received(sal,op,tmp);
1498 osip_from_free(from);
1501 eXosip_call_build_answer(ev->tid,202,&ans);
1503 eXosip_call_send_answer(ev->tid,202,ans);
1508 ms_warning("cannot do anything with the refer without destination\n");
1512 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1513 osip_message_t *ans=NULL;
1515 if (MSG_IS_INFO(ev->request)){
1516 osip_content_type_t *ct;
1517 ct=osip_message_get_content_type(ev->request);
1518 if (ct && ct->subtype){
1519 if (strcmp(ct->subtype,"media_control+xml")==0)
1520 process_media_control_xml(sal,ev);
1521 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1522 process_dtmf_relay(sal,ev);
1524 ms_message("Unhandled SIP INFO.");
1525 /*send an "Not implemented" answer*/
1527 eXosip_call_build_answer(ev->tid,501,&ans);
1529 eXosip_call_send_answer(ev->tid,501,ans);
1533 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1535 eXosip_call_build_answer(ev->tid,200,&ans);
1537 eXosip_call_send_answer(ev->tid,200,ans);
1540 }else if(MSG_IS_MESSAGE(ev->request)){
1541 /* SIP messages could be received into call */
1542 text_received(sal, ev);
1544 eXosip_call_build_answer(ev->tid,200,&ans);
1546 eXosip_call_send_answer(ev->tid,200,ans);
1548 }else if(MSG_IS_REFER(ev->request)){
1549 SalOp *op=find_op(sal,ev);
1551 ms_message("Receiving REFER request !");
1552 process_refer(sal,op,ev);
1553 }else if(MSG_IS_NOTIFY(ev->request)){
1554 osip_header_t *h=NULL;
1556 SalOp *op=find_op(sal,ev);
1558 ms_message("Receiving NOTIFY request !");
1559 osip_from_to_str(ev->request->from,&from);
1560 osip_message_header_get_byname(ev->request,"Event",0,&h);
1562 sal->callbacks.notify(op,from,h->hvalue);
1563 /*answer that we received the notify*/
1565 eXosip_call_build_answer(ev->tid,200,&ans);
1567 eXosip_call_send_answer(ev->tid,200,ans);
1570 }else if (MSG_IS_OPTIONS(ev->request)){
1572 eXosip_call_build_answer(ev->tid,200,&ans);
1574 fill_options_answer(ans);
1575 eXosip_call_send_answer(ev->tid,200,ans);
1579 }else ms_warning("call_message_new: No request ?");
1582 static void inc_update(Sal *sal, eXosip_event_t *ev){
1583 osip_message_t *msg=NULL;
1584 ms_message("Processing incoming UPDATE");
1586 eXosip_message_build_answer(ev->tid,200,&msg);
1588 eXosip_message_send_answer(ev->tid,200,msg);
1592 static bool_t comes_from_local_if(osip_message_t *msg){
1593 osip_via_t *via=NULL;
1594 osip_message_get_via(msg,0,&via);
1597 host=osip_via_get_host(via);
1598 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1599 osip_generic_param_t *param=NULL;
1600 osip_via_param_get_byname(via,"received",¶m);
1601 if (param==NULL) return TRUE;
1602 if (param->gvalue &&
1603 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1611 static void text_received(Sal *sal, eXosip_event_t *ev){
1612 osip_body_t *body=NULL;
1613 char *from=NULL,*msg;
1615 osip_message_get_body(ev->request,0,&body);
1617 ms_error("Could not get text message from SIP body");
1621 osip_from_to_str(ev->request->from,&from);
1622 sal->callbacks.text_received(sal,from,msg);
1628 static void other_request(Sal *sal, eXosip_event_t *ev){
1629 ms_message("in other_request");
1630 if (ev->request==NULL) return;
1631 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1632 text_received(sal,ev);
1633 eXosip_message_send_answer(ev->tid,200,NULL);
1634 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1635 osip_message_t *options=NULL;
1636 eXosip_options_build_answer(ev->tid,200,&options);
1637 fill_options_answer(options);
1638 eXosip_options_send_answer(ev->tid,200,options);
1639 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1640 ms_message("Receiving REFER request !");
1641 if (comes_from_local_if(ev->request)) {
1642 process_refer(sal,NULL,ev);
1643 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1644 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1649 osip_message_to_str(ev->request,&tmp,&msglen);
1651 ms_message("Unsupported request received:\n%s",tmp);
1654 /*answer with a 501 Not implemented*/
1655 eXosip_message_send_answer(ev->tid,501,NULL);
1659 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1660 osip_via_t *via=NULL;
1661 osip_message_get_via(msg,0,&via);
1663 osip_free(via->port);
1664 via->port=osip_strdup(port);
1665 osip_free(via->host);
1666 via->host=osip_strdup(ip);
1671 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer) {
1672 osip_contact_t *ctt=NULL;
1673 const char *received;
1675 SalTransport transport;
1678 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1679 osip_message_get_contact(request,0,&ctt);
1681 ms_warning("fix_message_contact(): no contact to update");
1684 if (ctt->url->host!=NULL){
1685 osip_free(ctt->url->host);
1687 ctt->url->host=osip_strdup(received);
1688 if (ctt->url->port!=NULL){
1689 osip_free(ctt->url->port);
1691 snprintf(port,sizeof(port),"%i",rport);
1692 ctt->url->port=osip_strdup(port);
1693 if (op->masquerade_via) masquerade_via(request,received,port);
1695 if (transport != SalTransportUDP) {
1696 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1701 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1702 osip_contact_t *ctt=NULL;
1703 SalAddress* ori_contact_address=NULL;
1704 const char *received;
1706 SalTransport transport;
1708 osip_message_t *msg=NULL;
1709 Sal* sal=op->base.root;
1711 if (sal->double_reg==FALSE ) return FALSE;
1713 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1714 osip_message_get_contact(orig_request,0,&ctt);
1715 osip_contact_to_str(ctt,&tmp);
1716 ori_contact_address = sal_address_new(tmp);
1718 /*check if contact is up to date*/
1719 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1720 && sal_address_get_port_int(ori_contact_address) == rport
1721 && sal_address_get_transport(ori_contact_address) == transport) {
1722 ms_message("Register has up to date contact, doing nothing.");
1724 sal_address_destroy(ori_contact_address);
1726 } else ms_message("contact do not match, need to update the register (%s with %s:%i;transport=%s)"
1730 ,sal_transport_to_string(transport));
1732 sal_address_destroy(ori_contact_address);
1734 if (transport == SalTransportUDP) {
1736 eXosip_register_build_register(op->rid,op->expires,&msg);
1739 ms_warning("Fail to create a contact updated register.");
1742 if (fix_message_contact(op,msg,last_answer)) {
1743 eXosip_register_send_register(op->rid,msg);
1745 ms_message("Resending new register with updated contact");
1748 ms_warning("Fail to send updated register.");
1755 update_contact_from_response(op,last_answer);
1759 static void registration_success(Sal *sal, eXosip_event_t *ev){
1760 SalOp *op=sal_find_register(sal,ev->rid);
1761 osip_header_t *h=NULL;
1764 ms_error("Receiving register response for unknown operation");
1767 osip_message_get_expires(ev->request,0,&h);
1768 if (h!=NULL && atoi(h->hvalue)!=0){
1770 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1771 sal->callbacks.register_success(op,registered);
1774 sal->callbacks.register_success(op,FALSE);
1778 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1780 const char *reason=NULL;
1781 SalOp *op=sal_find_register(sal,ev->rid);
1782 SalReason sr=SalReasonUnknown;
1783 SalError se=SalErrorUnknown;
1786 ms_error("Receiving register failure for unknown operation");
1790 status_code=osip_message_get_status_code(ev->response);
1791 reason=osip_message_get_reason_phrase(ev->response);
1793 switch(status_code){
1796 return process_authentication(sal,ev);
1798 case 423: /*interval too brief*/
1799 {/*retry with greater interval */
1800 osip_header_t *h=NULL;
1801 osip_message_t *msg=NULL;
1802 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1803 if (h && h->hvalue && h->hvalue[0]!='\0'){
1804 int val=atoi(h->hvalue);
1805 if (val>op->expires)
1807 }else op->expires*=2;
1809 eXosip_register_build_register(op->rid,op->expires,&msg);
1810 eXosip_register_send_register(op->rid,msg);
1814 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1815 in vias, such as ekiga.net
1816 On the opposite, freephonie.net bugs when via are masqueraded.
1818 op->masquerade_via=TRUE;
1820 /* if contact is up to date, process the failure, otherwise resend a new register with
1821 updated contact first, just in case the faillure is due to incorrect contact */
1822 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1823 return TRUE; /*we are retrying with an updated contact*/
1824 if (status_code==403){
1826 sr=SalReasonForbidden;
1827 }else if (status_code==0){
1828 se=SalErrorNoResponse;
1830 sal->callbacks.register_failure(op,se,sr,reason);
1835 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1836 SalOp *op=find_op(sal,ev);
1839 ms_warning("other_request_reply(): Receiving response to unknown request.");
1843 update_contact_from_response(op,ev->response);
1844 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
1845 sal->callbacks.ping_reply(op);
1849 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
1850 ms_message("linphone process event get a message %d\n",ev->type);
1852 case EXOSIP_CALL_ANSWERED:
1853 ms_message("CALL_ANSWERED\n");
1854 call_accepted(sal,ev);
1855 authentication_ok(sal,ev);
1857 case EXOSIP_CALL_CLOSED:
1858 case EXOSIP_CALL_CANCELLED:
1859 ms_message("CALL_CLOSED or CANCELLED\n");
1860 call_terminated(sal,ev);
1862 case EXOSIP_CALL_TIMEOUT:
1863 case EXOSIP_CALL_NOANSWER:
1864 ms_message("CALL_TIMEOUT or NOANSWER\n");
1865 return call_failure(sal,ev);
1867 case EXOSIP_CALL_REQUESTFAILURE:
1868 case EXOSIP_CALL_GLOBALFAILURE:
1869 case EXOSIP_CALL_SERVERFAILURE:
1870 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
1871 return call_failure(sal,ev);
1873 case EXOSIP_CALL_RELEASED:
1874 ms_message("CALL_RELEASED\n");
1875 call_released(sal, ev);
1877 case EXOSIP_CALL_INVITE:
1878 ms_message("CALL_NEW\n");
1879 inc_new_call(sal,ev);
1881 case EXOSIP_CALL_REINVITE:
1882 handle_reinvite(sal,ev);
1884 case EXOSIP_CALL_ACK:
1885 ms_message("CALL_ACK");
1888 case EXOSIP_CALL_REDIRECTED:
1889 ms_message("CALL_REDIRECTED");
1890 eXosip_default_action(ev);
1892 case EXOSIP_CALL_PROCEEDING:
1893 ms_message("CALL_PROCEEDING");
1894 call_proceeding(sal,ev);
1896 case EXOSIP_CALL_RINGING:
1897 ms_message("CALL_RINGING");
1898 call_ringing(sal,ev);
1900 case EXOSIP_CALL_MESSAGE_NEW:
1901 ms_message("EXOSIP_CALL_MESSAGE_NEW");
1902 call_message_new(sal,ev);
1904 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
1906 (ev->response->status_code==407 || ev->response->status_code==401)){
1907 return process_authentication(sal,ev);
1910 case EXOSIP_IN_SUBSCRIPTION_NEW:
1911 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
1912 sal_exosip_subscription_recv(sal,ev);
1914 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
1915 ms_message("CALL_SUBSCRIPTION_NEW ");
1916 sal_exosip_in_subscription_closed(sal,ev);
1918 case EXOSIP_SUBSCRIPTION_UPDATE:
1919 ms_message("CALL_SUBSCRIPTION_UPDATE");
1921 case EXOSIP_SUBSCRIPTION_NOTIFY:
1922 ms_message("CALL_SUBSCRIPTION_NOTIFY");
1923 sal_exosip_notify_recv(sal,ev);
1925 case EXOSIP_SUBSCRIPTION_ANSWERED:
1926 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
1927 sal_exosip_subscription_answered(sal,ev);
1929 case EXOSIP_SUBSCRIPTION_CLOSED:
1930 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
1931 sal_exosip_subscription_closed(sal,ev);
1933 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
1934 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
1935 return process_authentication(sal,ev);
1937 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
1938 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
1939 sal_exosip_subscription_closed(sal,ev);
1941 case EXOSIP_REGISTRATION_FAILURE:
1942 ms_message("REGISTRATION_FAILURE\n");
1943 return registration_failure(sal,ev);
1945 case EXOSIP_REGISTRATION_SUCCESS:
1946 authentication_ok(sal,ev);
1947 registration_success(sal,ev);
1949 case EXOSIP_MESSAGE_NEW:
1950 other_request(sal,ev);
1952 case EXOSIP_MESSAGE_PROCEEDING:
1953 case EXOSIP_MESSAGE_ANSWERED:
1954 case EXOSIP_MESSAGE_REDIRECTED:
1955 case EXOSIP_MESSAGE_SERVERFAILURE:
1956 case EXOSIP_MESSAGE_GLOBALFAILURE:
1957 other_request_reply(sal,ev);
1959 case EXOSIP_MESSAGE_REQUESTFAILURE:
1960 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
1962 switch (ev->response->status_code) {
1965 return process_authentication(sal,ev);
1967 eXosip_automatic_action ();
1972 other_request_reply(sal,ev);
1975 ms_message("Unhandled exosip event ! %i",ev->type);
1981 int sal_iterate(Sal *sal){
1983 while((ev=eXosip_event_wait(0,0))!=NULL){
1984 if (process_event(sal,ev))
1985 eXosip_event_free(ev);
1988 eXosip_automatic_refresh();
1993 static void register_set_contact(osip_message_t *msg, const char *contact){
1994 osip_uri_param_t *param = NULL;
1995 osip_contact_t *ct=NULL;
1997 /*we get the line parameter choosed by exosip, and add it to our own contact*/
1998 osip_message_get_contact(msg,0,&ct);
2000 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2001 if (param && param->gvalue)
2002 line=osip_strdup(param->gvalue);
2004 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2005 osip_message_set_contact(msg,contact);
2006 osip_message_get_contact(msg,0,&ct);
2007 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2010 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2011 osip_message_t *msg;
2012 const char *contact=sal_op_get_contact(h);
2014 sal_op_set_route(h,proxy);
2017 h->rid=eXosip_register_build_initial_register(from,proxy,NULL,expires,&msg);
2019 if (contact) register_set_contact(msg,contact);
2020 sal_add_register(h->base.root,h);
2022 ms_error("Could not build initial register.");
2028 eXosip_register_build_register(h->rid,expires,&msg);
2030 eXosip_register_send_register(h->rid,msg);
2036 int sal_register_refresh(SalOp *op, int expires){
2037 osip_message_t *msg=NULL;
2038 const char *contact=sal_op_get_contact(op);
2041 ms_error("Unexistant registration context, not possible to refresh.");
2045 eXosip_register_build_register(op->rid,expires,&msg);
2047 if (contact) register_set_contact(msg,contact);
2048 eXosip_register_send_register(op->rid,msg);
2049 }else ms_error("Could not build REGISTER refresh message.");
2055 int sal_unregister(SalOp *h){
2056 osip_message_t *msg=NULL;
2058 eXosip_register_build_register(h->rid,0,&msg);
2059 if (msg) eXosip_register_send_register(h->rid,msg);
2060 else ms_warning("Could not build unREGISTER !");
2065 SalAddress * sal_address_new(const char *uri){
2067 osip_from_init(&from);
2069 // Remove front spaces
2070 while (uri[0]==' ') {
2074 if (osip_from_parse(from,uri)!=0){
2075 osip_from_free(from);
2078 if (from->displayname!=NULL && from->displayname[0]=='"'){
2079 char *unquoted=osip_strdup_without_quote(from->displayname);
2080 osip_free(from->displayname);
2081 from->displayname=unquoted;
2083 return (SalAddress*)from;
2086 SalAddress * sal_address_clone(const SalAddress *addr){
2087 osip_from_t *ret=NULL;
2088 osip_from_clone((osip_from_t*)addr,&ret);
2089 return (SalAddress*)ret;
2092 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2094 const char *sal_address_get_scheme(const SalAddress *addr){
2095 const osip_from_t *u=(const osip_from_t*)addr;
2096 return null_if_empty(u->url->scheme);
2099 const char *sal_address_get_display_name(const SalAddress* addr){
2100 const osip_from_t *u=(const osip_from_t*)addr;
2101 return null_if_empty(u->displayname);
2104 const char *sal_address_get_username(const SalAddress *addr){
2105 const osip_from_t *u=(const osip_from_t*)addr;
2106 return null_if_empty(u->url->username);
2109 const char *sal_address_get_domain(const SalAddress *addr){
2110 const osip_from_t *u=(const osip_from_t*)addr;
2111 return null_if_empty(u->url->host);
2114 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2115 osip_from_t *u=(osip_from_t*)addr;
2116 if (u->displayname!=NULL){
2117 osip_free(u->displayname);
2118 u->displayname=NULL;
2120 if (display_name!=NULL && display_name[0]!='\0'){
2121 u->displayname=osip_strdup(display_name);
2125 void sal_address_set_username(SalAddress *addr, const char *username){
2126 osip_from_t *uri=(osip_from_t*)addr;
2127 if (uri->url->username!=NULL){
2128 osip_free(uri->url->username);
2129 uri->url->username=NULL;
2132 uri->url->username=osip_strdup(username);
2135 void sal_address_set_domain(SalAddress *addr, const char *host){
2136 osip_from_t *uri=(osip_from_t*)addr;
2137 if (uri->url->host!=NULL){
2138 osip_free(uri->url->host);
2139 uri->url->host=NULL;
2142 uri->url->host=osip_strdup(host);
2145 void sal_address_set_port(SalAddress *addr, const char *port){
2146 osip_from_t *uri=(osip_from_t*)addr;
2147 if (uri->url->port!=NULL){
2148 osip_free(uri->url->port);
2149 uri->url->port=NULL;
2152 uri->url->port=osip_strdup(port);
2155 void sal_address_set_port_int(SalAddress *uri, int port){
2158 /*this is the default, special case to leave the port field blank*/
2159 sal_address_set_port(uri,NULL);
2162 snprintf(tmp,sizeof(tmp),"%i",port);
2163 sal_address_set_port(uri,tmp);
2166 void sal_address_clean(SalAddress *addr){
2167 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2168 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2171 char *sal_address_as_string(const SalAddress *u){
2173 osip_from_t *from=(osip_from_t *)u;
2174 char *old_displayname=NULL;
2175 /* hack to force use of quotes around the displayname*/
2176 if (from->displayname!=NULL
2177 && from->displayname[0]!='"'){
2178 old_displayname=from->displayname;
2179 from->displayname=osip_enquote(from->displayname);
2181 osip_from_to_str(from,&tmp);
2182 if (old_displayname!=NULL){
2183 ms_free(from->displayname);
2184 from->displayname=old_displayname;
2191 char *sal_address_as_string_uri_only(const SalAddress *u){
2192 char *tmp=NULL,*ret;
2193 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2198 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2199 osip_uri_param_t *param=NULL;
2200 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2202 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),ms_strdup(value));
2204 osip_free(param->gvalue);
2205 param->gvalue=osip_strdup(value);
2210 void sal_address_destroy(SalAddress *u){
2211 osip_from_free((osip_from_t*)u);
2214 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2215 ctx->keepalive_period=value;
2216 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2218 unsigned int sal_get_keepalive_period(Sal *ctx) {
2219 return ctx->keepalive_period;
2222 const char * sal_address_get_port(const SalAddress *addr) {
2223 const osip_from_t *u=(const osip_from_t*)addr;
2224 return null_if_empty(u->url->port);
2227 int sal_address_get_port_int(const SalAddress *uri) {
2228 const char* port = sal_address_get_port(uri);
2235 SalTransport sal_address_get_transport(const SalAddress* addr) {
2236 const osip_from_t *u=(const osip_from_t*)addr;
2237 osip_uri_param_t *transport_param=NULL;
2238 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2239 if (transport_param == NULL){
2240 return SalTransportUDP;
2242 return sal_transport_parse(transport_param->gvalue);
2245 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2246 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2249 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2250 int sal_call_update(SalOp *h, const char *subject){
2252 osip_message_t *reinvite=NULL;
2255 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2260 osip_message_set_subject(reinvite,subject);
2261 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2262 if (h->base.root->session_expires!=0){
2263 osip_message_set_header(reinvite, "Session-expires", "200");
2264 osip_message_set_supported(reinvite, "timer");
2266 if (h->base.local_media){
2267 h->sdp_offering=TRUE;
2268 set_sdp_from_desc(reinvite,h->base.local_media);
2269 }else h->sdp_offering=FALSE;
2271 err = eXosip_call_send_request(h->did, reinvite);
2275 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2276 ctx->reuse_authorization=value;