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->nstreams;++i){
593 if (h->result->streams[i].rtp_port>0){
594 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
595 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
596 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
597 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
598 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
599 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
601 if (h->result->streams[i].proto == SalProtoRtpSavp) {
602 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
610 int sal_call_is_offerer(const SalOp *h){
611 return h->sdp_offering;
614 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
616 sal_media_description_ref(desc);
617 if (h->base.local_media)
618 sal_media_description_unref(h->base.local_media);
619 h->base.local_media=desc;
620 if (h->base.remote_media){
621 /*case of an incoming call where we modify the local capabilities between the time
622 * the call is ringing and it is accepted (for example if you want to accept without video*/
623 /*reset the sdp answer so that it is computed again*/
625 sdp_message_free(h->sdp_answer);
632 int sal_call(SalOp *h, const char *from, const char *to){
635 osip_message_t *invite=NULL;
636 osip_call_id_t *callid;
637 sal_op_set_from(h,from);
639 sal_exosip_fix_route(h);
641 h->terminated = FALSE;
643 route = sal_op_get_route(h);
644 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
646 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
647 err, from, to, route);
650 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
651 if (h->base.contact){
652 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
653 osip_message_set_contact(invite,h->base.contact);
655 if (h->base.root->session_expires!=0){
656 osip_message_set_header(invite, "Session-expires", "200");
657 osip_message_set_supported(invite, "timer");
659 if (h->base.local_media){
660 h->sdp_offering=TRUE;
661 set_sdp_from_desc(invite,h->base.local_media);
662 }else h->sdp_offering=FALSE;
664 osip_message_set_header(invite,"Replaces",h->replaces);
666 osip_message_set_header(invite,"Referred-By",h->referred_by);
670 err=eXosip_call_send_initial_invite(invite);
674 ms_error("Fail to send invite ! Error code %d", err);
677 callid=osip_message_get_call_id(invite);
678 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
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_replaces(SalOp *op, osip_message_t *req){
1021 osip_header_t *h=NULL;
1024 ms_free(op->replaces);
1027 osip_message_header_get_byname(req,"replaces",0,&h);
1029 if (h->hvalue && h->hvalue[0]!='\0'){
1030 op->replaces=ms_strdup(h->hvalue);
1035 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1037 return sal_find_call(sal,ev->cid);
1040 return sal_find_register(sal,ev->rid);
1043 return sal_find_out_subscribe(sal,ev->sid);
1046 return sal_find_in_subscribe(sal,ev->nid);
1048 if (ev->response) return sal_find_other(sal,ev->response);
1049 else if (ev->request) return sal_find_other(sal,ev->request);
1053 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1054 SalOp *op=sal_op_new(sal);
1055 osip_from_t *from,*to;
1056 osip_call_info_t *call_info;
1058 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1059 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1060 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1062 set_network_origin(op,ev->request);
1063 set_remote_ua(op,ev->request);
1064 set_replaces(op,ev->request);
1067 op->sdp_offering=FALSE;
1068 op->base.remote_media=sal_media_description_new();
1069 sdp_to_media_description(sdp,op->base.remote_media);
1070 sdp_message_free(sdp);
1071 }else op->sdp_offering=TRUE;
1073 from=osip_message_get_from(ev->request);
1074 to=osip_message_get_to(ev->request);
1075 osip_from_to_str(from,&tmp);
1076 sal_op_set_from(op,tmp);
1078 osip_from_to_str(to,&tmp);
1079 sal_op_set_to(op,tmp);
1082 osip_message_get_call_info(ev->request,0,&call_info);
1085 osip_call_info_to_str(call_info,&tmp);
1086 if( strstr(tmp,"answer-after=") != NULL)
1088 op->auto_answer_asked=TRUE;
1089 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1097 sal_add_call(op->base.root,op);
1098 sal->callbacks.call_received(op);
1101 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1102 SalOp *op=find_op(sal,ev);
1106 ms_warning("Reinvite for non-existing operation !");
1111 sdp=eXosip_get_sdp_info(ev->request);
1112 if (op->base.remote_media){
1113 sal_media_description_unref(op->base.remote_media);
1114 op->base.remote_media=NULL;
1117 sal_media_description_unref(op->result);
1121 op->sdp_offering=FALSE;
1122 op->base.remote_media=sal_media_description_new();
1123 sdp_to_media_description(sdp,op->base.remote_media);
1124 sdp_message_free(sdp);
1127 op->sdp_offering=TRUE;
1129 sal->callbacks.call_updating(op);
1132 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1133 SalOp *op=find_op(sal,ev);
1137 ms_warning("ack for non-existing call !");
1140 if (op->terminated) {
1141 ms_warning("ack for terminated call, ignoring");
1145 if (op->sdp_offering){
1146 sdp=eXosip_get_sdp_info(ev->ack);
1148 if (op->base.remote_media)
1149 sal_media_description_unref(op->base.remote_media);
1150 op->base.remote_media=sal_media_description_new();
1151 sdp_to_media_description(sdp,op->base.remote_media);
1153 sdp_message_free(sdp);
1159 sal->callbacks.call_ack(op);
1162 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1163 const char *received;
1165 SalTransport transport;
1166 if (extract_received_rport(response,&received,&rport,&transport)==0){
1167 const char *contact=sal_op_get_contact(op);
1169 /*no contact given yet, use from instead*/
1170 contact=sal_op_get_from(op);
1173 SalAddress *addr=sal_address_new(contact);
1175 sal_address_set_domain(addr,received);
1176 sal_address_set_port_int(addr,rport);
1177 if (transport!=SalTransportUDP)
1178 sal_address_set_transport(addr,transport);
1179 tmp=sal_address_as_string(addr);
1180 ms_message("Contact address updated to %s",tmp);
1181 sal_op_set_contact(op,tmp);
1182 sal_address_destroy(addr);
1188 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1189 SalOp *op=find_op(sal,ev);
1191 if (op==NULL || op->terminated==TRUE) {
1192 ms_warning("This call has been canceled.");
1194 eXosip_call_terminate(ev->cid,ev->did);
1202 /* update contact if received and rport are set by the server
1203 note: will only be used by remote for next INVITE, if any...*/
1204 update_contact_from_response(op,ev->response);
1208 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1210 SalOp *op=find_op(sal,ev);
1211 if (call_proceeding(sal, ev)==-1) return;
1213 set_remote_ua(op,ev->response);
1214 sdp=eXosip_get_sdp_info(ev->response);
1216 op->base.remote_media=sal_media_description_new();
1217 sdp_to_media_description(sdp,op->base.remote_media);
1218 sdp_message_free(sdp);
1219 if (op->base.local_media) sdp_process(op);
1221 sal->callbacks.call_ringing(op);
1224 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1226 osip_message_t *msg=NULL;
1227 SalOp *op=find_op(sal,ev);
1228 const char *contact;
1230 if (op==NULL || op->terminated==TRUE) {
1231 ms_warning("This call has been already terminated.");
1233 eXosip_call_terminate(ev->cid,ev->did);
1239 set_remote_ua(op,ev->response);
1241 sdp=eXosip_get_sdp_info(ev->response);
1243 op->base.remote_media=sal_media_description_new();
1244 sdp_to_media_description(sdp,op->base.remote_media);
1245 sdp_message_free(sdp);
1246 if (op->base.local_media) sdp_process(op);
1248 eXosip_call_build_ack(ev->did,&msg);
1250 ms_warning("This call has been already terminated.");
1252 eXosip_call_terminate(ev->cid,ev->did);
1256 contact=sal_op_get_contact(op);
1258 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1259 osip_message_set_contact(msg,contact);
1261 if (op->sdp_answer){
1262 set_sdp(msg,op->sdp_answer);
1263 sdp_message_free(op->sdp_answer);
1264 op->sdp_answer=NULL;
1266 eXosip_call_send_ack(ev->did,msg);
1267 sal->callbacks.call_accepted(op);
1270 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1272 SalOp *op=find_op(sal,ev);
1274 ms_warning("Call terminated for already closed call ?");
1278 osip_from_to_str(ev->request->from,&from);
1280 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1281 if (from) osip_free(from);
1282 op->terminated=TRUE;
1285 static void call_released(Sal *sal, eXosip_event_t *ev){
1286 SalOp *op=find_op(sal,ev);
1288 ms_warning("No op associated to this call_released()");
1291 if (!op->terminated){
1292 /* no response received so far */
1293 call_failure(sal,ev);
1295 sal->callbacks.call_released(op);
1298 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1299 const char *prx_realm=NULL,*www_realm=NULL;
1300 osip_proxy_authenticate_t *prx_auth;
1301 osip_www_authenticate_t *www_auth;
1303 *username=osip_uri_get_username(resp->from->url);
1304 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1305 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1307 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1309 www_realm=osip_www_authenticate_get_realm(www_auth);
1313 }else if (www_realm){
1321 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1322 osip_authorization_t *auth=NULL;
1323 osip_proxy_authorization_t *prx_auth=NULL;
1325 *username=osip_uri_get_username(msg->from->url);
1326 osip_message_get_authorization(msg, 0, &auth);
1328 *realm=osip_authorization_get_realm(auth);
1331 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1333 *realm=osip_proxy_authorization_get_realm(prx_auth);
1339 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1340 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1341 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1345 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1346 if (op->pending_auth){
1347 return get_auth_data(op->pending_auth,realm,username);
1352 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1354 const char *username,*realm;
1357 ms_warning("No operation associated with this authentication !");
1360 if (get_auth_data(ev,&realm,&username)==0){
1361 if (op->pending_auth!=NULL){
1362 eXosip_event_free(op->pending_auth);
1363 op->pending_auth=ev;
1365 op->pending_auth=ev;
1366 sal_add_pending_auth(sal,op);
1369 sal->callbacks.auth_requested(op,realm,username);
1375 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1377 const char *username,*realm;
1380 ms_warning("No operation associated with this authentication_ok!");
1383 if (op->pending_auth){
1384 eXosip_event_free(op->pending_auth);
1385 sal_remove_pending_auth(sal,op);
1386 op->pending_auth=NULL;
1388 if (get_auth_data(ev,&realm,&username)==0){
1389 sal->callbacks.auth_success(op,realm,username);
1393 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1396 char* computedReason=NULL;
1397 const char *reason=NULL;
1398 SalError error=SalErrorUnknown;
1399 SalReason sr=SalReasonUnknown;
1402 op=(SalOp*)find_op(sal,ev);
1405 ms_warning("Call failure reported for a closed call, ignored.");
1410 code=osip_message_get_status_code(ev->response);
1411 reason=osip_message_get_reason_phrase(ev->response);
1412 osip_header_t *h=NULL;
1413 if (!osip_message_header_get_byname( ev->response
1417 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1418 reason = computedReason;
1426 return process_authentication(sal,ev);
1429 error=SalErrorUnknown;
1432 error=SalErrorFailure;
1433 sr=SalReasonNotFound;
1436 error=SalErrorFailure;
1440 eXosip_default_action(ev);
1444 error=SalErrorFailure;
1445 sr=SalReasonTemporarilyUnavailable;
1447 error=SalErrorFailure;
1453 error=SalErrorFailure;
1454 sr=SalReasonDoNotDisturb;
1457 error=SalErrorFailure;
1458 sr=SalReasonDeclined;
1462 error=SalErrorFailure;
1463 sr=SalReasonUnknown;
1464 }else error=SalErrorNoResponse;
1466 op->terminated=TRUE;
1467 sal->callbacks.call_failure(op,error,sr,reason,code);
1468 if (computedReason != NULL){
1469 ms_free(computedReason);
1474 /* Request remote side to send us VFU */
1475 void sal_call_send_vfu_request(SalOp *h){
1476 osip_message_t *msg=NULL;
1478 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1482 " <picture_fast_update></picture_fast_update>"
1490 eXosip_call_build_info(h->did,&msg);
1492 osip_message_set_body(msg,info_body,strlen(info_body));
1493 osip_message_set_content_type(msg,"application/media_control+xml");
1494 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1495 osip_message_set_content_length(msg,clen);
1496 eXosip_call_send_request(h->did,msg);
1497 ms_message("Sending VFU request !");
1502 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1503 SalOp *op=find_op(sal,ev);
1504 osip_body_t *body=NULL;
1507 ms_warning("media control xml received without operation context!");
1511 osip_message_get_body(ev->request,0,&body);
1512 if (body && body->body!=NULL &&
1513 strstr(body->body,"picture_fast_update")){
1514 osip_message_t *ans=NULL;
1515 ms_message("Receiving VFU request !");
1516 if (sal->callbacks.vfu_request){
1517 sal->callbacks.vfu_request(op);
1518 eXosip_call_build_answer(ev->tid,200,&ans);
1520 eXosip_call_send_answer(ev->tid,200,ans);
1524 /*in all other cases we must say it is not implemented.*/
1526 osip_message_t *ans=NULL;
1528 eXosip_call_build_answer(ev->tid,501,&ans);
1530 eXosip_call_send_answer(ev->tid,501,ans);
1535 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1536 SalOp *op=find_op(sal,ev);
1537 osip_body_t *body=NULL;
1540 ms_warning("media dtmf relay received without operation context!");
1544 osip_message_get_body(ev->request,0,&body);
1545 if (body && body->body!=NULL){
1546 osip_message_t *ans=NULL;
1547 const char *name=strstr(body->body,"Signal");
1548 if (name==NULL) name=strstr(body->body,"signal");
1550 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1553 name+=strlen("signal");
1554 if (sscanf(name," = %1s",tmp)==1){
1555 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1556 if (sal->callbacks.dtmf_received != NULL)
1557 sal->callbacks.dtmf_received(op, tmp[0]);
1561 eXosip_call_build_answer(ev->tid,200,&ans);
1563 eXosip_call_send_answer(ev->tid,200,ans);
1568 static void fill_options_answer(osip_message_t *options){
1569 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1570 osip_message_set_accept(options,"application/sdp");
1573 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1574 osip_header_t *h=NULL;
1575 osip_message_t *ans=NULL;
1576 ms_message("Receiving REFER request !");
1577 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1580 osip_from_t *from=NULL;
1582 osip_from_init(&from);
1584 if (osip_from_parse(from,h->hvalue)==0){
1586 osip_uri_header_t *uh=NULL;
1587 osip_header_t *referred_by=NULL;
1588 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1589 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1590 ms_message("Found replaces in Refer-To");
1592 ms_free(op->replaces);
1594 op->replaces=ms_strdup(uh->gvalue);
1596 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1597 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1598 if (op->referred_by)
1599 ms_free(op->referred_by);
1600 op->referred_by=ms_strdup(referred_by->hvalue);
1603 osip_uri_header_freelist(&from->url->url_headers);
1604 osip_from_to_str(from,&tmp);
1605 sal->callbacks.refer_received(sal,op,tmp);
1607 osip_from_free(from);
1610 eXosip_call_build_answer(ev->tid,202,&ans);
1612 eXosip_call_send_answer(ev->tid,202,ans);
1617 ms_warning("cannot do anything with the refer without destination\n");
1621 static void process_notify(Sal *sal, eXosip_event_t *ev){
1622 osip_header_t *h=NULL;
1624 SalOp *op=find_op(sal,ev);
1625 osip_message_t *ans=NULL;
1627 ms_message("Receiving NOTIFY request !");
1628 osip_from_to_str(ev->request->from,&from);
1629 osip_message_header_get_byname(ev->request,"Event",0,&h);
1631 osip_body_t *body=NULL;
1632 //osip_content_type_t *ct=NULL;
1633 osip_message_get_body(ev->request,0,&body);
1634 //ct=osip_message_get_content_type(ev->request);
1635 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1636 /*special handling of refer events*/
1637 if (body && body->body){
1638 osip_message_t *msg;
1639 osip_message_init(&msg);
1640 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1641 int code=osip_message_get_status_code(msg);
1643 sal->callbacks.notify_refer(op,SalReferTrying);
1644 }else if (code==200){
1645 sal->callbacks.notify_refer(op,SalReferSuccess);
1646 }else if (code>=400){
1647 sal->callbacks.notify_refer(op,SalReferFailed);
1650 osip_message_free(msg);
1653 /*generic handling*/
1654 sal->callbacks.notify(op,from,h->hvalue);
1657 /*answer that we received the notify*/
1659 eXosip_call_build_answer(ev->tid,200,&ans);
1661 eXosip_call_send_answer(ev->tid,200,ans);
1666 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1667 osip_message_t *ans=NULL;
1669 if (MSG_IS_INFO(ev->request)){
1670 osip_content_type_t *ct;
1671 ct=osip_message_get_content_type(ev->request);
1672 if (ct && ct->subtype){
1673 if (strcmp(ct->subtype,"media_control+xml")==0)
1674 process_media_control_xml(sal,ev);
1675 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1676 process_dtmf_relay(sal,ev);
1678 ms_message("Unhandled SIP INFO.");
1679 /*send an "Not implemented" answer*/
1681 eXosip_call_build_answer(ev->tid,501,&ans);
1683 eXosip_call_send_answer(ev->tid,501,ans);
1687 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1689 eXosip_call_build_answer(ev->tid,200,&ans);
1691 eXosip_call_send_answer(ev->tid,200,ans);
1694 }else if(MSG_IS_MESSAGE(ev->request)){
1695 /* SIP messages could be received into call */
1696 text_received(sal, ev);
1698 eXosip_call_build_answer(ev->tid,200,&ans);
1700 eXosip_call_send_answer(ev->tid,200,ans);
1702 }else if(MSG_IS_REFER(ev->request)){
1703 SalOp *op=find_op(sal,ev);
1705 ms_message("Receiving REFER request !");
1706 process_refer(sal,op,ev);
1707 }else if(MSG_IS_NOTIFY(ev->request)){
1708 process_notify(sal,ev);
1709 }else if (MSG_IS_OPTIONS(ev->request)){
1711 eXosip_call_build_answer(ev->tid,200,&ans);
1713 fill_options_answer(ans);
1714 eXosip_call_send_answer(ev->tid,200,ans);
1718 }else ms_warning("call_message_new: No request ?");
1721 static void inc_update(Sal *sal, eXosip_event_t *ev){
1722 osip_message_t *msg=NULL;
1723 ms_message("Processing incoming UPDATE");
1725 eXosip_message_build_answer(ev->tid,200,&msg);
1727 eXosip_message_send_answer(ev->tid,200,msg);
1731 static bool_t comes_from_local_if(osip_message_t *msg){
1732 osip_via_t *via=NULL;
1733 osip_message_get_via(msg,0,&via);
1736 host=osip_via_get_host(via);
1737 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1738 osip_generic_param_t *param=NULL;
1739 osip_via_param_get_byname(via,"received",¶m);
1740 if (param==NULL) return TRUE;
1741 if (param->gvalue &&
1742 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1750 static void text_received(Sal *sal, eXosip_event_t *ev){
1751 osip_body_t *body=NULL;
1752 char *from=NULL,*msg=NULL;
1753 osip_content_type_t* content_type;
1754 osip_uri_param_t* external_body_url;
1755 char unquoted_external_body_url [256];
1756 int external_body_size=0;
1758 char message_id[256]={0};
1760 content_type= osip_message_get_content_type(ev->request);
1761 if (!content_type) {
1762 ms_error("Could not get message because no content type");
1765 osip_from_to_str(ev->request->from,&from);
1766 if (content_type->type
1767 && strcmp(content_type->type, "text")==0
1768 && content_type->subtype
1769 && strcmp(content_type->subtype, "plain")==0 ) {
1770 osip_message_get_body(ev->request,0,&body);
1772 ms_error("Could not get text message from SIP body");
1777 }else if (content_type->type
1778 && strcmp(content_type->type, "message")==0
1779 && content_type->subtype
1780 && strcmp(content_type->subtype, "external-body")==0 ) {
1782 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1783 /*remove both first and last character*/
1784 strncpy(unquoted_external_body_url
1785 ,&external_body_url->gvalue[1]
1786 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1787 unquoted_external_body_url[external_body_size-1]='\0';
1789 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1793 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1797 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1798 salmsg.message_id=message_id;
1799 sal->callbacks.text_received(sal,&salmsg);
1805 static void other_request(Sal *sal, eXosip_event_t *ev){
1806 ms_message("in other_request");
1807 if (ev->request==NULL) return;
1808 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1809 text_received(sal,ev);
1810 eXosip_message_send_answer(ev->tid,200,NULL);
1811 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1812 osip_message_t *options=NULL;
1813 eXosip_options_build_answer(ev->tid,200,&options);
1814 fill_options_answer(options);
1815 eXosip_options_send_answer(ev->tid,200,options);
1816 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1817 ms_message("Receiving REFER request !");
1818 if (comes_from_local_if(ev->request)) {
1819 process_refer(sal,NULL,ev);
1820 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1821 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1826 osip_message_to_str(ev->request,&tmp,&msglen);
1828 ms_message("Unsupported request received:\n%s",tmp);
1831 /*answer with a 501 Not implemented*/
1832 eXosip_message_send_answer(ev->tid,501,NULL);
1836 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1837 osip_via_t *via=NULL;
1838 osip_message_get_via(msg,0,&via);
1840 osip_free(via->port);
1841 via->port=osip_strdup(port);
1842 osip_free(via->host);
1843 via->host=osip_strdup(ip);
1848 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1849 osip_contact_t *ctt=NULL;
1850 const char *received;
1852 SalTransport transport;
1855 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1856 osip_message_get_contact(request,0,&ctt);
1858 ms_warning("fix_message_contact(): no contact to update");
1861 if (expire_last_contact){
1862 osip_contact_t *oldct=NULL,*prevct;
1863 osip_generic_param_t *param=NULL;
1864 osip_contact_clone(ctt,&oldct);
1865 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1866 osip_contact_free(prevct);
1867 osip_list_remove(&request->contacts,1);
1869 osip_list_add(&request->contacts,oldct,1);
1870 osip_contact_param_get_byname(oldct,"expires",¶m);
1872 if (param->gvalue) osip_free(param->gvalue);
1873 param->gvalue=osip_strdup("0");
1875 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1878 if (ctt->url->host!=NULL){
1879 osip_free(ctt->url->host);
1881 ctt->url->host=osip_strdup(received);
1882 if (ctt->url->port!=NULL){
1883 osip_free(ctt->url->port);
1885 snprintf(port,sizeof(port),"%i",rport);
1886 ctt->url->port=osip_strdup(port);
1887 if (op->masquerade_via) masquerade_via(request,received,port);
1889 if (transport != SalTransportUDP) {
1890 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1895 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1896 osip_contact_t *ctt=NULL;
1897 SalAddress* ori_contact_address=NULL;
1898 const char *received;
1900 SalTransport transport;
1902 osip_message_t *msg=NULL;
1903 Sal* sal=op->base.root;
1905 bool_t found_valid_contact=FALSE;
1906 bool_t from_request=FALSE;
1908 if (sal->double_reg==FALSE ) return FALSE;
1910 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1913 osip_message_get_contact(last_answer,i,&ctt);
1914 if (!from_request && ctt==NULL) {
1915 osip_message_get_contact(orig_request,0,&ctt);
1919 osip_contact_to_str(ctt,&tmp);
1920 ori_contact_address = sal_address_new(tmp);
1922 /*check if contact is up to date*/
1923 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1924 && sal_address_get_port_int(ori_contact_address) == rport
1925 && sal_address_get_transport(ori_contact_address) == transport) {
1927 ms_message("Register response has up to date contact, doing nothing.");
1929 ms_warning("Register response does not have up to date contact, but last request had."
1930 "Stupid registrar detected, giving up.");
1932 found_valid_contact=TRUE;
1935 sal_address_destroy(ori_contact_address);
1938 }while(!found_valid_contact);
1939 if (!found_valid_contact)
1940 ms_message("Contact do not match, resending register.");
1944 eXosip_register_build_register(op->rid,op->expires,&msg);
1947 ms_warning("Fail to create a contact updated register.");
1950 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1951 eXosip_register_send_register(op->rid,msg);
1953 ms_message("Resending new register with updated contact");
1954 update_contact_from_response(op,last_answer);
1957 ms_warning("Fail to send updated register.");
1965 static void registration_success(Sal *sal, eXosip_event_t *ev){
1966 SalOp *op=sal_find_register(sal,ev->rid);
1967 osip_header_t *h=NULL;
1970 ms_error("Receiving register response for unknown operation");
1973 osip_message_get_expires(ev->request,0,&h);
1974 if (h!=NULL && atoi(h->hvalue)!=0){
1976 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1977 sal->callbacks.register_success(op,registered);
1980 sal->callbacks.register_success(op,FALSE);
1984 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1986 const char *reason=NULL;
1987 SalOp *op=sal_find_register(sal,ev->rid);
1988 SalReason sr=SalReasonUnknown;
1989 SalError se=SalErrorUnknown;
1992 ms_error("Receiving register failure for unknown operation");
1996 status_code=osip_message_get_status_code(ev->response);
1997 reason=osip_message_get_reason_phrase(ev->response);
1999 switch(status_code){
2002 return process_authentication(sal,ev);
2004 case 423: /*interval too brief*/
2005 {/*retry with greater interval */
2006 osip_header_t *h=NULL;
2007 osip_message_t *msg=NULL;
2008 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
2009 if (h && h->hvalue && h->hvalue[0]!='\0'){
2010 int val=atoi(h->hvalue);
2011 if (val>op->expires)
2013 }else op->expires*=2;
2015 eXosip_register_build_register(op->rid,op->expires,&msg);
2016 eXosip_register_send_register(op->rid,msg);
2020 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2021 in vias, such as ekiga.net
2022 On the opposite, freephonie.net bugs when via are masqueraded.
2024 op->masquerade_via=TRUE;
2026 /* if contact is up to date, process the failure, otherwise resend a new register with
2027 updated contact first, just in case the faillure is due to incorrect contact */
2028 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2029 return TRUE; /*we are retrying with an updated contact*/
2030 if (status_code==403){
2032 sr=SalReasonForbidden;
2033 }else if (status_code==0){
2034 se=SalErrorNoResponse;
2036 sal->callbacks.register_failure(op,se,sr,reason);
2041 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2042 SalOp *op=find_op(sal,ev);
2044 ms_warning("other_request_reply(): Receiving response to unknown request.");
2048 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2049 update_contact_from_response(op,ev->response);
2050 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2051 sal->callbacks.ping_reply(op);
2053 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2054 /*out of call message acknolegment*/
2055 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2057 if (ev->response->status_code<200){
2058 status=SalTextDeliveryInProgress;
2059 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2060 status=SalTextDeliveryDone;
2063 sal->callbacks.text_delivery_update(op,status);
2067 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2068 SalOp *op=find_op(sal,ev);
2070 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2071 if (op->sipfrag_pending){
2072 send_notify_for_refer(op->did,op->sipfrag_pending);
2073 op->sipfrag_pending=NULL;
2079 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2080 ms_message("linphone process event get a message %d\n",ev->type);
2082 case EXOSIP_CALL_ANSWERED:
2083 ms_message("CALL_ANSWERED\n");
2084 call_accepted(sal,ev);
2085 authentication_ok(sal,ev);
2087 case EXOSIP_CALL_CLOSED:
2088 case EXOSIP_CALL_CANCELLED:
2089 ms_message("CALL_CLOSED or CANCELLED\n");
2090 call_terminated(sal,ev);
2092 case EXOSIP_CALL_TIMEOUT:
2093 case EXOSIP_CALL_NOANSWER:
2094 ms_message("CALL_TIMEOUT or NOANSWER\n");
2095 return call_failure(sal,ev);
2097 case EXOSIP_CALL_REQUESTFAILURE:
2098 case EXOSIP_CALL_GLOBALFAILURE:
2099 case EXOSIP_CALL_SERVERFAILURE:
2100 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2101 return call_failure(sal,ev);
2103 case EXOSIP_CALL_RELEASED:
2104 ms_message("CALL_RELEASED\n");
2105 call_released(sal, ev);
2107 case EXOSIP_CALL_INVITE:
2108 ms_message("CALL_NEW\n");
2109 inc_new_call(sal,ev);
2111 case EXOSIP_CALL_REINVITE:
2112 handle_reinvite(sal,ev);
2114 case EXOSIP_CALL_ACK:
2115 ms_message("CALL_ACK");
2118 case EXOSIP_CALL_REDIRECTED:
2119 ms_message("CALL_REDIRECTED");
2120 eXosip_default_action(ev);
2122 case EXOSIP_CALL_PROCEEDING:
2123 ms_message("CALL_PROCEEDING");
2124 call_proceeding(sal,ev);
2126 case EXOSIP_CALL_RINGING:
2127 ms_message("CALL_RINGING");
2128 call_ringing(sal,ev);
2129 authentication_ok(sal,ev);
2131 case EXOSIP_CALL_MESSAGE_NEW:
2132 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2133 call_message_new(sal,ev);
2135 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2137 (ev->response->status_code==407 || ev->response->status_code==401)){
2138 return process_authentication(sal,ev);
2141 case EXOSIP_CALL_MESSAGE_ANSWERED:
2142 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2143 process_in_call_reply(sal,ev);
2145 case EXOSIP_IN_SUBSCRIPTION_NEW:
2146 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2147 sal_exosip_subscription_recv(sal,ev);
2149 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2150 ms_message("CALL_SUBSCRIPTION_NEW ");
2151 sal_exosip_in_subscription_closed(sal,ev);
2153 case EXOSIP_SUBSCRIPTION_UPDATE:
2154 ms_message("CALL_SUBSCRIPTION_UPDATE");
2156 case EXOSIP_SUBSCRIPTION_NOTIFY:
2157 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2158 sal_exosip_notify_recv(sal,ev);
2160 case EXOSIP_SUBSCRIPTION_ANSWERED:
2161 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2162 sal_exosip_subscription_answered(sal,ev);
2164 case EXOSIP_SUBSCRIPTION_CLOSED:
2165 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2166 sal_exosip_subscription_closed(sal,ev);
2168 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2169 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2170 return process_authentication(sal,ev);
2172 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2173 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2174 sal_exosip_subscription_closed(sal,ev);
2176 case EXOSIP_REGISTRATION_FAILURE:
2177 ms_message("REGISTRATION_FAILURE\n");
2178 return registration_failure(sal,ev);
2180 case EXOSIP_REGISTRATION_SUCCESS:
2181 authentication_ok(sal,ev);
2182 registration_success(sal,ev);
2184 case EXOSIP_MESSAGE_NEW:
2185 other_request(sal,ev);
2187 case EXOSIP_MESSAGE_PROCEEDING:
2188 case EXOSIP_MESSAGE_ANSWERED:
2189 case EXOSIP_MESSAGE_REDIRECTED:
2190 case EXOSIP_MESSAGE_SERVERFAILURE:
2191 case EXOSIP_MESSAGE_GLOBALFAILURE:
2192 other_request_reply(sal,ev);
2194 case EXOSIP_MESSAGE_REQUESTFAILURE:
2195 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2197 switch (ev->response->status_code) {
2200 return process_authentication(sal,ev);
2202 eXosip_automatic_action ();
2207 other_request_reply(sal,ev);
2210 ms_message("Unhandled exosip event ! %i",ev->type);
2216 int sal_iterate(Sal *sal){
2218 while((ev=eXosip_event_wait(0,0))!=NULL){
2219 if (process_event(sal,ev))
2220 eXosip_event_free(ev);
2222 #ifdef HAVE_EXOSIP_TRYLOCK
2223 if (eXosip_trylock()==0){
2224 eXosip_automatic_refresh();
2227 ms_warning("eXosip_trylock busy.");
2231 eXosip_automatic_refresh();
2237 static void register_set_contact(osip_message_t *msg, const char *contact){
2238 osip_uri_param_t *param = NULL;
2239 osip_contact_t *ct=NULL;
2241 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2242 osip_message_get_contact(msg,0,&ct);
2244 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2245 if (param && param->gvalue)
2246 line=osip_strdup(param->gvalue);
2248 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2249 osip_message_set_contact(msg,contact);
2250 osip_message_get_contact(msg,0,&ct);
2251 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2254 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2255 osip_route_t *route;
2257 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2259 osip_route_init(&route);
2260 if (osip_route_parse(route,proxy)==0){
2261 osip_uri_param_t *lr_param = NULL;
2262 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2263 if (lr_param == NULL){
2264 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2266 osip_list_add(&msg->routes,route,0);
2269 osip_route_free(route);
2273 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2274 osip_message_t *msg;
2275 const char *contact=sal_op_get_contact(h);
2277 sal_op_set_route(h,proxy);
2279 SalAddress *from_parsed=sal_address_new(from);
2281 char *uri, *domain_ptr = NULL;
2282 if (from_parsed==NULL) {
2283 ms_warning("sal_register() bad from %s",from);
2286 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2287 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2288 uri = sal_address_as_string_uri_only(from_parsed);
2289 if (uri) domain_ptr = strchr(uri, '@');
2291 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2293 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2295 if (uri) ms_free(uri);
2296 sal_address_destroy(from_parsed);
2298 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2300 if (contact) register_set_contact(msg,contact);
2301 sal_register_add_route(msg,proxy);
2302 sal_add_register(h->base.root,h);
2304 ms_error("Could not build initial register.");
2310 eXosip_register_build_register(h->rid,expires,&msg);
2311 sal_register_add_route(msg,proxy);
2314 eXosip_register_send_register(h->rid,msg);
2318 return (msg != NULL) ? 0 : -1;
2321 int sal_register_refresh(SalOp *op, int expires){
2322 osip_message_t *msg=NULL;
2323 const char *contact=sal_op_get_contact(op);
2326 ms_error("Unexistant registration context, not possible to refresh.");
2329 #ifdef HAVE_EXOSIP_TRYLOCK
2332 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2333 * 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
2334 * the exosip lock in a non blocking way, and give up if it takes too long*/
2335 while (eXosip_trylock()!=0){
2337 if (tries>30) {/*after 3 seconds, give up*/
2338 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2346 eXosip_register_build_register(op->rid,expires,&msg);
2348 if (contact) register_set_contact(msg,contact);
2349 sal_register_add_route(msg,sal_op_get_route(op));
2350 eXosip_register_send_register(op->rid,msg);
2351 }else ms_error("Could not build REGISTER refresh message.");
2353 return (msg != NULL) ? 0 : -1;
2357 int sal_unregister(SalOp *h){
2358 osip_message_t *msg=NULL;
2360 eXosip_register_build_register(h->rid,0,&msg);
2361 if (msg) eXosip_register_send_register(h->rid,msg);
2362 else ms_warning("Could not build unREGISTER !");
2367 SalAddress * sal_address_new(const char *uri){
2369 osip_from_init(&from);
2371 // Remove front spaces
2372 while (uri[0]==' ') {
2376 if (osip_from_parse(from,uri)!=0){
2377 osip_from_free(from);
2380 if (from->displayname!=NULL && from->displayname[0]=='"'){
2381 char *unquoted=osip_strdup_without_quote(from->displayname);
2382 osip_free(from->displayname);
2383 from->displayname=unquoted;
2385 return (SalAddress*)from;
2388 SalAddress * sal_address_clone(const SalAddress *addr){
2389 osip_from_t *ret=NULL;
2390 osip_from_clone((osip_from_t*)addr,&ret);
2391 return (SalAddress*)ret;
2394 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2396 const char *sal_address_get_scheme(const SalAddress *addr){
2397 const osip_from_t *u=(const osip_from_t*)addr;
2398 return null_if_empty(u->url->scheme);
2401 const char *sal_address_get_display_name(const SalAddress* addr){
2402 const osip_from_t *u=(const osip_from_t*)addr;
2403 return null_if_empty(u->displayname);
2406 const char *sal_address_get_username(const SalAddress *addr){
2407 const osip_from_t *u=(const osip_from_t*)addr;
2408 return null_if_empty(u->url->username);
2411 const char *sal_address_get_domain(const SalAddress *addr){
2412 const osip_from_t *u=(const osip_from_t*)addr;
2413 return null_if_empty(u->url->host);
2416 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2417 osip_from_t *u=(osip_from_t*)addr;
2418 if (u->displayname!=NULL){
2419 osip_free(u->displayname);
2420 u->displayname=NULL;
2422 if (display_name!=NULL && display_name[0]!='\0'){
2423 u->displayname=osip_strdup(display_name);
2427 void sal_address_set_username(SalAddress *addr, const char *username){
2428 osip_from_t *uri=(osip_from_t*)addr;
2429 if (uri->url->username!=NULL){
2430 osip_free(uri->url->username);
2431 uri->url->username=NULL;
2434 uri->url->username=osip_strdup(username);
2437 void sal_address_set_domain(SalAddress *addr, const char *host){
2438 osip_from_t *uri=(osip_from_t*)addr;
2439 if (uri->url->host!=NULL){
2440 osip_free(uri->url->host);
2441 uri->url->host=NULL;
2444 uri->url->host=osip_strdup(host);
2447 void sal_address_set_port(SalAddress *addr, const char *port){
2448 osip_from_t *uri=(osip_from_t*)addr;
2449 if (uri->url->port!=NULL){
2450 osip_free(uri->url->port);
2451 uri->url->port=NULL;
2454 uri->url->port=osip_strdup(port);
2457 void sal_address_set_port_int(SalAddress *uri, int port){
2460 /*this is the default, special case to leave the port field blank*/
2461 sal_address_set_port(uri,NULL);
2464 snprintf(tmp,sizeof(tmp),"%i",port);
2465 sal_address_set_port(uri,tmp);
2468 void sal_address_clean(SalAddress *addr){
2469 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2470 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2473 char *sal_address_as_string(const SalAddress *u){
2475 osip_from_t *from=(osip_from_t *)u;
2476 char *old_displayname=NULL;
2477 /* hack to force use of quotes around the displayname*/
2478 if (from->displayname!=NULL
2479 && from->displayname[0]!='"'){
2480 old_displayname=from->displayname;
2481 from->displayname=osip_enquote(from->displayname);
2483 osip_from_to_str(from,&tmp);
2484 if (old_displayname!=NULL){
2485 ms_free(from->displayname);
2486 from->displayname=old_displayname;
2493 char *sal_address_as_string_uri_only(const SalAddress *u){
2494 char *tmp=NULL,*ret;
2495 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2500 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2501 osip_uri_param_t *param=NULL;
2502 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2504 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2506 osip_free(param->gvalue);
2507 param->gvalue=value ? osip_strdup(value) : NULL;
2512 void sal_address_destroy(SalAddress *u){
2513 osip_from_free((osip_from_t*)u);
2516 void sal_use_tcp_tls_keepalive(Sal *ctx, bool_t enabled) {
2517 ctx->tcp_tls_keepalive = enabled;
2520 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2521 switch (ctx->transport) {
2522 case SalTransportUDP:
2523 ctx->keepalive_period = value;
2525 case SalTransportTCP:
2526 case SalTransportTLS:
2527 if (ctx->tcp_tls_keepalive) ctx->keepalive_period = value;
2528 else ctx->keepalive_period = -1;
2533 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &ctx->keepalive_period);
2535 unsigned int sal_get_keepalive_period(Sal *ctx) {
2536 return ctx->keepalive_period;
2539 const char * sal_address_get_port(const SalAddress *addr) {
2540 const osip_from_t *u=(const osip_from_t*)addr;
2541 return null_if_empty(u->url->port);
2544 int sal_address_get_port_int(const SalAddress *uri) {
2545 const char* port = sal_address_get_port(uri);
2552 SalTransport sal_address_get_transport(const SalAddress* addr) {
2553 const osip_from_t *u=(const osip_from_t*)addr;
2554 osip_uri_param_t *transport_param=NULL;
2555 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2556 if (transport_param == NULL){
2557 return SalTransportUDP;
2559 return sal_transport_parse(transport_param->gvalue);
2562 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2563 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2566 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2567 int sal_call_update(SalOp *h, const char *subject){
2569 osip_message_t *reinvite=NULL;
2572 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2577 osip_message_set_subject(reinvite,subject);
2578 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2579 if (h->base.contact){
2580 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2581 osip_message_set_contact(reinvite,h->base.contact);
2583 if (h->base.root->session_expires!=0){
2584 osip_message_set_header(reinvite, "Session-expires", "200");
2585 osip_message_set_supported(reinvite, "timer");
2587 if (h->base.local_media){
2588 h->sdp_offering=TRUE;
2589 set_sdp_from_desc(reinvite,h->base.local_media);
2590 }else h->sdp_offering=FALSE;
2592 err = eXosip_call_send_request(h->did, reinvite);
2596 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2597 ctx->reuse_authorization=value;