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);
675 callid=osip_message_get_call_id(invite);
676 osip_call_id_to_str(callid,&tmp);
677 h->base.call_id=ms_strdup(tmp);
679 sal_add_call(h->base.root,h);
684 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
687 /*if early media send also 180 and 183 */
691 eXosip_call_build_answer(h->tid,183,&msg);
695 set_sdp(msg,h->sdp_answer);
696 sdp_message_free(h->sdp_answer);
699 eXosip_call_send_answer(h->tid,183,msg);
704 eXosip_call_send_answer(h->tid,180,NULL);
710 int sal_call_accept(SalOp * h){
712 const char *contact=sal_op_get_contact(h);
714 int err=eXosip_call_build_answer(h->tid,200,&msg);
715 if (err<0 || msg==NULL){
716 ms_error("Fail to build answer for call: err=%i",err);
719 if (h->base.root->session_expires!=0){
720 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
724 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
725 osip_message_set_contact(msg,contact);
728 if (h->base.local_media){
729 /*this is the case where we received an invite without SDP*/
730 if (h->sdp_offering) {
731 set_sdp_from_desc(msg,h->base.local_media);
733 if (h->sdp_answer==NULL) sdp_process(h);
735 set_sdp(msg,h->sdp_answer);
736 sdp_message_free(h->sdp_answer);
741 ms_error("You are accepting a call but not defined any media capabilities !");
743 eXosip_call_send_answer(h->tid,200,msg);
747 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
748 if (reason==SalReasonBusy){
750 eXosip_call_send_answer(h->tid,486,NULL);
753 else if (reason==SalReasonTemporarilyUnavailable){
755 eXosip_call_send_answer(h->tid,480,NULL);
757 }else if (reason==SalReasonDoNotDisturb){
759 eXosip_call_send_answer(h->tid,600,NULL);
761 }else if (reason==SalReasonMedia){
763 eXosip_call_send_answer(h->tid,415,NULL);
765 }else if (redirect!=NULL && reason==SalReasonRedirect){
768 if (strstr(redirect,"sip:")!=0) code=302;
771 eXosip_call_build_answer(h->tid,code,&msg);
772 osip_message_set_contact(msg,redirect);
773 eXosip_call_send_answer(h->tid,code,msg);
775 }else sal_call_terminate(h);
779 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
780 return h->base.remote_media;
783 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
784 if (h->base.local_media && h->base.remote_media && !h->result){
790 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
791 if (refered_call->replaces)
792 h->replaces=ms_strdup(refered_call->replaces);
793 if (refered_call->referred_by)
794 h->referred_by=ms_strdup(refered_call->referred_by);
798 static int send_notify_for_refer(int did, const char *sipfrag){
801 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
804 ms_warning("Could not build NOTIFY for refer.");
807 osip_message_set_content_type(msg,"message/sipfrag");
808 osip_message_set_header(msg,"Event","refer");
809 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
810 eXosip_call_send_request(did,msg);
815 /* currently only support to notify trying and 200Ok*/
816 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
819 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
821 else if (newcall->cid!=-1){
822 if (newcall->did==-1){
823 /* not yet established*/
824 if (!newcall->terminated){
826 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
829 if (!newcall->terminated){
830 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
831 /* we need previous notify transaction to complete, so buffer the request for later*/
832 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
840 int sal_ping(SalOp *op, const char *from, const char *to){
841 osip_message_t *options=NULL;
843 sal_op_set_from(op,from);
844 sal_op_set_to(op,to);
845 sal_exosip_fix_route(op);
847 eXosip_options_build_request (&options, sal_op_get_to(op),
848 sal_op_get_from(op),sal_op_get_route(op));
850 if (op->base.root->session_expires!=0){
851 osip_message_set_header(options, "Session-expires", "200");
852 osip_message_set_supported(options, "timer");
854 sal_add_other(sal_op_get_sal(op),op,options);
855 return eXosip_options_send_request(options);
860 int sal_call_refer(SalOp *h, const char *refer_to){
861 osip_message_t *msg=NULL;
864 eXosip_call_build_refer(h->did,refer_to, &msg);
865 if (msg) err=eXosip_call_send_request(h->did, msg);
871 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
872 osip_message_t *msg=NULL;
873 char referto[256]={0};
876 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
877 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
881 eXosip_call_build_refer(h->did,referto, &msg);
882 osip_message_set_header(msg,"Referred-By",h->base.from);
883 if (msg) err=eXosip_call_send_request(h->did, msg);
889 SalOp *sal_call_get_replaces(SalOp *h){
890 if (h!=NULL && h->replaces!=NULL){
893 cid=eXosip_call_find_by_replaces(h->replaces);
896 SalOp *ret=sal_find_call(h->base.root,cid);
903 int sal_call_send_dtmf(SalOp *h, char dtmf){
904 osip_message_t *msg=NULL;
909 eXosip_call_build_info(h->did,&msg);
911 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
912 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
913 osip_message_set_content_type(msg,"application/dtmf-relay");
914 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
915 osip_message_set_content_length(msg,clen);
916 eXosip_call_send_request(h->did,msg);
922 static void push_auth_to_exosip(const SalAuthInfo *info){
924 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
925 else userid=info->userid;
926 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
927 eXosip_add_authentication_info (info->username,userid,
928 info->password, NULL,info->realm);
931 * Just for symmetry ;-)
933 static void pop_auth_from_exosip() {
934 eXosip_clear_authentication_info();
937 int sal_call_terminate(SalOp *h){
939 if (h == NULL) return -1;
940 if (h->auth_info) push_auth_to_exosip(h->auth_info);
942 err=eXosip_call_terminate(h->cid,h->did);
944 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
946 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
952 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
953 bool_t terminating=FALSE;
954 if (h->pending_auth && strcmp(h->pending_auth->request->sip_method,"BYE")==0) {
957 if (h->terminated && !terminating) return;
959 if (h->pending_auth){
960 push_auth_to_exosip(info);
962 /*FIXME exosip does not take into account this update register message*/
964 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
968 update_contact_from_response(h,h->pending_auth->response);
970 eXosip_default_action(h->pending_auth);
972 ms_message("eXosip_default_action() done");
973 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
975 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
976 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
979 void sal_op_cancel_authentication(SalOp *h) {
981 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
982 } else if (h->cid >0) {
983 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
985 ms_warning("Auth failure not handled");
989 static void set_network_origin(SalOp *op, osip_message_t *req){
990 const char *received=NULL;
993 SalTransport transport;
994 if (extract_received_rport(req,&received,&rport,&transport)!=0){
995 osip_via_t *via=NULL;
997 osip_message_get_via(req,0,&via);
998 received=osip_via_get_host(via);
999 tmp=osip_via_get_port(via);
1000 if (tmp) rport=atoi(tmp);
1002 if (transport != SalTransportUDP) {
1003 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
1005 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
1007 __sal_op_set_network_origin(op,origin);
1010 static void set_remote_ua(SalOp* op, osip_message_t *req){
1011 if (op->base.remote_ua==NULL){
1012 osip_header_t *h=NULL;
1013 osip_message_get_user_agent(req,0,&h);
1015 op->base.remote_ua=ms_strdup(h->hvalue);
1020 static void set_remote_contact(SalOp* op, osip_message_t *req){
1021 if (op->base.remote_contact==NULL){
1022 osip_contact_t *h=NULL;
1023 osip_message_get_contact(req,0,&h);
1026 osip_contact_to_str(h,&tmp);
1027 __sal_op_set_remote_contact(op,tmp);
1033 static void set_replaces(SalOp *op, osip_message_t *req){
1034 osip_header_t *h=NULL;
1037 ms_free(op->replaces);
1040 osip_message_header_get_byname(req,"replaces",0,&h);
1042 if (h->hvalue && h->hvalue[0]!='\0'){
1043 op->replaces=ms_strdup(h->hvalue);
1048 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1050 return sal_find_call(sal,ev->cid);
1053 return sal_find_register(sal,ev->rid);
1056 return sal_find_out_subscribe(sal,ev->sid);
1059 return sal_find_in_subscribe(sal,ev->nid);
1061 if (ev->response) return sal_find_other(sal,ev->response);
1062 else if (ev->request) return sal_find_other(sal,ev->request);
1066 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1067 SalOp *op=sal_op_new(sal);
1068 osip_from_t *from,*to;
1069 osip_call_info_t *call_info;
1071 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1073 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1075 osip_call_id_to_str(callid,&tmp);
1076 op->base.call_id=ms_strdup(tmp);
1079 set_network_origin(op,ev->request);
1080 set_remote_contact(op,ev->request);
1081 set_remote_ua(op,ev->request);
1082 set_replaces(op,ev->request);
1085 op->sdp_offering=FALSE;
1086 op->base.remote_media=sal_media_description_new();
1087 sdp_to_media_description(sdp,op->base.remote_media);
1088 sdp_message_free(sdp);
1089 }else op->sdp_offering=TRUE;
1091 from=osip_message_get_from(ev->request);
1092 to=osip_message_get_to(ev->request);
1093 osip_from_to_str(from,&tmp);
1094 sal_op_set_from(op,tmp);
1096 osip_from_to_str(to,&tmp);
1097 sal_op_set_to(op,tmp);
1100 osip_message_get_call_info(ev->request,0,&call_info);
1103 osip_call_info_to_str(call_info,&tmp);
1104 if( strstr(tmp,"answer-after=") != NULL)
1106 op->auto_answer_asked=TRUE;
1107 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1115 sal_add_call(op->base.root,op);
1116 sal->callbacks.call_received(op);
1119 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1120 SalOp *op=find_op(sal,ev);
1124 ms_warning("Reinvite for non-existing operation !");
1129 sdp=eXosip_get_sdp_info(ev->request);
1130 if (op->base.remote_media){
1131 sal_media_description_unref(op->base.remote_media);
1132 op->base.remote_media=NULL;
1135 sal_media_description_unref(op->result);
1139 op->sdp_offering=FALSE;
1140 op->base.remote_media=sal_media_description_new();
1141 sdp_to_media_description(sdp,op->base.remote_media);
1142 sdp_message_free(sdp);
1145 op->sdp_offering=TRUE;
1147 sal->callbacks.call_updating(op);
1150 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1151 SalOp *op=find_op(sal,ev);
1155 ms_warning("ack for non-existing call !");
1158 if (op->terminated) {
1159 ms_warning("ack for terminated call, ignoring");
1163 if (op->sdp_offering){
1164 sdp=eXosip_get_sdp_info(ev->ack);
1166 if (op->base.remote_media)
1167 sal_media_description_unref(op->base.remote_media);
1168 op->base.remote_media=sal_media_description_new();
1169 sdp_to_media_description(sdp,op->base.remote_media);
1171 sdp_message_free(sdp);
1177 sal->callbacks.call_ack(op);
1180 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1181 const char *received;
1183 SalTransport transport;
1184 if (extract_received_rport(response,&received,&rport,&transport)==0){
1185 const char *contact=sal_op_get_contact(op);
1187 /*no contact given yet, use from instead*/
1188 contact=sal_op_get_from(op);
1191 SalAddress *addr=sal_address_new(contact);
1193 sal_address_set_domain(addr,received);
1194 sal_address_set_port_int(addr,rport);
1195 if (transport!=SalTransportUDP)
1196 sal_address_set_transport(addr,transport);
1197 tmp=sal_address_as_string(addr);
1198 ms_message("Contact address updated to %s",tmp);
1199 sal_op_set_contact(op,tmp);
1200 sal_address_destroy(addr);
1206 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1207 SalOp *op=find_op(sal,ev);
1209 if (op==NULL || op->terminated==TRUE) {
1210 ms_warning("This call has been canceled.");
1212 eXosip_call_terminate(ev->cid,ev->did);
1220 /* update contact if received and rport are set by the server
1221 note: will only be used by remote for next INVITE, if any...*/
1222 update_contact_from_response(op,ev->response);
1226 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1228 SalOp *op=find_op(sal,ev);
1229 if (call_proceeding(sal, ev)==-1) return;
1231 set_remote_ua(op,ev->response);
1232 sdp=eXosip_get_sdp_info(ev->response);
1234 op->base.remote_media=sal_media_description_new();
1235 sdp_to_media_description(sdp,op->base.remote_media);
1236 sdp_message_free(sdp);
1237 if (op->base.local_media) sdp_process(op);
1239 sal->callbacks.call_ringing(op);
1242 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1244 osip_message_t *msg=NULL;
1245 SalOp *op=find_op(sal,ev);
1246 const char *contact;
1248 if (op==NULL || op->terminated==TRUE) {
1249 ms_warning("This call has been already terminated.");
1251 eXosip_call_terminate(ev->cid,ev->did);
1257 set_remote_ua(op,ev->response);
1258 set_remote_contact(op,ev->response);
1260 sdp=eXosip_get_sdp_info(ev->response);
1262 op->base.remote_media=sal_media_description_new();
1263 sdp_to_media_description(sdp,op->base.remote_media);
1264 sdp_message_free(sdp);
1265 if (op->base.local_media) sdp_process(op);
1267 eXosip_call_build_ack(ev->did,&msg);
1269 ms_warning("This call has been already terminated.");
1271 eXosip_call_terminate(ev->cid,ev->did);
1275 contact=sal_op_get_contact(op);
1277 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1278 osip_message_set_contact(msg,contact);
1280 if (op->sdp_answer){
1281 set_sdp(msg,op->sdp_answer);
1282 sdp_message_free(op->sdp_answer);
1283 op->sdp_answer=NULL;
1285 eXosip_call_send_ack(ev->did,msg);
1286 sal->callbacks.call_accepted(op);
1289 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1291 SalOp *op=find_op(sal,ev);
1293 ms_warning("Call terminated for already closed call ?");
1297 osip_from_to_str(ev->request->from,&from);
1299 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1300 if (from) osip_free(from);
1301 op->terminated=TRUE;
1304 static void call_released(Sal *sal, eXosip_event_t *ev){
1305 SalOp *op=find_op(sal,ev);
1307 ms_warning("No op associated to this call_released()");
1310 if (!op->terminated){
1311 /* no response received so far */
1312 call_failure(sal,ev);
1314 sal->callbacks.call_released(op);
1317 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1318 const char *prx_realm=NULL,*www_realm=NULL;
1319 osip_proxy_authenticate_t *prx_auth;
1320 osip_www_authenticate_t *www_auth;
1322 *username=osip_uri_get_username(resp->from->url);
1323 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1324 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1326 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1328 www_realm=osip_www_authenticate_get_realm(www_auth);
1332 }else if (www_realm){
1340 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1341 osip_authorization_t *auth=NULL;
1342 osip_proxy_authorization_t *prx_auth=NULL;
1344 *username=osip_uri_get_username(msg->from->url);
1345 osip_message_get_authorization(msg, 0, &auth);
1347 *realm=osip_authorization_get_realm(auth);
1350 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1352 *realm=osip_proxy_authorization_get_realm(prx_auth);
1358 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1359 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1360 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1364 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1365 if (op->pending_auth){
1366 return get_auth_data(op->pending_auth,realm,username);
1371 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1373 const char *username,*realm;
1376 ms_warning("No operation associated with this authentication !");
1379 if (get_auth_data(ev,&realm,&username)==0){
1380 if (op->pending_auth!=NULL){
1381 eXosip_event_free(op->pending_auth);
1382 op->pending_auth=ev;
1384 op->pending_auth=ev;
1385 sal_add_pending_auth(sal,op);
1388 sal->callbacks.auth_requested(op,realm,username);
1394 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1396 const char *username,*realm;
1399 ms_warning("No operation associated with this authentication_ok!");
1402 if (op->pending_auth){
1403 eXosip_event_free(op->pending_auth);
1404 sal_remove_pending_auth(sal,op);
1405 op->pending_auth=NULL;
1407 if (get_auth_data(ev,&realm,&username)==0){
1408 sal->callbacks.auth_success(op,realm,username);
1412 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1415 char* computedReason=NULL;
1416 const char *reason=NULL;
1417 SalError error=SalErrorUnknown;
1418 SalReason sr=SalReasonUnknown;
1421 op=(SalOp*)find_op(sal,ev);
1424 ms_warning("Call failure reported for a closed call, ignored.");
1429 code=osip_message_get_status_code(ev->response);
1430 reason=osip_message_get_reason_phrase(ev->response);
1431 osip_header_t *h=NULL;
1432 if (!osip_message_header_get_byname( ev->response
1436 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1437 reason = computedReason;
1445 return process_authentication(sal,ev);
1448 error=SalErrorUnknown;
1451 error=SalErrorFailure;
1452 sr=SalReasonNotFound;
1455 error=SalErrorFailure;
1459 eXosip_default_action(ev);
1463 error=SalErrorFailure;
1464 sr=SalReasonTemporarilyUnavailable;
1466 error=SalErrorFailure;
1472 error=SalErrorFailure;
1473 sr=SalReasonDoNotDisturb;
1476 error=SalErrorFailure;
1477 sr=SalReasonDeclined;
1481 error=SalErrorFailure;
1482 sr=SalReasonUnknown;
1483 }else error=SalErrorNoResponse;
1485 op->terminated=TRUE;
1486 sal->callbacks.call_failure(op,error,sr,reason,code);
1487 if (computedReason != NULL){
1488 ms_free(computedReason);
1493 /* Request remote side to send us VFU */
1494 void sal_call_send_vfu_request(SalOp *h){
1495 osip_message_t *msg=NULL;
1497 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1501 " <picture_fast_update></picture_fast_update>"
1509 eXosip_call_build_info(h->did,&msg);
1511 osip_message_set_body(msg,info_body,strlen(info_body));
1512 osip_message_set_content_type(msg,"application/media_control+xml");
1513 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1514 osip_message_set_content_length(msg,clen);
1515 eXosip_call_send_request(h->did,msg);
1516 ms_message("Sending VFU request !");
1521 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1522 SalOp *op=find_op(sal,ev);
1523 osip_body_t *body=NULL;
1526 ms_warning("media control xml received without operation context!");
1530 osip_message_get_body(ev->request,0,&body);
1531 if (body && body->body!=NULL &&
1532 strstr(body->body,"picture_fast_update")){
1533 osip_message_t *ans=NULL;
1534 ms_message("Receiving VFU request !");
1535 if (sal->callbacks.vfu_request){
1536 sal->callbacks.vfu_request(op);
1537 eXosip_call_build_answer(ev->tid,200,&ans);
1539 eXosip_call_send_answer(ev->tid,200,ans);
1543 /*in all other cases we must say it is not implemented.*/
1545 osip_message_t *ans=NULL;
1547 eXosip_call_build_answer(ev->tid,501,&ans);
1549 eXosip_call_send_answer(ev->tid,501,ans);
1554 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1555 SalOp *op=find_op(sal,ev);
1556 osip_body_t *body=NULL;
1559 ms_warning("media dtmf relay received without operation context!");
1563 osip_message_get_body(ev->request,0,&body);
1564 if (body && body->body!=NULL){
1565 osip_message_t *ans=NULL;
1566 const char *name=strstr(body->body,"Signal");
1567 if (name==NULL) name=strstr(body->body,"signal");
1569 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1572 name+=strlen("signal");
1573 if (sscanf(name," = %1s",tmp)==1){
1574 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1575 if (sal->callbacks.dtmf_received != NULL)
1576 sal->callbacks.dtmf_received(op, tmp[0]);
1580 eXosip_call_build_answer(ev->tid,200,&ans);
1582 eXosip_call_send_answer(ev->tid,200,ans);
1587 static void fill_options_answer(osip_message_t *options){
1588 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1589 osip_message_set_accept(options,"application/sdp");
1592 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1593 osip_header_t *h=NULL;
1594 osip_message_t *ans=NULL;
1595 ms_message("Receiving REFER request !");
1596 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1599 osip_from_t *from=NULL;
1601 osip_from_init(&from);
1603 if (osip_from_parse(from,h->hvalue)==0){
1605 osip_uri_header_t *uh=NULL;
1606 osip_header_t *referred_by=NULL;
1607 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1608 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1609 ms_message("Found replaces in Refer-To");
1611 ms_free(op->replaces);
1613 op->replaces=ms_strdup(uh->gvalue);
1615 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1616 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1617 if (op->referred_by)
1618 ms_free(op->referred_by);
1619 op->referred_by=ms_strdup(referred_by->hvalue);
1622 osip_uri_header_freelist(&from->url->url_headers);
1623 osip_from_to_str(from,&tmp);
1624 sal->callbacks.refer_received(sal,op,tmp);
1626 osip_from_free(from);
1629 eXosip_call_build_answer(ev->tid,202,&ans);
1631 eXosip_call_send_answer(ev->tid,202,ans);
1636 ms_warning("cannot do anything with the refer without destination\n");
1640 static void process_notify(Sal *sal, eXosip_event_t *ev){
1641 osip_header_t *h=NULL;
1643 SalOp *op=find_op(sal,ev);
1644 osip_message_t *ans=NULL;
1646 ms_message("Receiving NOTIFY request !");
1647 osip_from_to_str(ev->request->from,&from);
1648 osip_message_header_get_byname(ev->request,"Event",0,&h);
1650 osip_body_t *body=NULL;
1651 //osip_content_type_t *ct=NULL;
1652 osip_message_get_body(ev->request,0,&body);
1653 //ct=osip_message_get_content_type(ev->request);
1654 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1655 /*special handling of refer events*/
1656 if (body && body->body){
1657 osip_message_t *msg;
1658 osip_message_init(&msg);
1659 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1660 int code=osip_message_get_status_code(msg);
1662 sal->callbacks.notify_refer(op,SalReferTrying);
1663 }else if (code==200){
1664 sal->callbacks.notify_refer(op,SalReferSuccess);
1665 }else if (code>=400){
1666 sal->callbacks.notify_refer(op,SalReferFailed);
1669 osip_message_free(msg);
1672 /*generic handling*/
1673 sal->callbacks.notify(op,from,h->hvalue);
1676 /*answer that we received the notify*/
1678 eXosip_call_build_answer(ev->tid,200,&ans);
1680 eXosip_call_send_answer(ev->tid,200,ans);
1685 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1686 osip_message_t *ans=NULL;
1688 if (MSG_IS_INFO(ev->request)){
1689 osip_content_type_t *ct;
1690 ct=osip_message_get_content_type(ev->request);
1691 if (ct && ct->subtype){
1692 if (strcmp(ct->subtype,"media_control+xml")==0)
1693 process_media_control_xml(sal,ev);
1694 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1695 process_dtmf_relay(sal,ev);
1697 ms_message("Unhandled SIP INFO.");
1698 /*send an "Not implemented" answer*/
1700 eXosip_call_build_answer(ev->tid,501,&ans);
1702 eXosip_call_send_answer(ev->tid,501,ans);
1706 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1708 eXosip_call_build_answer(ev->tid,200,&ans);
1710 eXosip_call_send_answer(ev->tid,200,ans);
1713 }else if(MSG_IS_MESSAGE(ev->request)){
1714 /* SIP messages could be received into call */
1715 text_received(sal, ev);
1717 eXosip_call_build_answer(ev->tid,200,&ans);
1719 eXosip_call_send_answer(ev->tid,200,ans);
1721 }else if(MSG_IS_REFER(ev->request)){
1722 SalOp *op=find_op(sal,ev);
1724 ms_message("Receiving REFER request !");
1725 process_refer(sal,op,ev);
1726 }else if(MSG_IS_NOTIFY(ev->request)){
1727 process_notify(sal,ev);
1728 }else if (MSG_IS_OPTIONS(ev->request)){
1730 eXosip_call_build_answer(ev->tid,200,&ans);
1732 fill_options_answer(ans);
1733 eXosip_call_send_answer(ev->tid,200,ans);
1737 }else ms_warning("call_message_new: No request ?");
1740 static void inc_update(Sal *sal, eXosip_event_t *ev){
1741 osip_message_t *msg=NULL;
1742 ms_message("Processing incoming UPDATE");
1744 eXosip_message_build_answer(ev->tid,200,&msg);
1746 eXosip_message_send_answer(ev->tid,200,msg);
1750 static bool_t comes_from_local_if(osip_message_t *msg){
1751 osip_via_t *via=NULL;
1752 osip_message_get_via(msg,0,&via);
1755 host=osip_via_get_host(via);
1756 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1757 osip_generic_param_t *param=NULL;
1758 osip_via_param_get_byname(via,"received",¶m);
1759 if (param==NULL) return TRUE;
1760 if (param->gvalue &&
1761 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1769 static void text_received(Sal *sal, eXosip_event_t *ev){
1770 osip_body_t *body=NULL;
1771 char *from=NULL,*msg=NULL;
1772 osip_content_type_t* content_type;
1773 osip_uri_param_t* external_body_url;
1774 char unquoted_external_body_url [256];
1775 int external_body_size=0;
1777 char message_id[256]={0};
1779 content_type= osip_message_get_content_type(ev->request);
1780 if (!content_type) {
1781 ms_error("Could not get message because no content type");
1784 osip_from_to_str(ev->request->from,&from);
1785 if (content_type->type
1786 && strcmp(content_type->type, "text")==0
1787 && content_type->subtype
1788 && strcmp(content_type->subtype, "plain")==0 ) {
1789 osip_message_get_body(ev->request,0,&body);
1791 ms_error("Could not get text message from SIP body");
1796 }else if (content_type->type
1797 && strcmp(content_type->type, "message")==0
1798 && content_type->subtype
1799 && strcmp(content_type->subtype, "external-body")==0 ) {
1801 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1802 /*remove both first and last character*/
1803 strncpy(unquoted_external_body_url
1804 ,&external_body_url->gvalue[1]
1805 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1806 unquoted_external_body_url[external_body_size-1]='\0';
1808 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1812 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1816 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1817 salmsg.message_id=message_id;
1818 sal->callbacks.text_received(sal,&salmsg);
1824 static void other_request(Sal *sal, eXosip_event_t *ev){
1825 ms_message("in other_request");
1826 if (ev->request==NULL) return;
1827 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1828 text_received(sal,ev);
1829 eXosip_message_send_answer(ev->tid,200,NULL);
1830 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1831 osip_message_t *options=NULL;
1832 eXosip_options_build_answer(ev->tid,200,&options);
1833 fill_options_answer(options);
1834 eXosip_options_send_answer(ev->tid,200,options);
1835 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1836 ms_message("Receiving REFER request !");
1837 if (comes_from_local_if(ev->request)) {
1838 process_refer(sal,NULL,ev);
1839 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1840 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1845 osip_message_to_str(ev->request,&tmp,&msglen);
1847 ms_message("Unsupported request received:\n%s",tmp);
1850 /*answer with a 501 Not implemented*/
1851 eXosip_message_send_answer(ev->tid,501,NULL);
1855 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1856 osip_via_t *via=NULL;
1857 osip_message_get_via(msg,0,&via);
1859 osip_free(via->port);
1860 via->port=osip_strdup(port);
1861 osip_free(via->host);
1862 via->host=osip_strdup(ip);
1867 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1868 osip_contact_t *ctt=NULL;
1869 const char *received;
1871 SalTransport transport;
1874 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1875 osip_message_get_contact(request,0,&ctt);
1877 ms_warning("fix_message_contact(): no contact to update");
1880 if (expire_last_contact){
1881 osip_contact_t *oldct=NULL,*prevct;
1882 osip_generic_param_t *param=NULL;
1883 osip_contact_clone(ctt,&oldct);
1884 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1885 osip_contact_free(prevct);
1886 osip_list_remove(&request->contacts,1);
1888 osip_list_add(&request->contacts,oldct,1);
1889 osip_contact_param_get_byname(oldct,"expires",¶m);
1891 if (param->gvalue) osip_free(param->gvalue);
1892 param->gvalue=osip_strdup("0");
1894 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1897 if (ctt->url->host!=NULL){
1898 osip_free(ctt->url->host);
1900 ctt->url->host=osip_strdup(received);
1901 if (ctt->url->port!=NULL){
1902 osip_free(ctt->url->port);
1904 snprintf(port,sizeof(port),"%i",rport);
1905 ctt->url->port=osip_strdup(port);
1906 if (op->masquerade_via) masquerade_via(request,received,port);
1908 if (transport != SalTransportUDP) {
1909 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1914 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1915 osip_contact_t *ctt=NULL;
1916 SalAddress* ori_contact_address=NULL;
1917 const char *received;
1919 SalTransport transport;
1921 osip_message_t *msg=NULL;
1922 Sal* sal=op->base.root;
1924 bool_t found_valid_contact=FALSE;
1925 bool_t from_request=FALSE;
1927 if (sal->double_reg==FALSE ) return FALSE;
1929 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1932 osip_message_get_contact(last_answer,i,&ctt);
1933 if (!from_request && ctt==NULL) {
1934 osip_message_get_contact(orig_request,0,&ctt);
1938 osip_contact_to_str(ctt,&tmp);
1939 ori_contact_address = sal_address_new(tmp);
1941 /*check if contact is up to date*/
1942 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1943 && sal_address_get_port_int(ori_contact_address) == rport
1944 && sal_address_get_transport(ori_contact_address) == transport) {
1946 ms_message("Register response has up to date contact, doing nothing.");
1948 ms_warning("Register response does not have up to date contact, but last request had."
1949 "Stupid registrar detected, giving up.");
1951 found_valid_contact=TRUE;
1954 sal_address_destroy(ori_contact_address);
1957 }while(!found_valid_contact);
1958 if (!found_valid_contact)
1959 ms_message("Contact do not match, resending register.");
1963 eXosip_register_build_register(op->rid,op->expires,&msg);
1966 ms_warning("Fail to create a contact updated register.");
1969 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1970 eXosip_register_send_register(op->rid,msg);
1972 ms_message("Resending new register with updated contact");
1973 update_contact_from_response(op,last_answer);
1976 ms_warning("Fail to send updated register.");
1984 static void registration_success(Sal *sal, eXosip_event_t *ev){
1985 SalOp *op=sal_find_register(sal,ev->rid);
1986 osip_header_t *h=NULL;
1989 ms_error("Receiving register response for unknown operation");
1992 osip_message_get_expires(ev->request,0,&h);
1993 if (h!=NULL && atoi(h->hvalue)!=0){
1995 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1996 sal->callbacks.register_success(op,registered);
1999 sal->callbacks.register_success(op,FALSE);
2003 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
2005 const char *reason=NULL;
2006 SalOp *op=sal_find_register(sal,ev->rid);
2007 SalReason sr=SalReasonUnknown;
2008 SalError se=SalErrorUnknown;
2011 ms_error("Receiving register failure for unknown operation");
2015 status_code=osip_message_get_status_code(ev->response);
2016 reason=osip_message_get_reason_phrase(ev->response);
2018 switch(status_code){
2021 return process_authentication(sal,ev);
2023 case 423: /*interval too brief*/
2024 {/*retry with greater interval */
2025 osip_header_t *h=NULL;
2026 osip_message_t *msg=NULL;
2027 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
2028 if (h && h->hvalue && h->hvalue[0]!='\0'){
2029 int val=atoi(h->hvalue);
2030 if (val>op->expires)
2032 }else op->expires*=2;
2034 eXosip_register_build_register(op->rid,op->expires,&msg);
2035 eXosip_register_send_register(op->rid,msg);
2039 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2040 in vias, such as ekiga.net
2041 On the opposite, freephonie.net bugs when via are masqueraded.
2043 op->masquerade_via=TRUE;
2045 /* if contact is up to date, process the failure, otherwise resend a new register with
2046 updated contact first, just in case the faillure is due to incorrect contact */
2047 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2048 return TRUE; /*we are retrying with an updated contact*/
2049 if (status_code==403){
2051 sr=SalReasonForbidden;
2052 }else if (status_code==0){
2053 se=SalErrorNoResponse;
2055 sal->callbacks.register_failure(op,se,sr,reason);
2060 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2061 SalOp *op=find_op(sal,ev);
2063 ms_warning("other_request_reply(): Receiving response to unknown request.");
2067 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2068 update_contact_from_response(op,ev->response);
2069 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2070 sal->callbacks.ping_reply(op);
2072 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2073 /*out of call message acknolegment*/
2074 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2076 if (ev->response->status_code<200){
2077 status=SalTextDeliveryInProgress;
2078 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2079 status=SalTextDeliveryDone;
2082 sal->callbacks.text_delivery_update(op,status);
2086 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2087 SalOp *op=find_op(sal,ev);
2089 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2090 if (op->sipfrag_pending){
2091 send_notify_for_refer(op->did,op->sipfrag_pending);
2092 op->sipfrag_pending=NULL;
2098 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2099 ms_message("linphone process event get a message %d\n",ev->type);
2101 case EXOSIP_CALL_ANSWERED:
2102 ms_message("CALL_ANSWERED\n");
2103 call_accepted(sal,ev);
2104 authentication_ok(sal,ev);
2106 case EXOSIP_CALL_CLOSED:
2107 case EXOSIP_CALL_CANCELLED:
2108 ms_message("CALL_CLOSED or CANCELLED\n");
2109 call_terminated(sal,ev);
2111 case EXOSIP_CALL_TIMEOUT:
2112 case EXOSIP_CALL_NOANSWER:
2113 ms_message("CALL_TIMEOUT or NOANSWER\n");
2114 return call_failure(sal,ev);
2116 case EXOSIP_CALL_REQUESTFAILURE:
2117 case EXOSIP_CALL_GLOBALFAILURE:
2118 case EXOSIP_CALL_SERVERFAILURE:
2119 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2120 return call_failure(sal,ev);
2122 case EXOSIP_CALL_RELEASED:
2123 ms_message("CALL_RELEASED\n");
2124 call_released(sal, ev);
2126 case EXOSIP_CALL_INVITE:
2127 ms_message("CALL_NEW\n");
2128 inc_new_call(sal,ev);
2130 case EXOSIP_CALL_REINVITE:
2131 handle_reinvite(sal,ev);
2133 case EXOSIP_CALL_ACK:
2134 ms_message("CALL_ACK");
2137 case EXOSIP_CALL_REDIRECTED:
2138 ms_message("CALL_REDIRECTED");
2139 eXosip_default_action(ev);
2141 case EXOSIP_CALL_PROCEEDING:
2142 ms_message("CALL_PROCEEDING");
2143 call_proceeding(sal,ev);
2145 case EXOSIP_CALL_RINGING:
2146 ms_message("CALL_RINGING");
2147 call_ringing(sal,ev);
2148 authentication_ok(sal,ev);
2150 case EXOSIP_CALL_MESSAGE_NEW:
2151 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2152 call_message_new(sal,ev);
2154 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2156 (ev->response->status_code==407 || ev->response->status_code==401)){
2157 return process_authentication(sal,ev);
2160 case EXOSIP_CALL_MESSAGE_ANSWERED:
2161 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2162 process_in_call_reply(sal,ev);
2164 case EXOSIP_IN_SUBSCRIPTION_NEW:
2165 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2166 sal_exosip_subscription_recv(sal,ev);
2168 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2169 ms_message("CALL_SUBSCRIPTION_NEW ");
2170 sal_exosip_in_subscription_closed(sal,ev);
2172 case EXOSIP_SUBSCRIPTION_UPDATE:
2173 ms_message("CALL_SUBSCRIPTION_UPDATE");
2175 case EXOSIP_SUBSCRIPTION_NOTIFY:
2176 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2177 sal_exosip_notify_recv(sal,ev);
2179 case EXOSIP_SUBSCRIPTION_ANSWERED:
2180 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2181 sal_exosip_subscription_answered(sal,ev);
2183 case EXOSIP_SUBSCRIPTION_CLOSED:
2184 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2185 sal_exosip_subscription_closed(sal,ev);
2187 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2188 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2189 return process_authentication(sal,ev);
2191 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2192 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2193 sal_exosip_subscription_closed(sal,ev);
2195 case EXOSIP_REGISTRATION_FAILURE:
2196 ms_message("REGISTRATION_FAILURE\n");
2197 return registration_failure(sal,ev);
2199 case EXOSIP_REGISTRATION_SUCCESS:
2200 authentication_ok(sal,ev);
2201 registration_success(sal,ev);
2203 case EXOSIP_MESSAGE_NEW:
2204 other_request(sal,ev);
2206 case EXOSIP_MESSAGE_PROCEEDING:
2207 case EXOSIP_MESSAGE_ANSWERED:
2208 case EXOSIP_MESSAGE_REDIRECTED:
2209 case EXOSIP_MESSAGE_SERVERFAILURE:
2210 case EXOSIP_MESSAGE_GLOBALFAILURE:
2211 other_request_reply(sal,ev);
2213 case EXOSIP_MESSAGE_REQUESTFAILURE:
2214 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2216 switch (ev->response->status_code) {
2219 return process_authentication(sal,ev);
2221 eXosip_automatic_action ();
2226 other_request_reply(sal,ev);
2229 ms_message("Unhandled exosip event ! %i",ev->type);
2235 int sal_iterate(Sal *sal){
2237 while((ev=eXosip_event_wait(0,0))!=NULL){
2238 if (process_event(sal,ev))
2239 eXosip_event_free(ev);
2241 #ifdef HAVE_EXOSIP_TRYLOCK
2242 if (eXosip_trylock()==0){
2243 eXosip_automatic_refresh();
2246 ms_warning("eXosip_trylock busy.");
2250 eXosip_automatic_refresh();
2256 static void register_set_contact(osip_message_t *msg, const char *contact){
2257 osip_uri_param_t *param = NULL;
2258 osip_contact_t *ct=NULL;
2260 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2261 osip_message_get_contact(msg,0,&ct);
2263 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2264 if (param && param->gvalue)
2265 line=osip_strdup(param->gvalue);
2267 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2268 osip_message_set_contact(msg,contact);
2269 osip_message_get_contact(msg,0,&ct);
2270 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2273 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2274 osip_route_t *route;
2276 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2278 osip_route_init(&route);
2279 if (osip_route_parse(route,proxy)==0){
2280 osip_uri_param_t *lr_param = NULL;
2281 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2282 if (lr_param == NULL){
2283 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2285 osip_list_add(&msg->routes,route,0);
2288 osip_route_free(route);
2292 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2293 osip_message_t *msg;
2294 const char *contact=sal_op_get_contact(h);
2296 sal_op_set_route(h,proxy);
2298 SalAddress *from_parsed=sal_address_new(from);
2300 char *uri, *domain_ptr = NULL;
2301 if (from_parsed==NULL) {
2302 ms_warning("sal_register() bad from %s",from);
2305 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2306 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2307 uri = sal_address_as_string_uri_only(from_parsed);
2308 if (uri) domain_ptr = strchr(uri, '@');
2310 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2312 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2314 if (uri) ms_free(uri);
2315 sal_address_destroy(from_parsed);
2317 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2319 if (contact) register_set_contact(msg,contact);
2320 sal_register_add_route(msg,proxy);
2321 sal_add_register(h->base.root,h);
2323 ms_error("Could not build initial register.");
2329 eXosip_register_build_register(h->rid,expires,&msg);
2330 sal_register_add_route(msg,proxy);
2333 eXosip_register_send_register(h->rid,msg);
2337 return (msg != NULL) ? 0 : -1;
2340 int sal_register_refresh(SalOp *op, int expires){
2341 osip_message_t *msg=NULL;
2342 const char *contact=sal_op_get_contact(op);
2345 ms_error("Unexistant registration context, not possible to refresh.");
2348 #ifdef HAVE_EXOSIP_TRYLOCK
2351 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2352 * 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
2353 * the exosip lock in a non blocking way, and give up if it takes too long*/
2354 while (eXosip_trylock()!=0){
2356 if (tries>30) {/*after 3 seconds, give up*/
2357 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2365 eXosip_register_build_register(op->rid,expires,&msg);
2367 if (contact) register_set_contact(msg,contact);
2368 sal_register_add_route(msg,sal_op_get_route(op));
2369 eXosip_register_send_register(op->rid,msg);
2370 }else ms_error("Could not build REGISTER refresh message.");
2372 return (msg != NULL) ? 0 : -1;
2376 int sal_unregister(SalOp *h){
2377 osip_message_t *msg=NULL;
2379 eXosip_register_build_register(h->rid,0,&msg);
2380 if (msg) eXosip_register_send_register(h->rid,msg);
2381 else ms_warning("Could not build unREGISTER !");
2386 SalAddress * sal_address_new(const char *uri){
2388 osip_from_init(&from);
2390 // Remove front spaces
2391 while (uri[0]==' ') {
2395 if (osip_from_parse(from,uri)!=0){
2396 osip_from_free(from);
2399 if (from->displayname!=NULL && from->displayname[0]=='"'){
2400 char *unquoted=osip_strdup_without_quote(from->displayname);
2401 osip_free(from->displayname);
2402 from->displayname=unquoted;
2404 return (SalAddress*)from;
2407 SalAddress * sal_address_clone(const SalAddress *addr){
2408 osip_from_t *ret=NULL;
2409 osip_from_clone((osip_from_t*)addr,&ret);
2410 return (SalAddress*)ret;
2413 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2415 const char *sal_address_get_scheme(const SalAddress *addr){
2416 const osip_from_t *u=(const osip_from_t*)addr;
2417 return null_if_empty(u->url->scheme);
2420 const char *sal_address_get_display_name(const SalAddress* addr){
2421 const osip_from_t *u=(const osip_from_t*)addr;
2422 return null_if_empty(u->displayname);
2425 const char *sal_address_get_username(const SalAddress *addr){
2426 const osip_from_t *u=(const osip_from_t*)addr;
2427 return null_if_empty(u->url->username);
2430 const char *sal_address_get_domain(const SalAddress *addr){
2431 const osip_from_t *u=(const osip_from_t*)addr;
2432 return null_if_empty(u->url->host);
2435 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2436 osip_from_t *u=(osip_from_t*)addr;
2437 if (u->displayname!=NULL){
2438 osip_free(u->displayname);
2439 u->displayname=NULL;
2441 if (display_name!=NULL && display_name[0]!='\0'){
2442 u->displayname=osip_strdup(display_name);
2446 void sal_address_set_username(SalAddress *addr, const char *username){
2447 osip_from_t *uri=(osip_from_t*)addr;
2448 if (uri->url->username!=NULL){
2449 osip_free(uri->url->username);
2450 uri->url->username=NULL;
2453 uri->url->username=osip_strdup(username);
2456 void sal_address_set_domain(SalAddress *addr, const char *host){
2457 osip_from_t *uri=(osip_from_t*)addr;
2458 if (uri->url->host!=NULL){
2459 osip_free(uri->url->host);
2460 uri->url->host=NULL;
2463 uri->url->host=osip_strdup(host);
2466 void sal_address_set_port(SalAddress *addr, const char *port){
2467 osip_from_t *uri=(osip_from_t*)addr;
2468 if (uri->url->port!=NULL){
2469 osip_free(uri->url->port);
2470 uri->url->port=NULL;
2473 uri->url->port=osip_strdup(port);
2476 void sal_address_set_port_int(SalAddress *uri, int port){
2479 /*this is the default, special case to leave the port field blank*/
2480 sal_address_set_port(uri,NULL);
2483 snprintf(tmp,sizeof(tmp),"%i",port);
2484 sal_address_set_port(uri,tmp);
2487 void sal_address_clean(SalAddress *addr){
2488 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2489 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2492 char *sal_address_as_string(const SalAddress *u){
2494 osip_from_t *from=(osip_from_t *)u;
2495 char *old_displayname=NULL;
2496 /* hack to force use of quotes around the displayname*/
2497 if (from->displayname!=NULL
2498 && from->displayname[0]!='"'){
2499 old_displayname=from->displayname;
2500 from->displayname=osip_enquote(from->displayname);
2502 osip_from_to_str(from,&tmp);
2503 if (old_displayname!=NULL){
2504 ms_free(from->displayname);
2505 from->displayname=old_displayname;
2512 char *sal_address_as_string_uri_only(const SalAddress *u){
2513 char *tmp=NULL,*ret;
2514 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2519 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2520 osip_uri_param_t *param=NULL;
2521 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2523 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2525 osip_free(param->gvalue);
2526 param->gvalue=value ? osip_strdup(value) : NULL;
2531 void sal_address_destroy(SalAddress *u){
2532 osip_from_free((osip_from_t*)u);
2535 void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
2536 ctx->tcp_tls_keepalive = enabled;
2539 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2540 switch (ctx->transport) {
2541 case SalTransportUDP:
2542 ctx->keepalive_period = value;
2544 case SalTransportTCP:
2545 case SalTransportTLS:
2546 if (ctx->tcp_tls_keepalive) ctx->keepalive_period = value;
2547 else ctx->keepalive_period = -1;
2552 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
2554 unsigned int sal_get_keepalive_period(Sal *ctx) {
2555 return ctx->keepalive_period;
2558 const char * sal_address_get_port(const SalAddress *addr) {
2559 const osip_from_t *u=(const osip_from_t*)addr;
2560 return null_if_empty(u->url->port);
2563 int sal_address_get_port_int(const SalAddress *uri) {
2564 const char* port = sal_address_get_port(uri);
2571 SalTransport sal_address_get_transport(const SalAddress* addr) {
2572 const osip_from_t *u=(const osip_from_t*)addr;
2573 osip_uri_param_t *transport_param=NULL;
2574 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2575 if (transport_param == NULL){
2576 return SalTransportUDP;
2578 return sal_transport_parse(transport_param->gvalue);
2581 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2582 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2585 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2586 int sal_call_update(SalOp *h, const char *subject){
2588 osip_message_t *reinvite=NULL;
2591 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2596 osip_message_set_subject(reinvite,subject);
2597 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2598 if (h->base.contact){
2599 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2600 osip_message_set_contact(reinvite,h->base.contact);
2602 if (h->base.root->session_expires!=0){
2603 osip_message_set_header(reinvite, "Session-expires", "200");
2604 osip_message_set_supported(reinvite, "timer");
2606 if (h->base.local_media){
2607 h->sdp_offering=TRUE;
2608 set_sdp_from_desc(reinvite,h->base.local_media);
2609 }else h->sdp_offering=FALSE;
2611 err = eXosip_call_send_request(h->did, reinvite);
2615 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2616 ctx->reuse_authorization=value;