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 !");
56 static SalOp * sal_find_call(Sal *sal, int cid){
59 for(elem=sal->calls;elem!=NULL;elem=elem->next){
60 op=(SalOp*)elem->data;
61 if (op->cid==cid) return op;
66 static void sal_add_call(Sal *sal, SalOp *op){
67 sal->calls=ms_list_append(sal->calls,op);
70 static void sal_remove_call(Sal *sal, SalOp *op){
71 sal->calls=ms_list_remove(sal->calls, op);
74 static SalOp * sal_find_register(Sal *sal, int rid){
77 for(elem=sal->registers;elem!=NULL;elem=elem->next){
78 op=(SalOp*)elem->data;
79 if (op->rid==rid) return op;
84 static void sal_add_register(Sal *sal, SalOp *op){
85 sal->registers=ms_list_append(sal->registers,op);
88 static void sal_remove_register(Sal *sal, int rid){
91 for(elem=sal->registers;elem!=NULL;elem=elem->next){
92 op=(SalOp*)elem->data;
94 sal->registers=ms_list_remove_link(sal->registers,elem);
100 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
103 osip_call_id_t *callid=osip_message_get_call_id(message);
105 ms_error("There is no call-id in this message !");
108 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
109 op=(SalOp*)elem->data;
110 if (osip_call_id_match(callid,op->call_id)==0) return op;
115 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
116 osip_call_id_t *callid=osip_message_get_call_id(request);
118 ms_error("There is no call id in the request !");
121 osip_call_id_clone(callid,&op->call_id);
122 sal->other_transactions=ms_list_append(sal->other_transactions,op);
125 static void sal_remove_other(Sal *sal, SalOp *op){
126 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
130 static void sal_add_pending_auth(Sal *sal, SalOp *op){
131 sal->pending_auths=ms_list_append(sal->pending_auths,op);
135 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
136 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
139 void sal_exosip_fix_route(SalOp *op){
140 if (sal_op_get_route(op)!=NULL){
141 osip_route_t *rt=NULL;
142 osip_uri_param_t *lr_param=NULL;
144 osip_route_init(&rt);
145 if (osip_route_parse(rt,sal_op_get_route(op))<0){
146 ms_warning("Bad route %s!",sal_op_get_route(op));
147 sal_op_set_route(op,NULL);
149 /* check if the lr parameter is set , if not add it */
150 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
153 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
154 osip_route_to_str(rt,&tmproute);
155 sal_op_set_route(op,tmproute);
163 SalOp * sal_op_new(Sal *sal){
164 SalOp *op=ms_new0(SalOp,1);
165 __sal_op_init(op,sal);
166 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
168 op->supports_session_timers=FALSE;
169 op->sdp_offering=TRUE;
170 op->pending_auth=NULL;
175 op->referred_by=NULL;
176 op->masquerade_via=FALSE;
177 op->auto_answer_asked=FALSE;
179 op->terminated=FALSE;
183 bool_t sal_call_autoanswer_asked(SalOp *op)
185 return op->auto_answer_asked;
188 void sal_op_release(SalOp *op){
190 sdp_message_free(op->sdp_answer);
191 if (op->pending_auth)
192 eXosip_event_free(op->pending_auth);
194 sal_remove_register(op->base.root,op->rid);
195 eXosip_register_remove(op->rid);
198 ms_message("Cleaning cid %i",op->cid);
199 sal_remove_call(op->base.root,op);
202 sal_remove_out_subscribe(op->base.root,op);
205 sal_remove_in_subscribe(op->base.root,op);
207 osip_call_id_free(op->call_id);
210 if (op->pending_auth){
211 sal_remove_pending_auth(op->base.root,op);
214 sal_media_description_unref(op->result);
216 sal_remove_other(op->base.root,op);
217 osip_call_id_free(op->call_id);
220 ms_free(op->replaces);
222 if (op->referred_by){
223 ms_free(op->referred_by);
226 sal_auth_info_delete(op->auth_info);
231 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
232 int ortp_level=ORTP_DEBUG;
238 ortp_level=ORTP_MESSAGE;
241 ortp_level=ORTP_WARNING;
245 ortp_level=ORTP_ERROR;
248 ortp_level=ORTP_FATAL;
250 case END_TRACE_LEVEL:
253 if (ortp_log_level_enabled(level)){
254 int len=strlen(chfr);
255 char *chfrdup=ortp_strdup(chfr);
256 /*need to remove endline*/
258 if (chfrdup[len-1]=='\n')
260 if (chfrdup[len-2]=='\r')
263 ortp_logv(ortp_level,chfrdup,ap);
270 static bool_t firsttime=TRUE;
273 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
278 sal->keepalive_period=30;
279 sal->double_reg=TRUE;
280 sal->use_rports=TRUE;
282 sal->reuse_authorization=FALSE;
284 sal->verify_server_certs=TRUE;
285 sal->verify_server_cn=TRUE;
286 sal->expire_old_contact=FALSE;
287 sal->add_dates=FALSE;
292 void sal_uninit(Sal* sal){
295 ms_free(sal->rootCa);
299 void sal_set_user_pointer(Sal *sal, void *user_data){
303 void *sal_get_user_pointer(const Sal *sal){
307 static void unimplemented_stub(){
308 ms_warning("Unimplemented SAL callback");
311 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
312 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
313 if (ctx->callbacks.call_received==NULL)
314 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
315 if (ctx->callbacks.call_ringing==NULL)
316 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
317 if (ctx->callbacks.call_accepted==NULL)
318 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
319 if (ctx->callbacks.call_failure==NULL)
320 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
321 if (ctx->callbacks.call_terminated==NULL)
322 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
323 if (ctx->callbacks.call_released==NULL)
324 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
325 if (ctx->callbacks.call_updating==NULL)
326 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
327 if (ctx->callbacks.auth_requested==NULL)
328 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
329 if (ctx->callbacks.auth_success==NULL)
330 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
331 if (ctx->callbacks.register_success==NULL)
332 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
333 if (ctx->callbacks.register_failure==NULL)
334 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
335 if (ctx->callbacks.dtmf_received==NULL)
336 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
337 if (ctx->callbacks.notify==NULL)
338 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
339 if (ctx->callbacks.notify_presence==NULL)
340 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
341 if (ctx->callbacks.subscribe_received==NULL)
342 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
343 if (ctx->callbacks.text_received==NULL)
344 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
345 if (ctx->callbacks.ping_reply==NULL)
346 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
349 int sal_unlisten_ports(Sal *ctx){
358 int sal_reset_transports(Sal *ctx){
359 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
361 ms_message("Exosip transports reset.");
362 eXosip_reset_transports();
366 ms_warning("sal_reset_transports() not implemented in this version.");
372 static void set_tls_options(Sal *ctx){
374 eXosip_tls_ctx_t tlsCtx;
375 memset(&tlsCtx, 0, sizeof(tlsCtx));
376 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
377 eXosip_set_tls_ctx(&tlsCtx);
379 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
380 eXosip_tls_verify_certificate(ctx->verify_server_certs);
382 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
383 eXosip_tls_verify_cn(ctx->verify_server_cn);
387 void sal_set_dscp(Sal *ctx, int dscp){
389 #ifdef HAVE_EXOSIP_DSCP
391 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
395 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
398 int proto=IPPROTO_UDP;
399 int keepalive = ctx->keepalive_period;
403 case SalTransportUDP:
405 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
407 case SalTransportTCP:
408 case SalTransportTLS:
410 if (!ctx->tcp_tls_keepalive) keepalive=-1;
411 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
412 set_tls_options(ctx);
415 ms_warning("unexpected proto, using datagram");
417 /*see if it looks like an IPv6 address*/
418 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
419 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
420 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
421 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
422 sal_set_dscp(ctx,ctx->dscp);
423 sal_use_dates(ctx,ctx->add_dates);
425 ipv6=strchr(addr,':')!=NULL;
426 eXosip_enable_ipv6(ipv6);
428 if (is_secure && tr == SalTransportUDP){
429 ms_fatal("SIP over DTLS is not supported yet.");
432 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
437 ortp_socket_t sal_get_socket(Sal *ctx){
438 #ifdef HAVE_EXOSIP_GET_SOCKET
439 return eXosip_get_socket(IPPROTO_UDP);
441 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
446 void sal_set_user_agent(Sal *ctx, const char *user_agent){
447 eXosip_set_user_agent(user_agent);
450 void sal_use_session_timers(Sal *ctx, int expires){
451 ctx->session_expires=expires;
454 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
455 ctx->one_matching_codec=one_matching_codec;
458 MSList *sal_get_pending_auths(Sal *sal){
459 return ms_list_copy(sal->pending_auths);
462 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
463 ctx->double_reg=enabled;
466 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
467 ctx->expire_old_contact=enabled;
470 void sal_use_dates(Sal *ctx, bool_t enabled){
471 ctx->add_dates=enabled;
472 #ifdef EXOSIP_OPT_REGISTER_WITH_DATE
475 eXosip_set_option(EXOSIP_OPT_REGISTER_WITH_DATE,&tmp);
478 if (enabled) ms_warning("Exosip does not support EXOSIP_OPT_REGISTER_WITH_DATE option.");
482 void sal_use_rport(Sal *ctx, bool_t use_rports){
483 ctx->use_rports=use_rports;
485 void sal_use_101(Sal *ctx, bool_t use_101){
486 ctx->use_101=use_101;
489 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
491 ms_free(ctx->rootCa);
492 ctx->rootCa = ms_strdup(rootCa);
493 set_tls_options(ctx);
496 const char *sal_get_root_ca(Sal* ctx) {
500 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
501 ctx->verify_server_certs=verify;
502 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
503 eXosip_tls_verify_certificate(verify);
507 void sal_verify_server_cn(Sal *ctx, bool_t verify){
508 ctx->verify_server_cn=verify;
509 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
510 eXosip_tls_verify_cn(verify);
514 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
515 osip_via_t *via=NULL;
516 osip_generic_param_t *param=NULL;
517 const char *rport=NULL;
521 osip_message_get_via(msg,0,&via);
523 ms_warning("extract_received_rport(): no via.");
527 *transport = sal_transport_parse(via->protocol);
529 if (via->port && via->port[0]!='\0')
530 *rportval=atoi(via->port);
532 osip_via_param_get_byname(via,"rport",¶m);
535 if (rport && rport[0]!='\0') *rportval=atoi(rport);
539 osip_via_param_get_byname(via,"received",¶m);
540 if (param) *received=param->gvalue;
542 if (rport==NULL && *received==NULL){
543 ms_warning("extract_received_rport(): no rport and no received parameters.");
549 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
553 sdp_message_to_str(msg,&sdp);
555 snprintf(clen,sizeof(clen),"%i",sdplen);
556 osip_message_set_body(sip,sdp,sdplen);
557 osip_message_set_content_type(sip,"application/sdp");
558 osip_message_set_content_length(sip,clen);
562 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
563 sdp_message_t *msg=media_description_to_sdp(desc);
565 ms_error("Fail to print sdp message !");
569 sdp_message_free(msg);
572 static void sdp_process(SalOp *h){
573 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
575 sal_media_description_unref(h->result);
577 h->result=sal_media_description_new();
578 if (h->sdp_offering){
579 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
583 sdp_message_free(h->sdp_answer);
585 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
586 h->sdp_answer=media_description_to_sdp(h->result);
587 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
588 It should contains media parameters constraint from the remote offer, not our response*/
589 strcpy(h->result->addr,h->base.remote_media->addr);
590 h->result->bandwidth=h->base.remote_media->bandwidth;
592 for(i=0;i<h->result->n_active_streams;++i){
593 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
594 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
595 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
596 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
597 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
598 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
599 if (h->result->streams[i].proto == SalProtoRtpSavp) {
600 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
607 int sal_call_is_offerer(const SalOp *h){
608 return h->sdp_offering;
611 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
613 sal_media_description_ref(desc);
614 if (h->base.local_media)
615 sal_media_description_unref(h->base.local_media);
616 h->base.local_media=desc;
617 if (h->base.remote_media){
618 /*case of an incoming call where we modify the local capabilities between the time
619 * the call is ringing and it is accepted (for example if you want to accept without video*/
620 /*reset the sdp answer so that it is computed again*/
622 sdp_message_free(h->sdp_answer);
629 int sal_call(SalOp *h, const char *from, const char *to){
632 osip_message_t *invite=NULL;
633 osip_call_id_t *callid;
634 sal_op_set_from(h,from);
636 sal_exosip_fix_route(h);
638 h->terminated = FALSE;
640 route = sal_op_get_route(h);
641 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
643 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
644 err, from, to, route);
647 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
648 if (h->base.contact){
649 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
650 osip_message_set_contact(invite,h->base.contact);
652 if (h->base.root->session_expires!=0){
653 osip_message_set_header(invite, "Session-expires", "200");
654 osip_message_set_supported(invite, "timer");
656 if (h->base.local_media){
657 h->sdp_offering=TRUE;
658 set_sdp_from_desc(invite,h->base.local_media);
659 }else h->sdp_offering=FALSE;
661 osip_message_set_header(invite,"Replaces",h->replaces);
663 osip_message_set_header(invite,"Referred-By",h->referred_by);
667 err=eXosip_call_send_initial_invite(invite);
671 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,(char **)(&h->base.call_id));
676 sal_add_call(h->base.root,h);
681 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
684 /*if early media send also 180 and 183 */
688 eXosip_call_build_answer(h->tid,183,&msg);
692 set_sdp(msg,h->sdp_answer);
693 sdp_message_free(h->sdp_answer);
696 eXosip_call_send_answer(h->tid,183,msg);
701 eXosip_call_send_answer(h->tid,180,NULL);
707 int sal_call_accept(SalOp * h){
709 const char *contact=sal_op_get_contact(h);
711 int err=eXosip_call_build_answer(h->tid,200,&msg);
712 if (err<0 || msg==NULL){
713 ms_error("Fail to build answer for call: err=%i",err);
716 if (h->base.root->session_expires!=0){
717 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
721 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
722 osip_message_set_contact(msg,contact);
725 if (h->base.local_media){
726 /*this is the case where we received an invite without SDP*/
727 if (h->sdp_offering) {
728 set_sdp_from_desc(msg,h->base.local_media);
730 if (h->sdp_answer==NULL) sdp_process(h);
732 set_sdp(msg,h->sdp_answer);
733 sdp_message_free(h->sdp_answer);
738 ms_error("You are accepting a call but not defined any media capabilities !");
740 eXosip_call_send_answer(h->tid,200,msg);
744 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
745 if (reason==SalReasonBusy){
747 eXosip_call_send_answer(h->tid,486,NULL);
750 else if (reason==SalReasonTemporarilyUnavailable){
752 eXosip_call_send_answer(h->tid,480,NULL);
754 }else if (reason==SalReasonDoNotDisturb){
756 eXosip_call_send_answer(h->tid,600,NULL);
758 }else if (reason==SalReasonMedia){
760 eXosip_call_send_answer(h->tid,415,NULL);
762 }else if (redirect!=NULL && reason==SalReasonRedirect){
765 if (strstr(redirect,"sip:")!=0) code=302;
768 eXosip_call_build_answer(h->tid,code,&msg);
769 osip_message_set_contact(msg,redirect);
770 eXosip_call_send_answer(h->tid,code,msg);
772 }else sal_call_terminate(h);
776 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
777 return h->base.remote_media;
780 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
781 if (h->base.local_media && h->base.remote_media && !h->result){
787 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
788 if (refered_call->replaces)
789 h->replaces=ms_strdup(refered_call->replaces);
790 if (refered_call->referred_by)
791 h->referred_by=ms_strdup(refered_call->referred_by);
795 static int send_notify_for_refer(int did, const char *sipfrag){
798 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
801 ms_warning("Could not build NOTIFY for refer.");
804 osip_message_set_content_type(msg,"message/sipfrag");
805 osip_message_set_header(msg,"Event","refer");
806 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
807 eXosip_call_send_request(did,msg);
812 /* currently only support to notify trying and 200Ok*/
813 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
816 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
818 else if (newcall->cid!=-1){
819 if (newcall->did==-1){
820 /* not yet established*/
821 if (!newcall->terminated){
823 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
826 if (!newcall->terminated){
827 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
828 /* we need previous notify transaction to complete, so buffer the request for later*/
829 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
837 int sal_ping(SalOp *op, const char *from, const char *to){
838 osip_message_t *options=NULL;
840 sal_op_set_from(op,from);
841 sal_op_set_to(op,to);
842 sal_exosip_fix_route(op);
844 eXosip_options_build_request (&options, sal_op_get_to(op),
845 sal_op_get_from(op),sal_op_get_route(op));
847 if (op->base.root->session_expires!=0){
848 osip_message_set_header(options, "Session-expires", "200");
849 osip_message_set_supported(options, "timer");
851 sal_add_other(sal_op_get_sal(op),op,options);
852 return eXosip_options_send_request(options);
857 int sal_call_refer(SalOp *h, const char *refer_to){
858 osip_message_t *msg=NULL;
861 eXosip_call_build_refer(h->did,refer_to, &msg);
862 if (msg) err=eXosip_call_send_request(h->did, msg);
868 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
869 osip_message_t *msg=NULL;
870 char referto[256]={0};
873 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
874 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
878 eXosip_call_build_refer(h->did,referto, &msg);
879 osip_message_set_header(msg,"Referred-By",h->base.from);
880 if (msg) err=eXosip_call_send_request(h->did, msg);
886 SalOp *sal_call_get_replaces(SalOp *h){
887 if (h!=NULL && h->replaces!=NULL){
890 cid=eXosip_call_find_by_replaces(h->replaces);
893 SalOp *ret=sal_find_call(h->base.root,cid);
900 int sal_call_send_dtmf(SalOp *h, char dtmf){
901 osip_message_t *msg=NULL;
906 eXosip_call_build_info(h->did,&msg);
908 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
909 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
910 osip_message_set_content_type(msg,"application/dtmf-relay");
911 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
912 osip_message_set_content_length(msg,clen);
913 eXosip_call_send_request(h->did,msg);
919 static void push_auth_to_exosip(const SalAuthInfo *info){
921 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
922 else userid=info->userid;
923 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
924 eXosip_add_authentication_info (info->username,userid,
925 info->password, NULL,info->realm);
928 * Just for symmetry ;-)
930 static void pop_auth_from_exosip() {
931 eXosip_clear_authentication_info();
934 int sal_call_terminate(SalOp *h){
936 if (h == NULL) return -1;
937 if (h->auth_info) push_auth_to_exosip(h->auth_info);
939 err=eXosip_call_terminate(h->cid,h->did);
941 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
943 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
949 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
950 bool_t terminating=FALSE;
951 if (h->pending_auth && strcmp(h->pending_auth->request->sip_method,"BYE")==0) {
954 if (h->terminated && !terminating) return;
956 if (h->pending_auth){
957 push_auth_to_exosip(info);
959 /*FIXME exosip does not take into account this update register message*/
961 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
965 update_contact_from_response(h,h->pending_auth->response);
967 eXosip_default_action(h->pending_auth);
969 ms_message("eXosip_default_action() done");
970 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
972 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
973 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
976 void sal_op_cancel_authentication(SalOp *h) {
978 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
979 } else if (h->cid >0) {
980 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
982 ms_warning("Auth failure not handled");
986 static void set_network_origin(SalOp *op, osip_message_t *req){
987 const char *received=NULL;
990 SalTransport transport;
991 if (extract_received_rport(req,&received,&rport,&transport)!=0){
992 osip_via_t *via=NULL;
994 osip_message_get_via(req,0,&via);
995 received=osip_via_get_host(via);
996 tmp=osip_via_get_port(via);
997 if (tmp) rport=atoi(tmp);
999 if (transport != SalTransportUDP) {
1000 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
1002 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
1004 __sal_op_set_network_origin(op,origin);
1007 static void set_remote_ua(SalOp* op, osip_message_t *req){
1008 if (op->base.remote_ua==NULL){
1009 osip_header_t *h=NULL;
1010 osip_message_get_user_agent(req,0,&h);
1012 op->base.remote_ua=ms_strdup(h->hvalue);
1017 static void set_replaces(SalOp *op, osip_message_t *req){
1018 osip_header_t *h=NULL;
1021 ms_free(op->replaces);
1024 osip_message_header_get_byname(req,"replaces",0,&h);
1026 if (h->hvalue && h->hvalue[0]!='\0'){
1027 op->replaces=ms_strdup(h->hvalue);
1032 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1034 return sal_find_call(sal,ev->cid);
1037 return sal_find_register(sal,ev->rid);
1040 return sal_find_out_subscribe(sal,ev->sid);
1043 return sal_find_in_subscribe(sal,ev->nid);
1045 if (ev->response) return sal_find_other(sal,ev->response);
1046 else if (ev->request) return sal_find_other(sal,ev->request);
1050 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1051 SalOp *op=sal_op_new(sal);
1052 osip_from_t *from,*to;
1053 osip_call_info_t *call_info;
1055 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1056 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1057 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1059 set_network_origin(op,ev->request);
1060 set_remote_ua(op,ev->request);
1061 set_replaces(op,ev->request);
1064 op->sdp_offering=FALSE;
1065 op->base.remote_media=sal_media_description_new();
1066 sdp_to_media_description(sdp,op->base.remote_media);
1067 sdp_message_free(sdp);
1068 }else op->sdp_offering=TRUE;
1070 from=osip_message_get_from(ev->request);
1071 to=osip_message_get_to(ev->request);
1072 osip_from_to_str(from,&tmp);
1073 sal_op_set_from(op,tmp);
1075 osip_from_to_str(to,&tmp);
1076 sal_op_set_to(op,tmp);
1079 osip_message_get_call_info(ev->request,0,&call_info);
1082 osip_call_info_to_str(call_info,&tmp);
1083 if( strstr(tmp,"answer-after=") != NULL)
1085 op->auto_answer_asked=TRUE;
1086 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1094 sal_add_call(op->base.root,op);
1095 sal->callbacks.call_received(op);
1098 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1099 SalOp *op=find_op(sal,ev);
1103 ms_warning("Reinvite for non-existing operation !");
1108 sdp=eXosip_get_sdp_info(ev->request);
1109 if (op->base.remote_media){
1110 sal_media_description_unref(op->base.remote_media);
1111 op->base.remote_media=NULL;
1114 sal_media_description_unref(op->result);
1118 op->sdp_offering=FALSE;
1119 op->base.remote_media=sal_media_description_new();
1120 sdp_to_media_description(sdp,op->base.remote_media);
1121 sdp_message_free(sdp);
1124 op->sdp_offering=TRUE;
1126 sal->callbacks.call_updating(op);
1129 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1130 SalOp *op=find_op(sal,ev);
1134 ms_warning("ack for non-existing call !");
1137 if (op->terminated) {
1138 ms_warning("ack for terminated call, ignoring");
1142 if (op->sdp_offering){
1143 sdp=eXosip_get_sdp_info(ev->ack);
1145 if (op->base.remote_media)
1146 sal_media_description_unref(op->base.remote_media);
1147 op->base.remote_media=sal_media_description_new();
1148 sdp_to_media_description(sdp,op->base.remote_media);
1150 sdp_message_free(sdp);
1156 sal->callbacks.call_ack(op);
1159 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1160 const char *received;
1162 SalTransport transport;
1163 if (extract_received_rport(response,&received,&rport,&transport)==0){
1164 const char *contact=sal_op_get_contact(op);
1166 /*no contact given yet, use from instead*/
1167 contact=sal_op_get_from(op);
1170 SalAddress *addr=sal_address_new(contact);
1172 sal_address_set_domain(addr,received);
1173 sal_address_set_port_int(addr,rport);
1174 if (transport!=SalTransportUDP)
1175 sal_address_set_transport(addr,transport);
1176 tmp=sal_address_as_string(addr);
1177 ms_message("Contact address updated to %s",tmp);
1178 sal_op_set_contact(op,tmp);
1179 sal_address_destroy(addr);
1185 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1186 SalOp *op=find_op(sal,ev);
1188 if (op==NULL || op->terminated==TRUE) {
1189 ms_warning("This call has been canceled.");
1191 eXosip_call_terminate(ev->cid,ev->did);
1199 /* update contact if received and rport are set by the server
1200 note: will only be used by remote for next INVITE, if any...*/
1201 update_contact_from_response(op,ev->response);
1205 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1207 SalOp *op=find_op(sal,ev);
1208 if (call_proceeding(sal, ev)==-1) return;
1210 set_remote_ua(op,ev->response);
1211 sdp=eXosip_get_sdp_info(ev->response);
1213 op->base.remote_media=sal_media_description_new();
1214 sdp_to_media_description(sdp,op->base.remote_media);
1215 sdp_message_free(sdp);
1216 if (op->base.local_media) sdp_process(op);
1218 sal->callbacks.call_ringing(op);
1221 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1223 osip_message_t *msg=NULL;
1224 SalOp *op=find_op(sal,ev);
1225 const char *contact;
1227 if (op==NULL || op->terminated==TRUE) {
1228 ms_warning("This call has been already terminated.");
1230 eXosip_call_terminate(ev->cid,ev->did);
1236 set_remote_ua(op,ev->response);
1238 sdp=eXosip_get_sdp_info(ev->response);
1240 op->base.remote_media=sal_media_description_new();
1241 sdp_to_media_description(sdp,op->base.remote_media);
1242 sdp_message_free(sdp);
1243 if (op->base.local_media) sdp_process(op);
1245 eXosip_call_build_ack(ev->did,&msg);
1247 ms_warning("This call has been already terminated.");
1249 eXosip_call_terminate(ev->cid,ev->did);
1253 contact=sal_op_get_contact(op);
1255 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1256 osip_message_set_contact(msg,contact);
1258 if (op->sdp_answer){
1259 set_sdp(msg,op->sdp_answer);
1260 sdp_message_free(op->sdp_answer);
1261 op->sdp_answer=NULL;
1263 eXosip_call_send_ack(ev->did,msg);
1264 sal->callbacks.call_accepted(op);
1267 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1269 SalOp *op=find_op(sal,ev);
1271 ms_warning("Call terminated for already closed call ?");
1275 osip_from_to_str(ev->request->from,&from);
1277 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1278 if (from) osip_free(from);
1279 op->terminated=TRUE;
1282 static void call_released(Sal *sal, eXosip_event_t *ev){
1283 SalOp *op=find_op(sal,ev);
1285 ms_warning("No op associated to this call_released()");
1288 if (!op->terminated){
1289 /* no response received so far */
1290 call_failure(sal,ev);
1292 sal->callbacks.call_released(op);
1295 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1296 const char *prx_realm=NULL,*www_realm=NULL;
1297 osip_proxy_authenticate_t *prx_auth;
1298 osip_www_authenticate_t *www_auth;
1300 *username=osip_uri_get_username(resp->from->url);
1301 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1302 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1304 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1306 www_realm=osip_www_authenticate_get_realm(www_auth);
1310 }else if (www_realm){
1318 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1319 osip_authorization_t *auth=NULL;
1320 osip_proxy_authorization_t *prx_auth=NULL;
1322 *username=osip_uri_get_username(msg->from->url);
1323 osip_message_get_authorization(msg, 0, &auth);
1325 *realm=osip_authorization_get_realm(auth);
1328 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1330 *realm=osip_proxy_authorization_get_realm(prx_auth);
1336 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1337 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1338 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1342 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1343 if (op->pending_auth){
1344 return get_auth_data(op->pending_auth,realm,username);
1349 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1351 const char *username,*realm;
1354 ms_warning("No operation associated with this authentication !");
1357 if (get_auth_data(ev,&realm,&username)==0){
1358 if (op->pending_auth!=NULL){
1359 eXosip_event_free(op->pending_auth);
1360 op->pending_auth=ev;
1362 op->pending_auth=ev;
1363 sal_add_pending_auth(sal,op);
1366 sal->callbacks.auth_requested(op,realm,username);
1372 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1374 const char *username,*realm;
1377 ms_warning("No operation associated with this authentication_ok!");
1380 if (op->pending_auth){
1381 eXosip_event_free(op->pending_auth);
1382 sal_remove_pending_auth(sal,op);
1383 op->pending_auth=NULL;
1385 if (get_auth_data(ev,&realm,&username)==0){
1386 sal->callbacks.auth_success(op,realm,username);
1390 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1393 char* computedReason=NULL;
1394 const char *reason=NULL;
1395 SalError error=SalErrorUnknown;
1396 SalReason sr=SalReasonUnknown;
1399 op=(SalOp*)find_op(sal,ev);
1402 ms_warning("Call failure reported for a closed call, ignored.");
1407 code=osip_message_get_status_code(ev->response);
1408 reason=osip_message_get_reason_phrase(ev->response);
1409 osip_header_t *h=NULL;
1410 if (!osip_message_header_get_byname( ev->response
1414 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1415 reason = computedReason;
1423 return process_authentication(sal,ev);
1426 error=SalErrorUnknown;
1429 error=SalErrorFailure;
1430 sr=SalReasonNotFound;
1433 error=SalErrorFailure;
1437 eXosip_default_action(ev);
1441 error=SalErrorFailure;
1442 sr=SalReasonTemporarilyUnavailable;
1444 error=SalErrorFailure;
1450 error=SalErrorFailure;
1451 sr=SalReasonDoNotDisturb;
1454 error=SalErrorFailure;
1455 sr=SalReasonDeclined;
1459 error=SalErrorFailure;
1460 sr=SalReasonUnknown;
1461 }else error=SalErrorNoResponse;
1463 op->terminated=TRUE;
1464 sal->callbacks.call_failure(op,error,sr,reason,code);
1465 if (computedReason != NULL){
1466 ms_free(computedReason);
1471 /* Request remote side to send us VFU */
1472 void sal_call_send_vfu_request(SalOp *h){
1473 osip_message_t *msg=NULL;
1475 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1479 " <picture_fast_update></picture_fast_update>"
1487 eXosip_call_build_info(h->did,&msg);
1489 osip_message_set_body(msg,info_body,strlen(info_body));
1490 osip_message_set_content_type(msg,"application/media_control+xml");
1491 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1492 osip_message_set_content_length(msg,clen);
1493 eXosip_call_send_request(h->did,msg);
1494 ms_message("Sending VFU request !");
1499 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1500 SalOp *op=find_op(sal,ev);
1501 osip_body_t *body=NULL;
1504 ms_warning("media control xml received without operation context!");
1508 osip_message_get_body(ev->request,0,&body);
1509 if (body && body->body!=NULL &&
1510 strstr(body->body,"picture_fast_update")){
1511 osip_message_t *ans=NULL;
1512 ms_message("Receiving VFU request !");
1513 if (sal->callbacks.vfu_request){
1514 sal->callbacks.vfu_request(op);
1515 eXosip_call_build_answer(ev->tid,200,&ans);
1517 eXosip_call_send_answer(ev->tid,200,ans);
1521 /*in all other cases we must say it is not implemented.*/
1523 osip_message_t *ans=NULL;
1525 eXosip_call_build_answer(ev->tid,501,&ans);
1527 eXosip_call_send_answer(ev->tid,501,ans);
1532 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1533 SalOp *op=find_op(sal,ev);
1534 osip_body_t *body=NULL;
1537 ms_warning("media dtmf relay received without operation context!");
1541 osip_message_get_body(ev->request,0,&body);
1542 if (body && body->body!=NULL){
1543 osip_message_t *ans=NULL;
1544 const char *name=strstr(body->body,"Signal");
1545 if (name==NULL) name=strstr(body->body,"signal");
1547 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1550 name+=strlen("signal");
1551 if (sscanf(name," = %1s",tmp)==1){
1552 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1553 if (sal->callbacks.dtmf_received != NULL)
1554 sal->callbacks.dtmf_received(op, tmp[0]);
1558 eXosip_call_build_answer(ev->tid,200,&ans);
1560 eXosip_call_send_answer(ev->tid,200,ans);
1565 static void fill_options_answer(osip_message_t *options){
1566 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1567 osip_message_set_accept(options,"application/sdp");
1570 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1571 osip_header_t *h=NULL;
1572 osip_message_t *ans=NULL;
1573 ms_message("Receiving REFER request !");
1574 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1577 osip_from_t *from=NULL;
1579 osip_from_init(&from);
1581 if (osip_from_parse(from,h->hvalue)==0){
1583 osip_uri_header_t *uh=NULL;
1584 osip_header_t *referred_by=NULL;
1585 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1586 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1587 ms_message("Found replaces in Refer-To");
1589 ms_free(op->replaces);
1591 op->replaces=ms_strdup(uh->gvalue);
1593 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1594 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1595 if (op->referred_by)
1596 ms_free(op->referred_by);
1597 op->referred_by=ms_strdup(referred_by->hvalue);
1600 osip_uri_header_freelist(&from->url->url_headers);
1601 osip_from_to_str(from,&tmp);
1602 sal->callbacks.refer_received(sal,op,tmp);
1604 osip_from_free(from);
1607 eXosip_call_build_answer(ev->tid,202,&ans);
1609 eXosip_call_send_answer(ev->tid,202,ans);
1614 ms_warning("cannot do anything with the refer without destination\n");
1618 static void process_notify(Sal *sal, eXosip_event_t *ev){
1619 osip_header_t *h=NULL;
1621 SalOp *op=find_op(sal,ev);
1622 osip_message_t *ans=NULL;
1624 ms_message("Receiving NOTIFY request !");
1625 osip_from_to_str(ev->request->from,&from);
1626 osip_message_header_get_byname(ev->request,"Event",0,&h);
1628 osip_body_t *body=NULL;
1629 //osip_content_type_t *ct=NULL;
1630 osip_message_get_body(ev->request,0,&body);
1631 //ct=osip_message_get_content_type(ev->request);
1632 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1633 /*special handling of refer events*/
1634 if (body && body->body){
1635 osip_message_t *msg;
1636 osip_message_init(&msg);
1637 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1638 int code=osip_message_get_status_code(msg);
1640 sal->callbacks.notify_refer(op,SalReferTrying);
1641 }else if (code==200){
1642 sal->callbacks.notify_refer(op,SalReferSuccess);
1643 }else if (code>=400){
1644 sal->callbacks.notify_refer(op,SalReferFailed);
1647 osip_message_free(msg);
1650 /*generic handling*/
1651 sal->callbacks.notify(op,from,h->hvalue);
1654 /*answer that we received the notify*/
1656 eXosip_call_build_answer(ev->tid,200,&ans);
1658 eXosip_call_send_answer(ev->tid,200,ans);
1663 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1664 osip_message_t *ans=NULL;
1666 if (MSG_IS_INFO(ev->request)){
1667 osip_content_type_t *ct;
1668 ct=osip_message_get_content_type(ev->request);
1669 if (ct && ct->subtype){
1670 if (strcmp(ct->subtype,"media_control+xml")==0)
1671 process_media_control_xml(sal,ev);
1672 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1673 process_dtmf_relay(sal,ev);
1675 ms_message("Unhandled SIP INFO.");
1676 /*send an "Not implemented" answer*/
1678 eXosip_call_build_answer(ev->tid,501,&ans);
1680 eXosip_call_send_answer(ev->tid,501,ans);
1684 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1686 eXosip_call_build_answer(ev->tid,200,&ans);
1688 eXosip_call_send_answer(ev->tid,200,ans);
1691 }else if(MSG_IS_MESSAGE(ev->request)){
1692 /* SIP messages could be received into call */
1693 text_received(sal, ev);
1695 eXosip_call_build_answer(ev->tid,200,&ans);
1697 eXosip_call_send_answer(ev->tid,200,ans);
1699 }else if(MSG_IS_REFER(ev->request)){
1700 SalOp *op=find_op(sal,ev);
1702 ms_message("Receiving REFER request !");
1703 process_refer(sal,op,ev);
1704 }else if(MSG_IS_NOTIFY(ev->request)){
1705 process_notify(sal,ev);
1706 }else if (MSG_IS_OPTIONS(ev->request)){
1708 eXosip_call_build_answer(ev->tid,200,&ans);
1710 fill_options_answer(ans);
1711 eXosip_call_send_answer(ev->tid,200,ans);
1715 }else ms_warning("call_message_new: No request ?");
1718 static void inc_update(Sal *sal, eXosip_event_t *ev){
1719 osip_message_t *msg=NULL;
1720 ms_message("Processing incoming UPDATE");
1722 eXosip_message_build_answer(ev->tid,200,&msg);
1724 eXosip_message_send_answer(ev->tid,200,msg);
1728 static bool_t comes_from_local_if(osip_message_t *msg){
1729 osip_via_t *via=NULL;
1730 osip_message_get_via(msg,0,&via);
1733 host=osip_via_get_host(via);
1734 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1735 osip_generic_param_t *param=NULL;
1736 osip_via_param_get_byname(via,"received",¶m);
1737 if (param==NULL) return TRUE;
1738 if (param->gvalue &&
1739 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1747 static void text_received(Sal *sal, eXosip_event_t *ev){
1748 osip_body_t *body=NULL;
1749 char *from=NULL,*msg=NULL;
1750 osip_content_type_t* content_type;
1751 osip_uri_param_t* external_body_url;
1752 char unquoted_external_body_url [256];
1753 int external_body_size=0;
1755 char message_id[256]={0};
1757 content_type= osip_message_get_content_type(ev->request);
1758 if (!content_type) {
1759 ms_error("Could not get message because no content type");
1762 osip_from_to_str(ev->request->from,&from);
1763 if (content_type->type
1764 && strcmp(content_type->type, "text")==0
1765 && content_type->subtype
1766 && strcmp(content_type->subtype, "plain")==0 ) {
1767 osip_message_get_body(ev->request,0,&body);
1769 ms_error("Could not get text message from SIP body");
1774 }else if (content_type->type
1775 && strcmp(content_type->type, "message")==0
1776 && content_type->subtype
1777 && strcmp(content_type->subtype, "external-body")==0 ) {
1779 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1780 /*remove both first and last character*/
1781 strncpy(unquoted_external_body_url
1782 ,&external_body_url->gvalue[1]
1783 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1784 unquoted_external_body_url[external_body_size-1]='\0';
1786 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1790 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1794 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1795 salmsg.message_id=message_id;
1796 sal->callbacks.text_received(sal,&salmsg);
1802 static void other_request(Sal *sal, eXosip_event_t *ev){
1803 ms_message("in other_request");
1804 if (ev->request==NULL) return;
1805 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1806 text_received(sal,ev);
1807 eXosip_message_send_answer(ev->tid,200,NULL);
1808 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1809 osip_message_t *options=NULL;
1810 eXosip_options_build_answer(ev->tid,200,&options);
1811 fill_options_answer(options);
1812 eXosip_options_send_answer(ev->tid,200,options);
1813 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1814 ms_message("Receiving REFER request !");
1815 if (comes_from_local_if(ev->request)) {
1816 process_refer(sal,NULL,ev);
1817 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1818 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1823 osip_message_to_str(ev->request,&tmp,&msglen);
1825 ms_message("Unsupported request received:\n%s",tmp);
1828 /*answer with a 501 Not implemented*/
1829 eXosip_message_send_answer(ev->tid,501,NULL);
1833 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1834 osip_via_t *via=NULL;
1835 osip_message_get_via(msg,0,&via);
1837 osip_free(via->port);
1838 via->port=osip_strdup(port);
1839 osip_free(via->host);
1840 via->host=osip_strdup(ip);
1845 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1846 osip_contact_t *ctt=NULL;
1847 const char *received;
1849 SalTransport transport;
1852 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1853 osip_message_get_contact(request,0,&ctt);
1855 ms_warning("fix_message_contact(): no contact to update");
1858 if (expire_last_contact){
1859 osip_contact_t *oldct=NULL,*prevct;
1860 osip_generic_param_t *param=NULL;
1861 osip_contact_clone(ctt,&oldct);
1862 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1863 osip_contact_free(prevct);
1864 osip_list_remove(&request->contacts,1);
1866 osip_list_add(&request->contacts,oldct,1);
1867 osip_contact_param_get_byname(oldct,"expires",¶m);
1869 if (param->gvalue) osip_free(param->gvalue);
1870 param->gvalue=osip_strdup("0");
1872 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1875 if (ctt->url->host!=NULL){
1876 osip_free(ctt->url->host);
1878 ctt->url->host=osip_strdup(received);
1879 if (ctt->url->port!=NULL){
1880 osip_free(ctt->url->port);
1882 snprintf(port,sizeof(port),"%i",rport);
1883 ctt->url->port=osip_strdup(port);
1884 if (op->masquerade_via) masquerade_via(request,received,port);
1886 if (transport != SalTransportUDP) {
1887 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1892 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1893 osip_contact_t *ctt=NULL;
1894 SalAddress* ori_contact_address=NULL;
1895 const char *received;
1897 SalTransport transport;
1899 osip_message_t *msg=NULL;
1900 Sal* sal=op->base.root;
1902 bool_t found_valid_contact=FALSE;
1903 bool_t from_request=FALSE;
1905 if (sal->double_reg==FALSE ) return FALSE;
1907 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1910 osip_message_get_contact(last_answer,i,&ctt);
1911 if (!from_request && ctt==NULL) {
1912 osip_message_get_contact(orig_request,0,&ctt);
1916 osip_contact_to_str(ctt,&tmp);
1917 ori_contact_address = sal_address_new(tmp);
1919 /*check if contact is up to date*/
1920 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1921 && sal_address_get_port_int(ori_contact_address) == rport
1922 && sal_address_get_transport(ori_contact_address) == transport) {
1924 ms_message("Register response has up to date contact, doing nothing.");
1926 ms_warning("Register response does not have up to date contact, but last request had."
1927 "Stupid registrar detected, giving up.");
1929 found_valid_contact=TRUE;
1932 sal_address_destroy(ori_contact_address);
1935 }while(!found_valid_contact);
1936 if (!found_valid_contact)
1937 ms_message("Contact do not match, resending register.");
1941 eXosip_register_build_register(op->rid,op->expires,&msg);
1944 ms_warning("Fail to create a contact updated register.");
1947 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1948 eXosip_register_send_register(op->rid,msg);
1950 ms_message("Resending new register with updated contact");
1951 update_contact_from_response(op,last_answer);
1954 ms_warning("Fail to send updated register.");
1962 static void registration_success(Sal *sal, eXosip_event_t *ev){
1963 SalOp *op=sal_find_register(sal,ev->rid);
1964 osip_header_t *h=NULL;
1967 ms_error("Receiving register response for unknown operation");
1970 osip_message_get_expires(ev->request,0,&h);
1971 if (h!=NULL && atoi(h->hvalue)!=0){
1973 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1974 sal->callbacks.register_success(op,registered);
1977 sal->callbacks.register_success(op,FALSE);
1981 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1983 const char *reason=NULL;
1984 SalOp *op=sal_find_register(sal,ev->rid);
1985 SalReason sr=SalReasonUnknown;
1986 SalError se=SalErrorUnknown;
1989 ms_error("Receiving register failure for unknown operation");
1993 status_code=osip_message_get_status_code(ev->response);
1994 reason=osip_message_get_reason_phrase(ev->response);
1996 switch(status_code){
1999 return process_authentication(sal,ev);
2001 case 423: /*interval too brief*/
2002 {/*retry with greater interval */
2003 osip_header_t *h=NULL;
2004 osip_message_t *msg=NULL;
2005 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
2006 if (h && h->hvalue && h->hvalue[0]!='\0'){
2007 int val=atoi(h->hvalue);
2008 if (val>op->expires)
2010 }else op->expires*=2;
2012 eXosip_register_build_register(op->rid,op->expires,&msg);
2013 eXosip_register_send_register(op->rid,msg);
2017 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2018 in vias, such as ekiga.net
2019 On the opposite, freephonie.net bugs when via are masqueraded.
2021 op->masquerade_via=TRUE;
2023 /* if contact is up to date, process the failure, otherwise resend a new register with
2024 updated contact first, just in case the faillure is due to incorrect contact */
2025 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2026 return TRUE; /*we are retrying with an updated contact*/
2027 if (status_code==403){
2029 sr=SalReasonForbidden;
2030 }else if (status_code==0){
2031 se=SalErrorNoResponse;
2033 sal->callbacks.register_failure(op,se,sr,reason);
2038 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2039 SalOp *op=find_op(sal,ev);
2041 ms_warning("other_request_reply(): Receiving response to unknown request.");
2045 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2046 update_contact_from_response(op,ev->response);
2047 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2048 sal->callbacks.ping_reply(op);
2050 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2051 /*out of call message acknolegment*/
2052 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2054 if (ev->response->status_code<200){
2055 status=SalTextDeliveryInProgress;
2056 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2057 status=SalTextDeliveryDone;
2060 sal->callbacks.text_delivery_update(op,status);
2064 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2065 SalOp *op=find_op(sal,ev);
2067 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2068 if (op->sipfrag_pending){
2069 send_notify_for_refer(op->did,op->sipfrag_pending);
2070 op->sipfrag_pending=NULL;
2076 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2077 ms_message("linphone process event get a message %d\n",ev->type);
2079 case EXOSIP_CALL_ANSWERED:
2080 ms_message("CALL_ANSWERED\n");
2081 call_accepted(sal,ev);
2082 authentication_ok(sal,ev);
2084 case EXOSIP_CALL_CLOSED:
2085 case EXOSIP_CALL_CANCELLED:
2086 ms_message("CALL_CLOSED or CANCELLED\n");
2087 call_terminated(sal,ev);
2089 case EXOSIP_CALL_TIMEOUT:
2090 case EXOSIP_CALL_NOANSWER:
2091 ms_message("CALL_TIMEOUT or NOANSWER\n");
2092 return call_failure(sal,ev);
2094 case EXOSIP_CALL_REQUESTFAILURE:
2095 case EXOSIP_CALL_GLOBALFAILURE:
2096 case EXOSIP_CALL_SERVERFAILURE:
2097 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2098 return call_failure(sal,ev);
2100 case EXOSIP_CALL_RELEASED:
2101 ms_message("CALL_RELEASED\n");
2102 call_released(sal, ev);
2104 case EXOSIP_CALL_INVITE:
2105 ms_message("CALL_NEW\n");
2106 inc_new_call(sal,ev);
2108 case EXOSIP_CALL_REINVITE:
2109 handle_reinvite(sal,ev);
2111 case EXOSIP_CALL_ACK:
2112 ms_message("CALL_ACK");
2115 case EXOSIP_CALL_REDIRECTED:
2116 ms_message("CALL_REDIRECTED");
2117 eXosip_default_action(ev);
2119 case EXOSIP_CALL_PROCEEDING:
2120 ms_message("CALL_PROCEEDING");
2121 call_proceeding(sal,ev);
2123 case EXOSIP_CALL_RINGING:
2124 ms_message("CALL_RINGING");
2125 call_ringing(sal,ev);
2126 authentication_ok(sal,ev);
2128 case EXOSIP_CALL_MESSAGE_NEW:
2129 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2130 call_message_new(sal,ev);
2132 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2134 (ev->response->status_code==407 || ev->response->status_code==401)){
2135 return process_authentication(sal,ev);
2138 case EXOSIP_CALL_MESSAGE_ANSWERED:
2139 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2140 process_in_call_reply(sal,ev);
2142 case EXOSIP_IN_SUBSCRIPTION_NEW:
2143 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2144 sal_exosip_subscription_recv(sal,ev);
2146 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2147 ms_message("CALL_SUBSCRIPTION_NEW ");
2148 sal_exosip_in_subscription_closed(sal,ev);
2150 case EXOSIP_SUBSCRIPTION_UPDATE:
2151 ms_message("CALL_SUBSCRIPTION_UPDATE");
2153 case EXOSIP_SUBSCRIPTION_NOTIFY:
2154 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2155 sal_exosip_notify_recv(sal,ev);
2157 case EXOSIP_SUBSCRIPTION_ANSWERED:
2158 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2159 sal_exosip_subscription_answered(sal,ev);
2161 case EXOSIP_SUBSCRIPTION_CLOSED:
2162 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2163 sal_exosip_subscription_closed(sal,ev);
2165 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2166 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2167 return process_authentication(sal,ev);
2169 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2170 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2171 sal_exosip_subscription_closed(sal,ev);
2173 case EXOSIP_REGISTRATION_FAILURE:
2174 ms_message("REGISTRATION_FAILURE\n");
2175 return registration_failure(sal,ev);
2177 case EXOSIP_REGISTRATION_SUCCESS:
2178 authentication_ok(sal,ev);
2179 registration_success(sal,ev);
2181 case EXOSIP_MESSAGE_NEW:
2182 other_request(sal,ev);
2184 case EXOSIP_MESSAGE_PROCEEDING:
2185 case EXOSIP_MESSAGE_ANSWERED:
2186 case EXOSIP_MESSAGE_REDIRECTED:
2187 case EXOSIP_MESSAGE_SERVERFAILURE:
2188 case EXOSIP_MESSAGE_GLOBALFAILURE:
2189 other_request_reply(sal,ev);
2191 case EXOSIP_MESSAGE_REQUESTFAILURE:
2192 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2194 switch (ev->response->status_code) {
2197 return process_authentication(sal,ev);
2199 eXosip_automatic_action ();
2204 other_request_reply(sal,ev);
2207 ms_message("Unhandled exosip event ! %i",ev->type);
2213 int sal_iterate(Sal *sal){
2215 while((ev=eXosip_event_wait(0,0))!=NULL){
2216 if (process_event(sal,ev))
2217 eXosip_event_free(ev);
2219 #ifdef HAVE_EXOSIP_TRYLOCK
2220 if (eXosip_trylock()==0){
2221 eXosip_automatic_refresh();
2224 ms_warning("eXosip_trylock busy.");
2228 eXosip_automatic_refresh();
2234 static void register_set_contact(osip_message_t *msg, const char *contact){
2235 osip_uri_param_t *param = NULL;
2236 osip_contact_t *ct=NULL;
2238 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2239 osip_message_get_contact(msg,0,&ct);
2241 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2242 if (param && param->gvalue)
2243 line=osip_strdup(param->gvalue);
2245 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2246 osip_message_set_contact(msg,contact);
2247 osip_message_get_contact(msg,0,&ct);
2248 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2251 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2252 osip_route_t *route;
2254 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2256 osip_route_init(&route);
2257 if (osip_route_parse(route,proxy)==0){
2258 osip_uri_param_t *lr_param = NULL;
2259 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2260 if (lr_param == NULL){
2261 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2263 osip_list_add(&msg->routes,route,0);
2266 osip_route_free(route);
2270 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2271 osip_message_t *msg;
2272 const char *contact=sal_op_get_contact(h);
2274 sal_op_set_route(h,proxy);
2276 SalAddress *from_parsed=sal_address_new(from);
2278 char *uri, *domain_ptr = NULL;
2279 if (from_parsed==NULL) {
2280 ms_warning("sal_register() bad from %s",from);
2283 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2284 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2285 uri = sal_address_as_string_uri_only(from_parsed);
2286 if (uri) domain_ptr = strchr(uri, '@');
2288 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2290 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2292 if (uri) ms_free(uri);
2293 sal_address_destroy(from_parsed);
2295 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2297 if (contact) register_set_contact(msg,contact);
2298 sal_register_add_route(msg,proxy);
2299 sal_add_register(h->base.root,h);
2301 ms_error("Could not build initial register.");
2307 eXosip_register_build_register(h->rid,expires,&msg);
2308 sal_register_add_route(msg,proxy);
2311 eXosip_register_send_register(h->rid,msg);
2315 return (msg != NULL) ? 0 : -1;
2318 int sal_register_refresh(SalOp *op, int expires){
2319 osip_message_t *msg=NULL;
2320 const char *contact=sal_op_get_contact(op);
2323 ms_error("Unexistant registration context, not possible to refresh.");
2326 #ifdef HAVE_EXOSIP_TRYLOCK
2329 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2330 * 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
2331 * the exosip lock in a non blocking way, and give up if it takes too long*/
2332 while (eXosip_trylock()!=0){
2334 if (tries>30) {/*after 3 seconds, give up*/
2335 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2343 eXosip_register_build_register(op->rid,expires,&msg);
2345 if (contact) register_set_contact(msg,contact);
2346 sal_register_add_route(msg,sal_op_get_route(op));
2347 eXosip_register_send_register(op->rid,msg);
2348 }else ms_error("Could not build REGISTER refresh message.");
2350 return (msg != NULL) ? 0 : -1;
2354 int sal_unregister(SalOp *h){
2355 osip_message_t *msg=NULL;
2357 eXosip_register_build_register(h->rid,0,&msg);
2358 if (msg) eXosip_register_send_register(h->rid,msg);
2359 else ms_warning("Could not build unREGISTER !");
2364 SalAddress * sal_address_new(const char *uri){
2366 osip_from_init(&from);
2368 // Remove front spaces
2369 while (uri[0]==' ') {
2373 if (osip_from_parse(from,uri)!=0){
2374 osip_from_free(from);
2377 if (from->displayname!=NULL && from->displayname[0]=='"'){
2378 char *unquoted=osip_strdup_without_quote(from->displayname);
2379 osip_free(from->displayname);
2380 from->displayname=unquoted;
2382 return (SalAddress*)from;
2385 SalAddress * sal_address_clone(const SalAddress *addr){
2386 osip_from_t *ret=NULL;
2387 osip_from_clone((osip_from_t*)addr,&ret);
2388 return (SalAddress*)ret;
2391 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2393 const char *sal_address_get_scheme(const SalAddress *addr){
2394 const osip_from_t *u=(const osip_from_t*)addr;
2395 return null_if_empty(u->url->scheme);
2398 const char *sal_address_get_display_name(const SalAddress* addr){
2399 const osip_from_t *u=(const osip_from_t*)addr;
2400 return null_if_empty(u->displayname);
2403 const char *sal_address_get_username(const SalAddress *addr){
2404 const osip_from_t *u=(const osip_from_t*)addr;
2405 return null_if_empty(u->url->username);
2408 const char *sal_address_get_domain(const SalAddress *addr){
2409 const osip_from_t *u=(const osip_from_t*)addr;
2410 return null_if_empty(u->url->host);
2413 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2414 osip_from_t *u=(osip_from_t*)addr;
2415 if (u->displayname!=NULL){
2416 osip_free(u->displayname);
2417 u->displayname=NULL;
2419 if (display_name!=NULL && display_name[0]!='\0'){
2420 u->displayname=osip_strdup(display_name);
2424 void sal_address_set_username(SalAddress *addr, const char *username){
2425 osip_from_t *uri=(osip_from_t*)addr;
2426 if (uri->url->username!=NULL){
2427 osip_free(uri->url->username);
2428 uri->url->username=NULL;
2431 uri->url->username=osip_strdup(username);
2434 void sal_address_set_domain(SalAddress *addr, const char *host){
2435 osip_from_t *uri=(osip_from_t*)addr;
2436 if (uri->url->host!=NULL){
2437 osip_free(uri->url->host);
2438 uri->url->host=NULL;
2441 uri->url->host=osip_strdup(host);
2444 void sal_address_set_port(SalAddress *addr, const char *port){
2445 osip_from_t *uri=(osip_from_t*)addr;
2446 if (uri->url->port!=NULL){
2447 osip_free(uri->url->port);
2448 uri->url->port=NULL;
2451 uri->url->port=osip_strdup(port);
2454 void sal_address_set_port_int(SalAddress *uri, int port){
2457 /*this is the default, special case to leave the port field blank*/
2458 sal_address_set_port(uri,NULL);
2461 snprintf(tmp,sizeof(tmp),"%i",port);
2462 sal_address_set_port(uri,tmp);
2465 void sal_address_clean(SalAddress *addr){
2466 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2467 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2470 char *sal_address_as_string(const SalAddress *u){
2472 osip_from_t *from=(osip_from_t *)u;
2473 char *old_displayname=NULL;
2474 /* hack to force use of quotes around the displayname*/
2475 if (from->displayname!=NULL
2476 && from->displayname[0]!='"'){
2477 old_displayname=from->displayname;
2478 from->displayname=osip_enquote(from->displayname);
2480 osip_from_to_str(from,&tmp);
2481 if (old_displayname!=NULL){
2482 ms_free(from->displayname);
2483 from->displayname=old_displayname;
2490 char *sal_address_as_string_uri_only(const SalAddress *u){
2491 char *tmp=NULL,*ret;
2492 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2497 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2498 osip_uri_param_t *param=NULL;
2499 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2501 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2503 osip_free(param->gvalue);
2504 param->gvalue=value ? osip_strdup(value) : NULL;
2509 void sal_address_destroy(SalAddress *u){
2510 osip_from_free((osip_from_t*)u);
2513 void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
2514 ctx->tcp_tls_keepalive = enabled;
2517 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2518 switch (ctx->transport) {
2519 case SalTransportUDP:
2520 ctx->keepalive_period = value;
2522 case SalTransportTCP:
2523 case SalTransportTLS:
2524 if (ctx->tcp_tls_keepalive) ctx->keepalive_period = value;
2525 else ctx->keepalive_period = -1;
2530 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
2532 unsigned int sal_get_keepalive_period(Sal *ctx) {
2533 return ctx->keepalive_period;
2536 const char * sal_address_get_port(const SalAddress *addr) {
2537 const osip_from_t *u=(const osip_from_t*)addr;
2538 return null_if_empty(u->url->port);
2541 int sal_address_get_port_int(const SalAddress *uri) {
2542 const char* port = sal_address_get_port(uri);
2549 SalTransport sal_address_get_transport(const SalAddress* addr) {
2550 const osip_from_t *u=(const osip_from_t*)addr;
2551 osip_uri_param_t *transport_param=NULL;
2552 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2553 if (transport_param == NULL){
2554 return SalTransportUDP;
2556 return sal_transport_parse(transport_param->gvalue);
2559 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2560 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2563 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2564 int sal_call_update(SalOp *h, const char *subject){
2566 osip_message_t *reinvite=NULL;
2569 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2574 osip_message_set_subject(reinvite,subject);
2575 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2576 if (h->base.contact){
2577 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2578 osip_message_set_contact(reinvite,h->base.contact);
2580 if (h->base.root->session_expires!=0){
2581 osip_message_set_header(reinvite, "Session-expires", "200");
2582 osip_message_set_supported(reinvite, "timer");
2584 if (h->base.local_media){
2585 h->sdp_offering=TRUE;
2586 set_sdp_from_desc(reinvite,h->base.local_media);
2587 }else h->sdp_offering=FALSE;
2589 err = eXosip_call_send_request(h->did, reinvite);
2593 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2594 ctx->reuse_authorization=value;