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"
24 #include "offeranswer.h"
27 // Necessary to make it linked
28 static void for_linker() { eXosip_transport_hook_register(NULL); }
30 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
32 static void text_received(Sal *sal, eXosip_event_t *ev);
34 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
35 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact);
36 static void update_contact_from_response(SalOp *op, osip_message_t *response);
38 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
40 while(!osip_list_eol(l,0)) {
41 data=osip_list_get(l,0);
42 osip_list_remove(l,0);
43 if (data) freefunc(data);
47 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
48 if (eXosip_guess_localip(address_family,ip,iplen)<0){
49 /*default to something */
50 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
51 ms_error("Could not find default routable ip address !");
55 static SalOp * sal_find_call(Sal *sal, int cid){
58 for(elem=sal->calls;elem!=NULL;elem=elem->next){
59 op=(SalOp*)elem->data;
60 if (op->cid==cid) return op;
65 static void sal_add_call(Sal *sal, SalOp *op){
66 sal->calls=ms_list_append(sal->calls,op);
69 static void sal_remove_call(Sal *sal, SalOp *op){
70 sal->calls=ms_list_remove(sal->calls, op);
73 static SalOp * sal_find_register(Sal *sal, int rid){
76 for(elem=sal->registers;elem!=NULL;elem=elem->next){
77 op=(SalOp*)elem->data;
78 if (op->rid==rid) return op;
83 static void sal_add_register(Sal *sal, SalOp *op){
84 sal->registers=ms_list_append(sal->registers,op);
87 static void sal_remove_register(Sal *sal, int rid){
90 for(elem=sal->registers;elem!=NULL;elem=elem->next){
91 op=(SalOp*)elem->data;
93 sal->registers=ms_list_remove_link(sal->registers,elem);
99 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
102 osip_call_id_t *callid=osip_message_get_call_id(message);
104 ms_error("There is no call-id in this message !");
107 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
108 op=(SalOp*)elem->data;
109 if (osip_call_id_match(callid,op->call_id)==0) return op;
114 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
115 osip_call_id_t *callid=osip_message_get_call_id(request);
117 ms_error("There is no call id in the request !");
120 osip_call_id_clone(callid,&op->call_id);
121 sal->other_transactions=ms_list_append(sal->other_transactions,op);
124 static void sal_remove_other(Sal *sal, SalOp *op){
125 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
129 static void sal_add_pending_auth(Sal *sal, SalOp *op){
130 sal->pending_auths=ms_list_append(sal->pending_auths,op);
134 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
135 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
138 void sal_exosip_fix_route(SalOp *op){
139 if (sal_op_get_route(op)!=NULL){
140 osip_route_t *rt=NULL;
141 osip_uri_param_t *lr_param=NULL;
143 osip_route_init(&rt);
144 if (osip_route_parse(rt,sal_op_get_route(op))<0){
145 ms_warning("Bad route %s!",sal_op_get_route(op));
146 sal_op_set_route(op,NULL);
148 /* check if the lr parameter is set , if not add it */
149 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
152 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
153 osip_route_to_str(rt,&tmproute);
154 sal_op_set_route(op,tmproute);
162 SalOp * sal_op_new(Sal *sal){
163 SalOp *op=ms_new0(SalOp,1);
164 __sal_op_init(op,sal);
165 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
167 op->supports_session_timers=FALSE;
168 op->sdp_offering=TRUE;
169 op->pending_auth=NULL;
174 op->referred_by=NULL;
175 op->masquerade_via=FALSE;
176 op->auto_answer_asked=FALSE;
178 op->terminated=FALSE;
182 bool_t sal_call_autoanswer_asked(SalOp *op)
184 return op->auto_answer_asked;
187 void sal_op_release(SalOp *op){
189 sdp_message_free(op->sdp_answer);
190 if (op->pending_auth)
191 eXosip_event_free(op->pending_auth);
193 sal_remove_register(op->base.root,op->rid);
194 eXosip_register_remove(op->rid);
197 ms_message("Cleaning cid %i",op->cid);
198 sal_remove_call(op->base.root,op);
201 sal_remove_out_subscribe(op->base.root,op);
204 sal_remove_in_subscribe(op->base.root,op);
206 osip_call_id_free(op->call_id);
209 if (op->pending_auth){
210 sal_remove_pending_auth(op->base.root,op);
213 sal_media_description_unref(op->result);
215 sal_remove_other(op->base.root,op);
216 osip_call_id_free(op->call_id);
219 ms_free(op->replaces);
221 if (op->referred_by){
222 ms_free(op->referred_by);
225 sal_auth_info_delete(op->auth_info);
230 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
231 int ortp_level=ORTP_DEBUG;
237 ortp_level=ORTP_MESSAGE;
240 ortp_level=ORTP_WARNING;
244 ortp_level=ORTP_ERROR;
247 ortp_level=ORTP_FATAL;
249 case END_TRACE_LEVEL:
252 if (ortp_log_level_enabled(level)){
253 int len=strlen(chfr);
254 char *chfrdup=ortp_strdup(chfr);
255 /*need to remove endline*/
257 if (chfrdup[len-1]=='\n')
259 if (chfrdup[len-2]=='\r')
262 ortp_logv(ortp_level,chfrdup,ap);
269 static bool_t firsttime=TRUE;
272 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
277 sal->keepalive_period=30;
278 sal->double_reg=TRUE;
279 sal->use_rports=TRUE;
281 sal->reuse_authorization=FALSE;
283 sal->verify_server_certs=TRUE;
284 sal->verify_server_cn=TRUE;
285 sal->expire_old_contact=FALSE;
286 sal->add_dates=FALSE;
291 void sal_uninit(Sal* sal){
294 ms_free(sal->rootCa);
298 void sal_set_user_pointer(Sal *sal, void *user_data){
302 void *sal_get_user_pointer(const Sal *sal){
306 static void unimplemented_stub(){
307 ms_warning("Unimplemented SAL callback");
310 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
311 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
312 if (ctx->callbacks.call_received==NULL)
313 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
314 if (ctx->callbacks.call_ringing==NULL)
315 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
316 if (ctx->callbacks.call_accepted==NULL)
317 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
318 if (ctx->callbacks.call_failure==NULL)
319 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
320 if (ctx->callbacks.call_terminated==NULL)
321 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
322 if (ctx->callbacks.call_released==NULL)
323 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
324 if (ctx->callbacks.call_updating==NULL)
325 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
326 if (ctx->callbacks.auth_requested==NULL)
327 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
328 if (ctx->callbacks.auth_success==NULL)
329 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
330 if (ctx->callbacks.register_success==NULL)
331 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
332 if (ctx->callbacks.register_failure==NULL)
333 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
334 if (ctx->callbacks.dtmf_received==NULL)
335 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
336 if (ctx->callbacks.notify==NULL)
337 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
338 if (ctx->callbacks.notify_presence==NULL)
339 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
340 if (ctx->callbacks.subscribe_received==NULL)
341 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
342 if (ctx->callbacks.text_received==NULL)
343 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
344 if (ctx->callbacks.ping_reply==NULL)
345 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
348 int sal_unlisten_ports(Sal *ctx){
357 int sal_reset_transports(Sal *ctx){
358 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
360 ms_message("Exosip transports reset.");
361 eXosip_reset_transports();
365 ms_warning("sal_reset_transports() not implemented in this version.");
371 static void set_tls_options(Sal *ctx){
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 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
379 eXosip_tls_verify_certificate(ctx->verify_server_certs);
381 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
382 eXosip_tls_verify_cn(ctx->verify_server_cn);
386 void sal_set_dscp(Sal *ctx, int dscp){
388 #ifdef HAVE_EXOSIP_DSCP
390 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
394 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
397 int proto=IPPROTO_UDP;
398 int keepalive = ctx->keepalive_period;
402 case SalTransportUDP:
404 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
406 case SalTransportTCP:
407 case SalTransportTLS:
409 if (!ctx->tcp_tls_keepalive) keepalive=-1;
410 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
411 set_tls_options(ctx);
414 ms_warning("unexpected proto, using datagram");
416 /*see if it looks like an IPv6 address*/
417 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
418 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
419 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
420 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
421 sal_set_dscp(ctx,ctx->dscp);
422 sal_use_dates(ctx,ctx->add_dates);
424 ipv6=strchr(addr,':')!=NULL;
425 eXosip_enable_ipv6(ipv6);
427 if (is_secure && tr == SalTransportUDP){
428 ms_fatal("SIP over DTLS is not supported yet.");
431 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
436 ortp_socket_t sal_get_socket(Sal *ctx){
437 #ifdef HAVE_EXOSIP_GET_SOCKET
438 return eXosip_get_socket(IPPROTO_UDP);
440 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
445 void sal_set_user_agent(Sal *ctx, const char *user_agent){
446 eXosip_set_user_agent(user_agent);
449 void sal_use_session_timers(Sal *ctx, int expires){
450 ctx->session_expires=expires;
453 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
454 ctx->one_matching_codec=one_matching_codec;
457 MSList *sal_get_pending_auths(Sal *sal){
458 return ms_list_copy(sal->pending_auths);
461 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
462 ctx->double_reg=enabled;
465 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
466 ctx->expire_old_contact=enabled;
469 void sal_use_dates(Sal *ctx, bool_t enabled){
470 ctx->add_dates=enabled;
471 #ifdef EXOSIP_OPT_REGISTER_WITH_DATE
474 eXosip_set_option(EXOSIP_OPT_REGISTER_WITH_DATE,&tmp);
477 if (enabled) ms_warning("Exosip does not support EXOSIP_OPT_REGISTER_WITH_DATE option.");
481 void sal_use_rport(Sal *ctx, bool_t use_rports){
482 ctx->use_rports=use_rports;
484 void sal_use_101(Sal *ctx, bool_t use_101){
485 ctx->use_101=use_101;
488 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
490 ms_free(ctx->rootCa);
491 ctx->rootCa = ms_strdup(rootCa);
492 set_tls_options(ctx);
495 const char *sal_get_root_ca(Sal* ctx) {
499 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
500 ctx->verify_server_certs=verify;
501 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
502 eXosip_tls_verify_certificate(verify);
506 void sal_verify_server_cn(Sal *ctx, bool_t verify){
507 ctx->verify_server_cn=verify;
508 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
509 eXosip_tls_verify_cn(verify);
513 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
514 osip_via_t *via=NULL;
515 osip_generic_param_t *param=NULL;
516 const char *rport=NULL;
520 osip_message_get_via(msg,0,&via);
522 ms_warning("extract_received_rport(): no via.");
526 *transport = sal_transport_parse(via->protocol);
528 if (via->port && via->port[0]!='\0')
529 *rportval=atoi(via->port);
531 osip_via_param_get_byname(via,"rport",¶m);
534 if (rport && rport[0]!='\0') *rportval=atoi(rport);
538 osip_via_param_get_byname(via,"received",¶m);
539 if (param) *received=param->gvalue;
541 if (rport==NULL && *received==NULL){
542 ms_warning("extract_received_rport(): no rport and no received parameters.");
548 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
552 sdp_message_to_str(msg,&sdp);
554 snprintf(clen,sizeof(clen),"%i",sdplen);
555 osip_message_set_body(sip,sdp,sdplen);
556 osip_message_set_content_type(sip,"application/sdp");
557 osip_message_set_content_length(sip,clen);
561 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
562 sdp_message_t *msg=media_description_to_sdp(desc);
564 ms_error("Fail to print sdp message !");
568 sdp_message_free(msg);
571 static void sdp_process(SalOp *h){
572 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
574 sal_media_description_unref(h->result);
576 h->result=sal_media_description_new();
577 if (h->sdp_offering){
578 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
582 sdp_message_free(h->sdp_answer);
584 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
585 h->sdp_answer=media_description_to_sdp(h->result);
586 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
587 It should contains media parameters constraint from the remote offer, not our response*/
588 strcpy(h->result->addr,h->base.remote_media->addr);
589 h->result->bandwidth=h->base.remote_media->bandwidth;
591 for(i=0;i<h->result->n_active_streams;++i){
592 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
593 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
594 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
595 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
596 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
597 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
598 if (h->result->streams[i].proto == SalProtoRtpSavp) {
599 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
606 int sal_call_is_offerer(const SalOp *h){
607 return h->sdp_offering;
610 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
612 sal_media_description_ref(desc);
613 if (h->base.local_media)
614 sal_media_description_unref(h->base.local_media);
615 h->base.local_media=desc;
616 if (h->base.remote_media){
617 /*case of an incoming call where we modify the local capabilities between the time
618 * the call is ringing and it is accepted (for example if you want to accept without video*/
619 /*reset the sdp answer so that it is computed again*/
621 sdp_message_free(h->sdp_answer);
628 int sal_call(SalOp *h, const char *from, const char *to){
631 osip_message_t *invite=NULL;
632 osip_call_id_t *callid;
633 sal_op_set_from(h,from);
635 sal_exosip_fix_route(h);
637 h->terminated = FALSE;
639 route = sal_op_get_route(h);
640 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
642 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
643 err, from, to, route);
646 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
647 if (h->base.contact){
648 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
649 osip_message_set_contact(invite,h->base.contact);
651 if (h->base.root->session_expires!=0){
652 osip_message_set_header(invite, "Session-expires", "200");
653 osip_message_set_supported(invite, "timer");
655 if (h->base.local_media){
656 h->sdp_offering=TRUE;
657 set_sdp_from_desc(invite,h->base.local_media);
658 }else h->sdp_offering=FALSE;
660 osip_message_set_header(invite,"Replaces",h->replaces);
662 osip_message_set_header(invite,"Referred-By",h->referred_by);
666 err=eXosip_call_send_initial_invite(invite);
670 ms_error("Fail to send invite ! Error code %d", err);
674 callid=osip_message_get_call_id(invite);
675 osip_call_id_to_str(callid,&tmp);
676 h->base.call_id=ms_strdup(tmp);
678 sal_add_call(h->base.root,h);
683 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
686 /*if early media send also 180 and 183 */
690 eXosip_call_build_answer(h->tid,183,&msg);
694 set_sdp(msg,h->sdp_answer);
695 sdp_message_free(h->sdp_answer);
698 eXosip_call_send_answer(h->tid,183,msg);
703 eXosip_call_send_answer(h->tid,180,NULL);
709 int sal_call_accept(SalOp * h){
711 const char *contact=sal_op_get_contact(h);
713 int err=eXosip_call_build_answer(h->tid,200,&msg);
714 if (err<0 || msg==NULL){
715 ms_error("Fail to build answer for call: err=%i",err);
718 if (h->base.root->session_expires!=0){
719 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
723 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
724 osip_message_set_contact(msg,contact);
727 if (h->base.local_media){
728 /*this is the case where we received an invite without SDP*/
729 if (h->sdp_offering) {
730 set_sdp_from_desc(msg,h->base.local_media);
732 if (h->sdp_answer==NULL) sdp_process(h);
734 set_sdp(msg,h->sdp_answer);
735 sdp_message_free(h->sdp_answer);
740 ms_error("You are accepting a call but not defined any media capabilities !");
742 eXosip_call_send_answer(h->tid,200,msg);
746 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
747 if (reason==SalReasonBusy){
749 eXosip_call_send_answer(h->tid,486,NULL);
752 else if (reason==SalReasonTemporarilyUnavailable){
754 eXosip_call_send_answer(h->tid,480,NULL);
756 }else if (reason==SalReasonDoNotDisturb){
758 eXosip_call_send_answer(h->tid,600,NULL);
760 }else if (reason==SalReasonMedia){
762 eXosip_call_send_answer(h->tid,415,NULL);
764 }else if (redirect!=NULL && reason==SalReasonRedirect){
767 if (strstr(redirect,"sip:")!=0) code=302;
770 eXosip_call_build_answer(h->tid,code,&msg);
771 osip_message_set_contact(msg,redirect);
772 eXosip_call_send_answer(h->tid,code,msg);
774 }else sal_call_terminate(h);
778 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
779 return h->base.remote_media;
782 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
783 if (h->base.local_media && h->base.remote_media && !h->result){
789 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
790 if (refered_call->replaces)
791 h->replaces=ms_strdup(refered_call->replaces);
792 if (refered_call->referred_by)
793 h->referred_by=ms_strdup(refered_call->referred_by);
797 static int send_notify_for_refer(int did, const char *sipfrag){
800 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
803 ms_warning("Could not build NOTIFY for refer.");
806 osip_message_set_content_type(msg,"message/sipfrag");
807 osip_message_set_header(msg,"Event","refer");
808 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
809 eXosip_call_send_request(did,msg);
814 /* currently only support to notify trying and 200Ok*/
815 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
818 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
820 else if (newcall->cid!=-1){
821 if (newcall->did==-1){
822 /* not yet established*/
823 if (!newcall->terminated){
825 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
828 if (!newcall->terminated){
829 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
830 /* we need previous notify transaction to complete, so buffer the request for later*/
831 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
839 int sal_ping(SalOp *op, const char *from, const char *to){
840 osip_message_t *options=NULL;
842 sal_op_set_from(op,from);
843 sal_op_set_to(op,to);
844 sal_exosip_fix_route(op);
846 eXosip_options_build_request (&options, sal_op_get_to(op),
847 sal_op_get_from(op),sal_op_get_route(op));
849 if (op->base.root->session_expires!=0){
850 osip_message_set_header(options, "Session-expires", "200");
851 osip_message_set_supported(options, "timer");
853 sal_add_other(sal_op_get_sal(op),op,options);
854 return eXosip_options_send_request(options);
859 int sal_call_refer(SalOp *h, const char *refer_to){
860 osip_message_t *msg=NULL;
863 eXosip_call_build_refer(h->did,refer_to, &msg);
864 if (msg) err=eXosip_call_send_request(h->did, msg);
870 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
871 osip_message_t *msg=NULL;
872 char referto[256]={0};
875 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
876 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
880 eXosip_call_build_refer(h->did,referto, &msg);
881 osip_message_set_header(msg,"Referred-By",h->base.from);
882 if (msg) err=eXosip_call_send_request(h->did, msg);
888 SalOp *sal_call_get_replaces(SalOp *h){
889 if (h!=NULL && h->replaces!=NULL){
892 cid=eXosip_call_find_by_replaces(h->replaces);
895 SalOp *ret=sal_find_call(h->base.root,cid);
902 int sal_call_send_dtmf(SalOp *h, char dtmf){
903 osip_message_t *msg=NULL;
908 eXosip_call_build_info(h->did,&msg);
910 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
911 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
912 osip_message_set_content_type(msg,"application/dtmf-relay");
913 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
914 osip_message_set_content_length(msg,clen);
915 eXosip_call_send_request(h->did,msg);
921 static void push_auth_to_exosip(const SalAuthInfo *info){
923 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
924 else userid=info->userid;
925 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
926 eXosip_add_authentication_info (info->username,userid,
927 info->password, NULL,info->realm);
930 * Just for symmetry ;-)
932 static void pop_auth_from_exosip() {
933 eXosip_clear_authentication_info();
936 int sal_call_terminate(SalOp *h){
938 if (h == NULL) return -1;
939 if (h->auth_info) push_auth_to_exosip(h->auth_info);
941 err=eXosip_call_terminate(h->cid,h->did);
943 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
945 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
951 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
952 bool_t terminating=FALSE;
953 if (h->pending_auth && strcmp(h->pending_auth->request->sip_method,"BYE")==0) {
956 if (h->terminated && !terminating) return;
958 if (h->pending_auth){
959 push_auth_to_exosip(info);
961 /*FIXME exosip does not take into account this update register message*/
963 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
967 update_contact_from_response(h,h->pending_auth->response);
969 eXosip_default_action(h->pending_auth);
971 ms_message("eXosip_default_action() done");
972 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
974 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
975 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
978 void sal_op_cancel_authentication(SalOp *h) {
980 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
981 } else if (h->cid >0) {
982 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
984 ms_warning("Auth failure not handled");
988 static void set_network_origin(SalOp *op, osip_message_t *req){
989 const char *received=NULL;
992 SalTransport transport;
993 if (extract_received_rport(req,&received,&rport,&transport)!=0){
994 osip_via_t *via=NULL;
996 osip_message_get_via(req,0,&via);
997 received=osip_via_get_host(via);
998 tmp=osip_via_get_port(via);
999 if (tmp) rport=atoi(tmp);
1001 if (transport != SalTransportUDP) {
1002 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
1004 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
1006 __sal_op_set_network_origin(op,origin);
1009 static void set_remote_ua(SalOp* op, osip_message_t *req){
1010 if (op->base.remote_ua==NULL){
1011 osip_header_t *h=NULL;
1012 osip_message_get_user_agent(req,0,&h);
1014 op->base.remote_ua=ms_strdup(h->hvalue);
1019 static void set_remote_contact(SalOp* op, osip_message_t *req){
1020 if (op->base.remote_contact==NULL){
1021 osip_contact_t *h=NULL;
1022 osip_message_get_contact(req,0,&h);
1025 osip_contact_to_str(h,&tmp);
1026 __sal_op_set_remote_contact(op,tmp);
1032 static void set_replaces(SalOp *op, osip_message_t *req){
1033 osip_header_t *h=NULL;
1036 ms_free(op->replaces);
1039 osip_message_header_get_byname(req,"replaces",0,&h);
1041 if (h->hvalue && h->hvalue[0]!='\0'){
1042 op->replaces=ms_strdup(h->hvalue);
1047 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1049 return sal_find_call(sal,ev->cid);
1052 return sal_find_register(sal,ev->rid);
1055 return sal_find_out_subscribe(sal,ev->sid);
1058 return sal_find_in_subscribe(sal,ev->nid);
1060 if (ev->response) return sal_find_other(sal,ev->response);
1061 else if (ev->request) return sal_find_other(sal,ev->request);
1065 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1066 SalOp *op=sal_op_new(sal);
1067 osip_from_t *from,*to;
1068 osip_call_info_t *call_info;
1070 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1072 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1074 osip_call_id_to_str(callid,&tmp);
1075 op->base.call_id=ms_strdup(tmp);
1078 set_network_origin(op,ev->request);
1079 set_remote_contact(op,ev->request);
1080 set_remote_ua(op,ev->request);
1081 set_replaces(op,ev->request);
1084 op->sdp_offering=FALSE;
1085 op->base.remote_media=sal_media_description_new();
1086 sdp_to_media_description(sdp,op->base.remote_media);
1087 sdp_message_free(sdp);
1088 }else op->sdp_offering=TRUE;
1090 from=osip_message_get_from(ev->request);
1091 to=osip_message_get_to(ev->request);
1092 osip_from_to_str(from,&tmp);
1093 sal_op_set_from(op,tmp);
1095 osip_from_to_str(to,&tmp);
1096 sal_op_set_to(op,tmp);
1099 osip_message_get_call_info(ev->request,0,&call_info);
1102 osip_call_info_to_str(call_info,&tmp);
1103 if( strstr(tmp,"answer-after=") != NULL)
1105 op->auto_answer_asked=TRUE;
1106 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1114 sal_add_call(op->base.root,op);
1115 sal->callbacks.call_received(op);
1118 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1119 SalOp *op=find_op(sal,ev);
1123 ms_warning("Reinvite for non-existing operation !");
1128 sdp=eXosip_get_sdp_info(ev->request);
1129 if (op->base.remote_media){
1130 sal_media_description_unref(op->base.remote_media);
1131 op->base.remote_media=NULL;
1134 sal_media_description_unref(op->result);
1138 op->sdp_offering=FALSE;
1139 op->base.remote_media=sal_media_description_new();
1140 sdp_to_media_description(sdp,op->base.remote_media);
1141 sdp_message_free(sdp);
1144 op->sdp_offering=TRUE;
1146 sal->callbacks.call_updating(op);
1149 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1150 SalOp *op=find_op(sal,ev);
1154 ms_warning("ack for non-existing call !");
1157 if (op->terminated) {
1158 ms_warning("ack for terminated call, ignoring");
1162 if (op->sdp_offering){
1163 sdp=eXosip_get_sdp_info(ev->ack);
1165 if (op->base.remote_media)
1166 sal_media_description_unref(op->base.remote_media);
1167 op->base.remote_media=sal_media_description_new();
1168 sdp_to_media_description(sdp,op->base.remote_media);
1170 sdp_message_free(sdp);
1176 sal->callbacks.call_ack(op);
1179 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1180 const char *received;
1182 SalTransport transport;
1183 if (extract_received_rport(response,&received,&rport,&transport)==0){
1184 const char *contact=sal_op_get_contact(op);
1186 /*no contact given yet, use from instead*/
1187 contact=sal_op_get_from(op);
1190 SalAddress *addr=sal_address_new(contact);
1192 sal_address_set_domain(addr,received);
1193 sal_address_set_port_int(addr,rport);
1194 if (transport!=SalTransportUDP)
1195 sal_address_set_transport(addr,transport);
1196 tmp=sal_address_as_string(addr);
1197 ms_message("Contact address updated to %s",tmp);
1198 sal_op_set_contact(op,tmp);
1199 sal_address_destroy(addr);
1205 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1206 SalOp *op=find_op(sal,ev);
1208 if (op==NULL || op->terminated==TRUE) {
1209 ms_warning("This call has been canceled.");
1211 eXosip_call_terminate(ev->cid,ev->did);
1219 /* update contact if received and rport are set by the server
1220 note: will only be used by remote for next INVITE, if any...*/
1221 update_contact_from_response(op,ev->response);
1225 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1227 SalOp *op=find_op(sal,ev);
1228 if (call_proceeding(sal, ev)==-1) return;
1230 set_remote_ua(op,ev->response);
1231 sdp=eXosip_get_sdp_info(ev->response);
1233 op->base.remote_media=sal_media_description_new();
1234 sdp_to_media_description(sdp,op->base.remote_media);
1235 sdp_message_free(sdp);
1236 if (op->base.local_media) sdp_process(op);
1238 sal->callbacks.call_ringing(op);
1241 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1243 osip_message_t *msg=NULL;
1244 SalOp *op=find_op(sal,ev);
1245 const char *contact;
1247 if (op==NULL || op->terminated==TRUE) {
1248 ms_warning("This call has been already terminated.");
1250 eXosip_call_terminate(ev->cid,ev->did);
1256 set_remote_ua(op,ev->response);
1257 set_remote_contact(op,ev->response);
1259 sdp=eXosip_get_sdp_info(ev->response);
1261 op->base.remote_media=sal_media_description_new();
1262 sdp_to_media_description(sdp,op->base.remote_media);
1263 sdp_message_free(sdp);
1264 if (op->base.local_media) sdp_process(op);
1266 eXosip_call_build_ack(ev->did,&msg);
1268 ms_warning("This call has been already terminated.");
1270 eXosip_call_terminate(ev->cid,ev->did);
1274 contact=sal_op_get_contact(op);
1276 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1277 osip_message_set_contact(msg,contact);
1279 if (op->sdp_answer){
1280 set_sdp(msg,op->sdp_answer);
1281 sdp_message_free(op->sdp_answer);
1282 op->sdp_answer=NULL;
1284 eXosip_call_send_ack(ev->did,msg);
1285 sal->callbacks.call_accepted(op);
1288 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1290 SalOp *op=find_op(sal,ev);
1292 ms_warning("Call terminated for already closed call ?");
1296 osip_from_to_str(ev->request->from,&from);
1298 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1299 if (from) osip_free(from);
1300 op->terminated=TRUE;
1303 static void call_released(Sal *sal, eXosip_event_t *ev){
1304 SalOp *op=find_op(sal,ev);
1306 ms_warning("No op associated to this call_released()");
1309 if (!op->terminated){
1310 /* no response received so far */
1311 call_failure(sal,ev);
1313 sal->callbacks.call_released(op);
1316 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1317 const char *prx_realm=NULL,*www_realm=NULL;
1318 osip_proxy_authenticate_t *prx_auth;
1319 osip_www_authenticate_t *www_auth;
1321 *username=osip_uri_get_username(resp->from->url);
1322 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1323 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1325 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1327 www_realm=osip_www_authenticate_get_realm(www_auth);
1331 }else if (www_realm){
1339 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1340 osip_authorization_t *auth=NULL;
1341 osip_proxy_authorization_t *prx_auth=NULL;
1343 *username=osip_uri_get_username(msg->from->url);
1344 osip_message_get_authorization(msg, 0, &auth);
1346 *realm=osip_authorization_get_realm(auth);
1349 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1351 *realm=osip_proxy_authorization_get_realm(prx_auth);
1357 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1358 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1359 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1363 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1364 if (op->pending_auth){
1365 return get_auth_data(op->pending_auth,realm,username);
1370 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1372 const char *username,*realm;
1375 ms_warning("No operation associated with this authentication !");
1378 if (get_auth_data(ev,&realm,&username)==0){
1379 if (op->pending_auth!=NULL){
1380 eXosip_event_free(op->pending_auth);
1381 op->pending_auth=ev;
1383 op->pending_auth=ev;
1384 sal_add_pending_auth(sal,op);
1387 sal->callbacks.auth_requested(op,realm,username);
1393 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1395 const char *username,*realm;
1398 ms_warning("No operation associated with this authentication_ok!");
1401 if (op->pending_auth){
1402 eXosip_event_free(op->pending_auth);
1403 sal_remove_pending_auth(sal,op);
1404 op->pending_auth=NULL;
1406 if (get_auth_data(ev,&realm,&username)==0){
1407 sal->callbacks.auth_success(op,realm,username);
1411 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1414 char* computedReason=NULL;
1415 const char *reason=NULL;
1416 SalError error=SalErrorUnknown;
1417 SalReason sr=SalReasonUnknown;
1420 op=(SalOp*)find_op(sal,ev);
1423 ms_warning("Call failure reported for a closed call, ignored.");
1428 code=osip_message_get_status_code(ev->response);
1429 reason=osip_message_get_reason_phrase(ev->response);
1430 osip_header_t *h=NULL;
1431 if (!osip_message_header_get_byname( ev->response
1435 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1436 reason = computedReason;
1444 return process_authentication(sal,ev);
1447 error=SalErrorUnknown;
1450 error=SalErrorFailure;
1451 sr=SalReasonNotFound;
1454 error=SalErrorFailure;
1458 eXosip_default_action(ev);
1462 error=SalErrorFailure;
1463 sr=SalReasonTemporarilyUnavailable;
1465 error=SalErrorFailure;
1471 error=SalErrorFailure;
1472 sr=SalReasonDoNotDisturb;
1475 error=SalErrorFailure;
1476 sr=SalReasonDeclined;
1480 error=SalErrorFailure;
1481 sr=SalReasonUnknown;
1482 }else error=SalErrorNoResponse;
1484 op->terminated=TRUE;
1485 sal->callbacks.call_failure(op,error,sr,reason,code);
1486 if (computedReason != NULL){
1487 ms_free(computedReason);
1492 /* Request remote side to send us VFU */
1493 void sal_call_send_vfu_request(SalOp *h){
1494 osip_message_t *msg=NULL;
1496 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1500 " <picture_fast_update></picture_fast_update>"
1508 eXosip_call_build_info(h->did,&msg);
1510 osip_message_set_body(msg,info_body,strlen(info_body));
1511 osip_message_set_content_type(msg,"application/media_control+xml");
1512 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1513 osip_message_set_content_length(msg,clen);
1514 eXosip_call_send_request(h->did,msg);
1515 ms_message("Sending VFU request !");
1520 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1521 SalOp *op=find_op(sal,ev);
1522 osip_body_t *body=NULL;
1525 ms_warning("media control xml received without operation context!");
1529 osip_message_get_body(ev->request,0,&body);
1530 if (body && body->body!=NULL &&
1531 strstr(body->body,"picture_fast_update")){
1532 osip_message_t *ans=NULL;
1533 ms_message("Receiving VFU request !");
1534 if (sal->callbacks.vfu_request){
1535 sal->callbacks.vfu_request(op);
1536 eXosip_call_build_answer(ev->tid,200,&ans);
1538 eXosip_call_send_answer(ev->tid,200,ans);
1542 /*in all other cases we must say it is not implemented.*/
1544 osip_message_t *ans=NULL;
1546 eXosip_call_build_answer(ev->tid,501,&ans);
1548 eXosip_call_send_answer(ev->tid,501,ans);
1553 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1554 SalOp *op=find_op(sal,ev);
1555 osip_body_t *body=NULL;
1558 ms_warning("media dtmf relay received without operation context!");
1562 osip_message_get_body(ev->request,0,&body);
1563 if (body && body->body!=NULL){
1564 osip_message_t *ans=NULL;
1565 const char *name=strstr(body->body,"Signal");
1566 if (name==NULL) name=strstr(body->body,"signal");
1568 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1571 name+=strlen("signal");
1572 if (sscanf(name," = %1s",tmp)==1){
1573 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1574 if (sal->callbacks.dtmf_received != NULL)
1575 sal->callbacks.dtmf_received(op, tmp[0]);
1579 eXosip_call_build_answer(ev->tid,200,&ans);
1581 eXosip_call_send_answer(ev->tid,200,ans);
1586 static void fill_options_answer(osip_message_t *options){
1587 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1588 osip_message_set_accept(options,"application/sdp");
1591 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1592 osip_header_t *h=NULL;
1593 osip_message_t *ans=NULL;
1594 ms_message("Receiving REFER request !");
1595 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1598 osip_from_t *from=NULL;
1600 osip_from_init(&from);
1602 if (osip_from_parse(from,h->hvalue)==0){
1604 osip_uri_header_t *uh=NULL;
1605 osip_header_t *referred_by=NULL;
1606 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1607 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1608 ms_message("Found replaces in Refer-To");
1610 ms_free(op->replaces);
1612 op->replaces=ms_strdup(uh->gvalue);
1614 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1615 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1616 if (op->referred_by)
1617 ms_free(op->referred_by);
1618 op->referred_by=ms_strdup(referred_by->hvalue);
1621 osip_uri_header_freelist(&from->url->url_headers);
1622 osip_from_to_str(from,&tmp);
1623 sal->callbacks.refer_received(sal,op,tmp);
1625 osip_from_free(from);
1628 eXosip_call_build_answer(ev->tid,202,&ans);
1630 eXosip_call_send_answer(ev->tid,202,ans);
1635 ms_warning("cannot do anything with the refer without destination\n");
1639 static void process_notify(Sal *sal, eXosip_event_t *ev){
1640 osip_header_t *h=NULL;
1642 SalOp *op=find_op(sal,ev);
1643 osip_message_t *ans=NULL;
1645 ms_message("Receiving NOTIFY request !");
1646 osip_from_to_str(ev->request->from,&from);
1647 osip_message_header_get_byname(ev->request,"Event",0,&h);
1649 osip_body_t *body=NULL;
1650 //osip_content_type_t *ct=NULL;
1651 osip_message_get_body(ev->request,0,&body);
1652 //ct=osip_message_get_content_type(ev->request);
1653 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1654 /*special handling of refer events*/
1655 if (body && body->body){
1656 osip_message_t *msg;
1657 osip_message_init(&msg);
1658 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1659 int code=osip_message_get_status_code(msg);
1661 sal->callbacks.notify_refer(op,SalReferTrying);
1662 }else if (code==200){
1663 sal->callbacks.notify_refer(op,SalReferSuccess);
1664 }else if (code>=400){
1665 sal->callbacks.notify_refer(op,SalReferFailed);
1668 osip_message_free(msg);
1671 /*generic handling*/
1672 sal->callbacks.notify(op,from,h->hvalue);
1675 /*answer that we received the notify*/
1677 eXosip_call_build_answer(ev->tid,200,&ans);
1679 eXosip_call_send_answer(ev->tid,200,ans);
1684 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1685 osip_message_t *ans=NULL;
1687 if (MSG_IS_INFO(ev->request)){
1688 osip_content_type_t *ct;
1689 ct=osip_message_get_content_type(ev->request);
1690 if (ct && ct->subtype){
1691 if (strcmp(ct->subtype,"media_control+xml")==0)
1692 process_media_control_xml(sal,ev);
1693 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1694 process_dtmf_relay(sal,ev);
1696 ms_message("Unhandled SIP INFO.");
1697 /*send an "Not implemented" answer*/
1699 eXosip_call_build_answer(ev->tid,501,&ans);
1701 eXosip_call_send_answer(ev->tid,501,ans);
1705 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1707 eXosip_call_build_answer(ev->tid,200,&ans);
1709 eXosip_call_send_answer(ev->tid,200,ans);
1712 }else if(MSG_IS_MESSAGE(ev->request)){
1713 /* SIP messages could be received into call */
1714 text_received(sal, ev);
1716 eXosip_call_build_answer(ev->tid,200,&ans);
1718 eXosip_call_send_answer(ev->tid,200,ans);
1720 }else if(MSG_IS_REFER(ev->request)){
1721 SalOp *op=find_op(sal,ev);
1723 ms_message("Receiving REFER request !");
1724 process_refer(sal,op,ev);
1725 }else if(MSG_IS_NOTIFY(ev->request)){
1726 process_notify(sal,ev);
1727 }else if (MSG_IS_OPTIONS(ev->request)){
1729 eXosip_call_build_answer(ev->tid,200,&ans);
1731 fill_options_answer(ans);
1732 eXosip_call_send_answer(ev->tid,200,ans);
1736 }else ms_warning("call_message_new: No request ?");
1739 static void inc_update(Sal *sal, eXosip_event_t *ev){
1740 osip_message_t *msg=NULL;
1741 ms_message("Processing incoming UPDATE");
1743 eXosip_message_build_answer(ev->tid,200,&msg);
1745 eXosip_message_send_answer(ev->tid,200,msg);
1749 static bool_t comes_from_local_if(osip_message_t *msg){
1750 osip_via_t *via=NULL;
1751 osip_message_get_via(msg,0,&via);
1754 host=osip_via_get_host(via);
1755 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1756 osip_generic_param_t *param=NULL;
1757 osip_via_param_get_byname(via,"received",¶m);
1758 if (param==NULL) return TRUE;
1759 if (param->gvalue &&
1760 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1768 static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
\r
1769 static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
1771 static void text_received(Sal *sal, eXosip_event_t *ev){
1772 osip_body_t *body=NULL;
1773 char *from=NULL,*msg=NULL;
1774 osip_content_type_t* content_type;
1775 osip_uri_param_t* external_body_url;
1776 char unquoted_external_body_url [256];
1777 int external_body_size=0;
1779 char message_id[256]={0};
1780 osip_header_t *date=NULL;
1786 osip_message_get_date(ev->request,0,&date);
1788 ms_error("Could not get the date of message");
1791 sscanf(date->hvalue,"%3c,%d%s%d%d:%d:%d",tmp1,&ret.tm_mday,tmp2,
1792 &ret.tm_year,&ret.tm_hour,&ret.tm_min,&ret.tm_sec);
1795 if(strcmp(tmp1,days[i])==0) ret.tm_wday=i;
1798 if(strcmp(tmp2,months[j])==0) ret.tm_mon=j;
1801 content_type= osip_message_get_content_type(ev->request);
1802 if (!content_type) {
1803 ms_error("Could not get message because no content type");
1806 osip_from_to_str(ev->request->from,&from);
1807 if (content_type->type
1808 && strcmp(content_type->type, "text")==0
1809 && content_type->subtype
1810 && strcmp(content_type->subtype, "plain")==0 ) {
1811 osip_message_get_body(ev->request,0,&body);
1813 ms_error("Could not get text message from SIP body");
1818 }else if (content_type->type
1819 && strcmp(content_type->type, "message")==0
1820 && content_type->subtype
1821 && strcmp(content_type->subtype, "external-body")==0 ) {
1823 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1824 /*remove both first and last character*/
1825 strncpy(unquoted_external_body_url
1826 ,&external_body_url->gvalue[1]
1827 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1828 unquoted_external_body_url[external_body_size-1]='\0';
1830 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1834 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1838 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1839 salmsg.message_id=message_id;
1840 salmsg.time=mktime(&ret);
1841 sal->callbacks.text_received(sal,&salmsg);
1847 static void other_request(Sal *sal, eXosip_event_t *ev){
1848 ms_message("in other_request");
1849 if (ev->request==NULL) return;
1850 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1851 text_received(sal,ev);
1852 eXosip_message_send_answer(ev->tid,200,NULL);
1853 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1854 osip_message_t *options=NULL;
1855 eXosip_options_build_answer(ev->tid,200,&options);
1856 fill_options_answer(options);
1857 eXosip_options_send_answer(ev->tid,200,options);
1858 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1859 ms_message("Receiving REFER request !");
1860 if (comes_from_local_if(ev->request)) {
1861 process_refer(sal,NULL,ev);
1862 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1863 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1868 osip_message_to_str(ev->request,&tmp,&msglen);
1870 ms_message("Unsupported request received:\n%s",tmp);
1873 /*answer with a 501 Not implemented*/
1874 eXosip_message_send_answer(ev->tid,501,NULL);
1878 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1879 osip_via_t *via=NULL;
1880 osip_message_get_via(msg,0,&via);
1882 osip_free(via->port);
1883 via->port=osip_strdup(port);
1884 osip_free(via->host);
1885 via->host=osip_strdup(ip);
1890 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1891 osip_contact_t *ctt=NULL;
1892 const char *received;
1894 SalTransport transport;
1897 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1898 osip_message_get_contact(request,0,&ctt);
1900 ms_warning("fix_message_contact(): no contact to update");
1903 if (expire_last_contact){
1904 osip_contact_t *oldct=NULL,*prevct;
1905 osip_generic_param_t *param=NULL;
1906 osip_contact_clone(ctt,&oldct);
1907 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1908 osip_contact_free(prevct);
1909 osip_list_remove(&request->contacts,1);
1911 osip_list_add(&request->contacts,oldct,1);
1912 osip_contact_param_get_byname(oldct,"expires",¶m);
1914 if (param->gvalue) osip_free(param->gvalue);
1915 param->gvalue=osip_strdup("0");
1917 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1920 if (ctt->url->host!=NULL){
1921 osip_free(ctt->url->host);
1923 ctt->url->host=osip_strdup(received);
1924 if (ctt->url->port!=NULL){
1925 osip_free(ctt->url->port);
1927 snprintf(port,sizeof(port),"%i",rport);
1928 ctt->url->port=osip_strdup(port);
1929 if (op->masquerade_via) masquerade_via(request,received,port);
1931 if (transport != SalTransportUDP) {
1932 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1937 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1938 osip_contact_t *ctt=NULL;
1939 SalAddress* ori_contact_address=NULL;
1940 const char *received;
1942 SalTransport transport;
1944 osip_message_t *msg=NULL;
1945 Sal* sal=op->base.root;
1947 bool_t found_valid_contact=FALSE;
1948 bool_t from_request=FALSE;
1950 if (sal->double_reg==FALSE ) return FALSE;
1952 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1955 osip_message_get_contact(last_answer,i,&ctt);
1956 if (!from_request && ctt==NULL) {
1957 osip_message_get_contact(orig_request,0,&ctt);
1961 osip_contact_to_str(ctt,&tmp);
1962 ori_contact_address = sal_address_new(tmp);
1964 /*check if contact is up to date*/
1965 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1966 && sal_address_get_port_int(ori_contact_address) == rport
1967 && sal_address_get_transport(ori_contact_address) == transport) {
1969 ms_message("Register response has up to date contact, doing nothing.");
1971 ms_warning("Register response does not have up to date contact, but last request had."
1972 "Stupid registrar detected, giving up.");
1974 found_valid_contact=TRUE;
1977 sal_address_destroy(ori_contact_address);
1980 }while(!found_valid_contact);
1981 if (!found_valid_contact)
1982 ms_message("Contact do not match, resending register.");
1986 eXosip_register_build_register(op->rid,op->expires,&msg);
1989 ms_warning("Fail to create a contact updated register.");
1992 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1993 eXosip_register_send_register(op->rid,msg);
1995 ms_message("Resending new register with updated contact");
1996 update_contact_from_response(op,last_answer);
1999 ms_warning("Fail to send updated register.");
2007 static void registration_success(Sal *sal, eXosip_event_t *ev){
2008 SalOp *op=sal_find_register(sal,ev->rid);
2009 osip_header_t *h=NULL;
2012 ms_error("Receiving register response for unknown operation");
2015 osip_message_get_expires(ev->request,0,&h);
2016 if (h!=NULL && atoi(h->hvalue)!=0){
2018 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
2019 sal->callbacks.register_success(op,registered);
2022 sal->callbacks.register_success(op,FALSE);
2026 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
2028 const char *reason=NULL;
2029 SalOp *op=sal_find_register(sal,ev->rid);
2030 SalReason sr=SalReasonUnknown;
2031 SalError se=SalErrorUnknown;
2034 ms_error("Receiving register failure for unknown operation");
2038 status_code=osip_message_get_status_code(ev->response);
2039 reason=osip_message_get_reason_phrase(ev->response);
2041 switch(status_code){
2044 return process_authentication(sal,ev);
2046 case 423: /*interval too brief*/
2047 {/*retry with greater interval */
2048 osip_header_t *h=NULL;
2049 osip_message_t *msg=NULL;
2050 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
2051 if (h && h->hvalue && h->hvalue[0]!='\0'){
2052 int val=atoi(h->hvalue);
2053 if (val>op->expires)
2055 }else op->expires*=2;
2057 eXosip_register_build_register(op->rid,op->expires,&msg);
2058 eXosip_register_send_register(op->rid,msg);
2062 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2063 in vias, such as ekiga.net
2064 On the opposite, freephonie.net bugs when via are masqueraded.
2066 op->masquerade_via=TRUE;
2068 /* if contact is up to date, process the failure, otherwise resend a new register with
2069 updated contact first, just in case the faillure is due to incorrect contact */
2070 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2071 return TRUE; /*we are retrying with an updated contact*/
2072 if (status_code==403){
2074 sr=SalReasonForbidden;
2075 }else if (status_code==0){
2076 se=SalErrorNoResponse;
2078 sal->callbacks.register_failure(op,se,sr,reason);
2083 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2084 SalOp *op=find_op(sal,ev);
2086 ms_warning("other_request_reply(): Receiving response to unknown request.");
2090 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2091 update_contact_from_response(op,ev->response);
2092 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2093 sal->callbacks.ping_reply(op);
2095 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2096 /*out of call message acknolegment*/
2097 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2099 if (ev->response->status_code<200){
2100 status=SalTextDeliveryInProgress;
2101 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2102 status=SalTextDeliveryDone;
2105 sal->callbacks.text_delivery_update(op,status);
2109 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2110 SalOp *op=find_op(sal,ev);
2112 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2113 if (op->sipfrag_pending){
2114 send_notify_for_refer(op->did,op->sipfrag_pending);
2115 op->sipfrag_pending=NULL;
2121 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2122 ms_message("linphone process event get a message %d\n",ev->type);
2124 case EXOSIP_CALL_ANSWERED:
2125 ms_message("CALL_ANSWERED\n");
2126 call_accepted(sal,ev);
2127 authentication_ok(sal,ev);
2129 case EXOSIP_CALL_CLOSED:
2130 case EXOSIP_CALL_CANCELLED:
2131 ms_message("CALL_CLOSED or CANCELLED\n");
2132 call_terminated(sal,ev);
2134 case EXOSIP_CALL_TIMEOUT:
2135 case EXOSIP_CALL_NOANSWER:
2136 ms_message("CALL_TIMEOUT or NOANSWER\n");
2137 return call_failure(sal,ev);
2139 case EXOSIP_CALL_REQUESTFAILURE:
2140 case EXOSIP_CALL_GLOBALFAILURE:
2141 case EXOSIP_CALL_SERVERFAILURE:
2142 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2143 return call_failure(sal,ev);
2145 case EXOSIP_CALL_RELEASED:
2146 ms_message("CALL_RELEASED\n");
2147 call_released(sal, ev);
2149 case EXOSIP_CALL_INVITE:
2150 ms_message("CALL_NEW\n");
2151 inc_new_call(sal,ev);
2153 case EXOSIP_CALL_REINVITE:
2154 handle_reinvite(sal,ev);
2156 case EXOSIP_CALL_ACK:
2157 ms_message("CALL_ACK");
2160 case EXOSIP_CALL_REDIRECTED:
2161 ms_message("CALL_REDIRECTED");
2162 eXosip_default_action(ev);
2164 case EXOSIP_CALL_PROCEEDING:
2165 ms_message("CALL_PROCEEDING");
2166 call_proceeding(sal,ev);
2168 case EXOSIP_CALL_RINGING:
2169 ms_message("CALL_RINGING");
2170 call_ringing(sal,ev);
2171 authentication_ok(sal,ev);
2173 case EXOSIP_CALL_MESSAGE_NEW:
2174 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2175 call_message_new(sal,ev);
2177 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2179 (ev->response->status_code==407 || ev->response->status_code==401)){
2180 return process_authentication(sal,ev);
2183 case EXOSIP_CALL_MESSAGE_ANSWERED:
2184 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2185 process_in_call_reply(sal,ev);
2187 case EXOSIP_IN_SUBSCRIPTION_NEW:
2188 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2189 sal_exosip_subscription_recv(sal,ev);
2191 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2192 ms_message("CALL_SUBSCRIPTION_NEW ");
2193 sal_exosip_in_subscription_closed(sal,ev);
2195 case EXOSIP_SUBSCRIPTION_UPDATE:
2196 ms_message("CALL_SUBSCRIPTION_UPDATE");
2198 case EXOSIP_SUBSCRIPTION_NOTIFY:
2199 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2200 sal_exosip_notify_recv(sal,ev);
2202 case EXOSIP_SUBSCRIPTION_ANSWERED:
2203 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2204 sal_exosip_subscription_answered(sal,ev);
2206 case EXOSIP_SUBSCRIPTION_CLOSED:
2207 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2208 sal_exosip_subscription_closed(sal,ev);
2210 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2211 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2212 return process_authentication(sal,ev);
2214 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2215 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2216 sal_exosip_subscription_closed(sal,ev);
2218 case EXOSIP_REGISTRATION_FAILURE:
2219 ms_message("REGISTRATION_FAILURE\n");
2220 return registration_failure(sal,ev);
2222 case EXOSIP_REGISTRATION_SUCCESS:
2223 authentication_ok(sal,ev);
2224 registration_success(sal,ev);
2226 case EXOSIP_MESSAGE_NEW:
2227 other_request(sal,ev);
2229 case EXOSIP_MESSAGE_PROCEEDING:
2230 case EXOSIP_MESSAGE_ANSWERED:
2231 case EXOSIP_MESSAGE_REDIRECTED:
2232 case EXOSIP_MESSAGE_SERVERFAILURE:
2233 case EXOSIP_MESSAGE_GLOBALFAILURE:
2234 other_request_reply(sal,ev);
2236 case EXOSIP_MESSAGE_REQUESTFAILURE:
2237 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2239 switch (ev->response->status_code) {
2242 return process_authentication(sal,ev);
2244 eXosip_automatic_action ();
2249 other_request_reply(sal,ev);
2252 ms_message("Unhandled exosip event ! %i",ev->type);
2258 int sal_iterate(Sal *sal){
2260 while((ev=eXosip_event_wait(0,0))!=NULL){
2261 if (process_event(sal,ev))
2262 eXosip_event_free(ev);
2264 #ifdef HAVE_EXOSIP_TRYLOCK
2265 if (eXosip_trylock()==0){
2266 eXosip_automatic_refresh();
2269 ms_warning("eXosip_trylock busy.");
2273 eXosip_automatic_refresh();
2279 static void register_set_contact(osip_message_t *msg, const char *contact){
2280 osip_uri_param_t *param = NULL;
2281 osip_contact_t *ct=NULL;
2283 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2284 osip_message_get_contact(msg,0,&ct);
2286 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2287 if (param && param->gvalue)
2288 line=osip_strdup(param->gvalue);
2290 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2291 osip_message_set_contact(msg,contact);
2292 osip_message_get_contact(msg,0,&ct);
2293 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2296 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2297 osip_route_t *route;
2299 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2301 osip_route_init(&route);
2302 if (osip_route_parse(route,proxy)==0){
2303 osip_uri_param_t *lr_param = NULL;
2304 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2305 if (lr_param == NULL){
2306 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2308 osip_list_add(&msg->routes,route,0);
2311 osip_route_free(route);
2315 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2316 osip_message_t *msg;
2317 const char *contact=sal_op_get_contact(h);
2319 sal_op_set_route(h,proxy);
2321 SalAddress *from_parsed=sal_address_new(from);
2323 char *uri, *domain_ptr = NULL;
2324 if (from_parsed==NULL) {
2325 ms_warning("sal_register() bad from %s",from);
2328 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2329 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2330 uri = sal_address_as_string_uri_only(from_parsed);
2331 if (uri) domain_ptr = strchr(uri, '@');
2333 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2335 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2337 if (uri) ms_free(uri);
2338 sal_address_destroy(from_parsed);
2340 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2342 if (contact) register_set_contact(msg,contact);
2343 sal_register_add_route(msg,proxy);
2344 sal_add_register(h->base.root,h);
2346 ms_error("Could not build initial register.");
2352 eXosip_register_build_register(h->rid,expires,&msg);
2353 sal_register_add_route(msg,proxy);
2356 eXosip_register_send_register(h->rid,msg);
2360 return (msg != NULL) ? 0 : -1;
2363 int sal_register_refresh(SalOp *op, int expires){
2364 osip_message_t *msg=NULL;
2365 const char *contact=sal_op_get_contact(op);
2368 ms_error("Unexistant registration context, not possible to refresh.");
2371 #ifdef HAVE_EXOSIP_TRYLOCK
2374 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2375 * In order to prevent this case that can occur when the exosip thread is busy with DNS while network isn't in a good shape, we try to take
2376 * the exosip lock in a non blocking way, and give up if it takes too long*/
2377 while (eXosip_trylock()!=0){
2379 if (tries>30) {/*after 3 seconds, give up*/
2380 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2388 eXosip_register_build_register(op->rid,expires,&msg);
2390 if (contact) register_set_contact(msg,contact);
2391 sal_register_add_route(msg,sal_op_get_route(op));
2392 eXosip_register_send_register(op->rid,msg);
2393 }else ms_error("Could not build REGISTER refresh message.");
2395 return (msg != NULL) ? 0 : -1;
2399 int sal_unregister(SalOp *h){
2400 osip_message_t *msg=NULL;
2402 eXosip_register_build_register(h->rid,0,&msg);
2403 if (msg) eXosip_register_send_register(h->rid,msg);
2404 else ms_warning("Could not build unREGISTER !");
2409 SalAddress * sal_address_new(const char *uri){
2411 osip_from_init(&from);
2413 // Remove front spaces
2414 while (uri[0]==' ') {
2418 if (osip_from_parse(from,uri)!=0){
2419 osip_from_free(from);
2422 if (from->displayname!=NULL && from->displayname[0]=='"'){
2423 char *unquoted=osip_strdup_without_quote(from->displayname);
2424 osip_free(from->displayname);
2425 from->displayname=unquoted;
2427 return (SalAddress*)from;
2430 SalAddress * sal_address_clone(const SalAddress *addr){
2431 osip_from_t *ret=NULL;
2432 osip_from_clone((osip_from_t*)addr,&ret);
2433 return (SalAddress*)ret;
2436 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2438 const char *sal_address_get_scheme(const SalAddress *addr){
2439 const osip_from_t *u=(const osip_from_t*)addr;
2440 return null_if_empty(u->url->scheme);
2443 const char *sal_address_get_display_name(const SalAddress* addr){
2444 const osip_from_t *u=(const osip_from_t*)addr;
2445 return null_if_empty(u->displayname);
2448 const char *sal_address_get_username(const SalAddress *addr){
2449 const osip_from_t *u=(const osip_from_t*)addr;
2450 return null_if_empty(u->url->username);
2453 const char *sal_address_get_domain(const SalAddress *addr){
2454 const osip_from_t *u=(const osip_from_t*)addr;
2455 return null_if_empty(u->url->host);
2458 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2459 osip_from_t *u=(osip_from_t*)addr;
2460 if (u->displayname!=NULL){
2461 osip_free(u->displayname);
2462 u->displayname=NULL;
2464 if (display_name!=NULL && display_name[0]!='\0'){
2465 u->displayname=osip_strdup(display_name);
2469 void sal_address_set_username(SalAddress *addr, const char *username){
2470 osip_from_t *uri=(osip_from_t*)addr;
2471 if (uri->url->username!=NULL){
2472 osip_free(uri->url->username);
2473 uri->url->username=NULL;
2476 uri->url->username=osip_strdup(username);
2479 void sal_address_set_domain(SalAddress *addr, const char *host){
2480 osip_from_t *uri=(osip_from_t*)addr;
2481 if (uri->url->host!=NULL){
2482 osip_free(uri->url->host);
2483 uri->url->host=NULL;
2486 uri->url->host=osip_strdup(host);
2489 void sal_address_set_port(SalAddress *addr, const char *port){
2490 osip_from_t *uri=(osip_from_t*)addr;
2491 if (uri->url->port!=NULL){
2492 osip_free(uri->url->port);
2493 uri->url->port=NULL;
2496 uri->url->port=osip_strdup(port);
2499 void sal_address_set_port_int(SalAddress *uri, int port){
2502 /*this is the default, special case to leave the port field blank*/
2503 sal_address_set_port(uri,NULL);
2506 snprintf(tmp,sizeof(tmp),"%i",port);
2507 sal_address_set_port(uri,tmp);
2510 void sal_address_clean(SalAddress *addr){
2511 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2512 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2515 char *sal_address_as_string(const SalAddress *u){
2517 osip_from_t *from=(osip_from_t *)u;
2518 char *old_displayname=NULL;
2519 /* hack to force use of quotes around the displayname*/
2520 if (from->displayname!=NULL
2521 && from->displayname[0]!='"'){
2522 old_displayname=from->displayname;
2523 from->displayname=osip_enquote(from->displayname);
2525 osip_from_to_str(from,&tmp);
2526 if (old_displayname!=NULL){
2527 ms_free(from->displayname);
2528 from->displayname=old_displayname;
2535 char *sal_address_as_string_uri_only(const SalAddress *u){
2536 char *tmp=NULL,*ret;
2537 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2542 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2543 osip_uri_param_t *param=NULL;
2544 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2546 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2548 osip_free(param->gvalue);
2549 param->gvalue=value ? osip_strdup(value) : NULL;
2554 void sal_address_destroy(SalAddress *u){
2555 osip_from_free((osip_from_t*)u);
2558 void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
2559 ctx->tcp_tls_keepalive = enabled;
2562 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2563 switch (ctx->transport) {
2564 case SalTransportUDP:
2565 ctx->keepalive_period = value;
2567 case SalTransportTCP:
2568 case SalTransportTLS:
2569 if (ctx->tcp_tls_keepalive) ctx->keepalive_period = value;
2570 else ctx->keepalive_period = -1;
2575 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
2577 unsigned int sal_get_keepalive_period(Sal *ctx) {
2578 return ctx->keepalive_period;
2581 const char * sal_address_get_port(const SalAddress *addr) {
2582 const osip_from_t *u=(const osip_from_t*)addr;
2583 return null_if_empty(u->url->port);
2586 int sal_address_get_port_int(const SalAddress *uri) {
2587 const char* port = sal_address_get_port(uri);
2594 SalTransport sal_address_get_transport(const SalAddress* addr) {
2595 const osip_from_t *u=(const osip_from_t*)addr;
2596 osip_uri_param_t *transport_param=NULL;
2597 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2598 if (transport_param == NULL){
2599 return SalTransportUDP;
2601 return sal_transport_parse(transport_param->gvalue);
2604 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2605 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2608 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2609 int sal_call_update(SalOp *h, const char *subject){
2611 osip_message_t *reinvite=NULL;
2614 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2619 osip_message_set_subject(reinvite,subject);
2620 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2621 if (h->base.contact){
2622 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2623 osip_message_set_contact(reinvite,h->base.contact);
2625 if (h->base.root->session_expires!=0){
2626 osip_message_set_header(reinvite, "Session-expires", "200");
2627 osip_message_set_supported(reinvite, "timer");
2629 if (h->base.local_media){
2630 h->sdp_offering=TRUE;
2631 set_sdp_from_desc(reinvite,h->base.local_media);
2632 }else h->sdp_offering=FALSE;
2634 err = eXosip_call_send_request(h->did, reinvite);
2638 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2639 ctx->reuse_authorization=value;