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->expire_old_contact=FALSE;
286 sal->add_dates=FALSE;
291 void sal_uninit(Sal* sal){
294 ms_free(sal->rootCa);
298 void sal_set_user_pointer(Sal *sal, void *user_data){
302 void *sal_get_user_pointer(const Sal *sal){
306 static void unimplemented_stub(){
307 ms_warning("Unimplemented SAL callback");
310 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
311 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
312 if (ctx->callbacks.call_received==NULL)
313 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
314 if (ctx->callbacks.call_ringing==NULL)
315 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
316 if (ctx->callbacks.call_accepted==NULL)
317 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
318 if (ctx->callbacks.call_failure==NULL)
319 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
320 if (ctx->callbacks.call_terminated==NULL)
321 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
322 if (ctx->callbacks.call_released==NULL)
323 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
324 if (ctx->callbacks.call_updating==NULL)
325 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
326 if (ctx->callbacks.auth_requested==NULL)
327 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
328 if (ctx->callbacks.auth_success==NULL)
329 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
330 if (ctx->callbacks.register_success==NULL)
331 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
332 if (ctx->callbacks.register_failure==NULL)
333 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
334 if (ctx->callbacks.dtmf_received==NULL)
335 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
336 if (ctx->callbacks.notify==NULL)
337 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
338 if (ctx->callbacks.notify_presence==NULL)
339 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
340 if (ctx->callbacks.subscribe_received==NULL)
341 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
342 if (ctx->callbacks.text_received==NULL)
343 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
344 if (ctx->callbacks.ping_reply==NULL)
345 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
346 if (ctx->callbacks.message_external_body==NULL)
347 ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)unimplemented_stub;
350 int sal_unlisten_ports(Sal *ctx){
359 int sal_reset_transports(Sal *ctx){
360 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
362 ms_message("Exosip transports reset.");
363 eXosip_reset_transports();
367 ms_warning("sal_reset_transports() not implemented in this version.");
373 static void set_tls_options(Sal *ctx){
375 eXosip_tls_ctx_t tlsCtx;
376 memset(&tlsCtx, 0, sizeof(tlsCtx));
377 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
378 eXosip_set_tls_ctx(&tlsCtx);
380 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
381 eXosip_tls_verify_certificate(ctx->verify_server_certs);
385 void sal_set_dscp(Sal *ctx, int dscp){
388 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
391 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
394 int proto=IPPROTO_UDP;
395 int keepalive = ctx->keepalive_period;
398 case SalTransportUDP:
400 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
402 case SalTransportTCP:
403 case SalTransportTLS:
406 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
407 set_tls_options(ctx);
410 ms_warning("unexpected proto, using datagram");
412 /*see if it looks like an IPv6 address*/
413 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
414 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
415 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
416 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
417 sal_set_dscp(ctx,ctx->dscp);
419 ipv6=strchr(addr,':')!=NULL;
420 eXosip_enable_ipv6(ipv6);
422 if (is_secure && tr == SalTransportUDP){
423 ms_fatal("SIP over DTLS is not supported yet.");
426 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
431 ortp_socket_t sal_get_socket(Sal *ctx){
432 #ifdef HAVE_EXOSIP_GET_SOCKET
433 return eXosip_get_socket(IPPROTO_UDP);
435 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
440 void sal_set_user_agent(Sal *ctx, const char *user_agent){
441 eXosip_set_user_agent(user_agent);
444 void sal_use_session_timers(Sal *ctx, int expires){
445 ctx->session_expires=expires;
448 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
449 ctx->one_matching_codec=one_matching_codec;
452 MSList *sal_get_pending_auths(Sal *sal){
453 return ms_list_copy(sal->pending_auths);
456 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
457 ctx->double_reg=enabled;
460 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
461 ctx->expire_old_contact=enabled;
464 void sal_use_dates(Sal *ctx, bool_t enabled){
465 ctx->add_dates=enabled;
468 void sal_use_rport(Sal *ctx, bool_t use_rports){
469 ctx->use_rports=use_rports;
471 void sal_use_101(Sal *ctx, bool_t use_101){
472 ctx->use_101=use_101;
475 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
477 ms_free(ctx->rootCa);
478 ctx->rootCa = ms_strdup(rootCa);
479 set_tls_options(ctx);
482 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
483 ctx->verify_server_certs=verify;
484 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
485 eXosip_tls_verify_certificate(verify);
489 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
490 osip_via_t *via=NULL;
491 osip_generic_param_t *param=NULL;
492 const char *rport=NULL;
496 osip_message_get_via(msg,0,&via);
498 ms_warning("extract_received_rport(): no via.");
502 *transport = sal_transport_parse(via->protocol);
504 if (via->port && via->port[0]!='\0')
505 *rportval=atoi(via->port);
507 osip_via_param_get_byname(via,"rport",¶m);
510 if (rport && rport[0]!='\0') *rportval=atoi(rport);
514 osip_via_param_get_byname(via,"received",¶m);
515 if (param) *received=param->gvalue;
517 if (rport==NULL && *received==NULL){
518 ms_warning("extract_received_rport(): no rport and no received parameters.");
524 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
528 sdp_message_to_str(msg,&sdp);
530 snprintf(clen,sizeof(clen),"%i",sdplen);
531 osip_message_set_body(sip,sdp,sdplen);
532 osip_message_set_content_type(sip,"application/sdp");
533 osip_message_set_content_length(sip,clen);
537 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
538 sdp_message_t *msg=media_description_to_sdp(desc);
540 ms_error("Fail to print sdp message !");
544 sdp_message_free(msg);
547 static void sdp_process(SalOp *h){
548 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
550 sal_media_description_unref(h->result);
552 h->result=sal_media_description_new();
553 if (h->sdp_offering){
554 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
558 sdp_message_free(h->sdp_answer);
560 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
561 h->sdp_answer=media_description_to_sdp(h->result);
562 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
563 It should contains media parameters constraint from the remote offer, not our response*/
564 strcpy(h->result->addr,h->base.remote_media->addr);
565 h->result->bandwidth=h->base.remote_media->bandwidth;
567 for(i=0;i<h->result->nstreams;++i){
568 if (h->result->streams[i].rtp_port>0){
569 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
570 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
571 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
572 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
573 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
574 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
576 if (h->result->streams[i].proto == SalProtoRtpSavp) {
577 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
585 int sal_call_is_offerer(const SalOp *h){
586 return h->sdp_offering;
589 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
591 sal_media_description_ref(desc);
592 if (h->base.local_media)
593 sal_media_description_unref(h->base.local_media);
594 h->base.local_media=desc;
595 if (h->base.remote_media){
596 /*case of an incoming call where we modify the local capabilities between the time
597 * the call is ringing and it is accepted (for example if you want to accept without video*/
598 /*reset the sdp answer so that it is computed again*/
600 sdp_message_free(h->sdp_answer);
607 int sal_call(SalOp *h, const char *from, const char *to){
610 osip_message_t *invite=NULL;
611 osip_call_id_t *callid;
612 sal_op_set_from(h,from);
614 sal_exosip_fix_route(h);
616 h->terminated = FALSE;
618 route = sal_op_get_route(h);
619 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
621 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
622 err, from, to, route);
625 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
626 if (h->base.contact){
627 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
628 osip_message_set_contact(invite,h->base.contact);
630 if (h->base.root->session_expires!=0){
631 osip_message_set_header(invite, "Session-expires", "200");
632 osip_message_set_supported(invite, "timer");
634 if (h->base.local_media){
635 h->sdp_offering=TRUE;
636 set_sdp_from_desc(invite,h->base.local_media);
637 }else h->sdp_offering=FALSE;
639 osip_message_set_header(invite,"Replaces",h->replaces);
641 osip_message_set_header(invite,"Referred-By",h->referred_by);
645 err=eXosip_call_send_initial_invite(invite);
649 ms_error("Fail to send invite ! Error code %d", err);
652 callid=osip_message_get_call_id(invite);
653 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
654 sal_add_call(h->base.root,h);
659 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
662 /*if early media send also 180 and 183 */
666 eXosip_call_build_answer(h->tid,183,&msg);
670 set_sdp(msg,h->sdp_answer);
671 sdp_message_free(h->sdp_answer);
674 eXosip_call_send_answer(h->tid,183,msg);
679 eXosip_call_send_answer(h->tid,180,NULL);
685 int sal_call_accept(SalOp * h){
687 const char *contact=sal_op_get_contact(h);
689 int err=eXosip_call_build_answer(h->tid,200,&msg);
690 if (err<0 || msg==NULL){
691 ms_error("Fail to build answer for call: err=%i",err);
694 if (h->base.root->session_expires!=0){
695 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
699 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
700 osip_message_set_contact(msg,contact);
703 if (h->base.local_media){
704 /*this is the case where we received an invite without SDP*/
705 if (h->sdp_offering) {
706 set_sdp_from_desc(msg,h->base.local_media);
708 if (h->sdp_answer==NULL) sdp_process(h);
710 set_sdp(msg,h->sdp_answer);
711 sdp_message_free(h->sdp_answer);
716 ms_error("You are accepting a call but not defined any media capabilities !");
718 eXosip_call_send_answer(h->tid,200,msg);
722 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
723 if (reason==SalReasonBusy){
725 eXosip_call_send_answer(h->tid,486,NULL);
728 else if (reason==SalReasonTemporarilyUnavailable){
730 eXosip_call_send_answer(h->tid,480,NULL);
732 }else if (reason==SalReasonDoNotDisturb){
734 eXosip_call_send_answer(h->tid,600,NULL);
736 }else if (reason==SalReasonMedia){
738 eXosip_call_send_answer(h->tid,415,NULL);
740 }else if (redirect!=NULL && reason==SalReasonRedirect){
743 if (strstr(redirect,"sip:")!=0) code=302;
746 eXosip_call_build_answer(h->tid,code,&msg);
747 osip_message_set_contact(msg,redirect);
748 eXosip_call_send_answer(h->tid,code,msg);
750 }else sal_call_terminate(h);
754 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
755 return h->base.remote_media;
758 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
759 if (h->base.local_media && h->base.remote_media && !h->result){
765 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
766 if (refered_call->replaces)
767 h->replaces=ms_strdup(refered_call->replaces);
768 if (refered_call->referred_by)
769 h->referred_by=ms_strdup(refered_call->referred_by);
773 static int send_notify_for_refer(int did, const char *sipfrag){
776 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
779 ms_warning("Could not build NOTIFY for refer.");
782 osip_message_set_content_type(msg,"message/sipfrag");
783 osip_message_set_header(msg,"Event","refer");
784 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
785 eXosip_call_send_request(did,msg);
790 /* currently only support to notify trying and 200Ok*/
791 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
794 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
796 else if (newcall->cid!=-1){
797 if (newcall->did==-1){
798 /* not yet established*/
799 if (!newcall->terminated){
801 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
804 if (!newcall->terminated){
805 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
806 /* we need previous notify transaction to complete, so buffer the request for later*/
807 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
815 int sal_ping(SalOp *op, const char *from, const char *to){
816 osip_message_t *options=NULL;
818 sal_op_set_from(op,from);
819 sal_op_set_to(op,to);
820 sal_exosip_fix_route(op);
822 eXosip_options_build_request (&options, sal_op_get_to(op),
823 sal_op_get_from(op),sal_op_get_route(op));
825 if (op->base.root->session_expires!=0){
826 osip_message_set_header(options, "Session-expires", "200");
827 osip_message_set_supported(options, "timer");
829 sal_add_other(sal_op_get_sal(op),op,options);
830 return eXosip_options_send_request(options);
835 int sal_call_refer(SalOp *h, const char *refer_to){
836 osip_message_t *msg=NULL;
839 eXosip_call_build_refer(h->did,refer_to, &msg);
840 if (msg) err=eXosip_call_send_request(h->did, msg);
846 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
847 osip_message_t *msg=NULL;
848 char referto[256]={0};
851 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
852 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
856 eXosip_call_build_refer(h->did,referto, &msg);
857 osip_message_set_header(msg,"Referred-By",h->base.from);
858 if (msg) err=eXosip_call_send_request(h->did, msg);
864 SalOp *sal_call_get_replaces(SalOp *h){
865 if (h!=NULL && h->replaces!=NULL){
868 cid=eXosip_call_find_by_replaces(h->replaces);
871 SalOp *ret=sal_find_call(h->base.root,cid);
878 int sal_call_send_dtmf(SalOp *h, char dtmf){
879 osip_message_t *msg=NULL;
884 eXosip_call_build_info(h->did,&msg);
886 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
887 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
888 osip_message_set_content_type(msg,"application/dtmf-relay");
889 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
890 osip_message_set_content_length(msg,clen);
891 eXosip_call_send_request(h->did,msg);
897 static void push_auth_to_exosip(const SalAuthInfo *info){
899 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
900 else userid=info->userid;
901 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
902 eXosip_add_authentication_info (info->username,userid,
903 info->password, NULL,info->realm);
906 * Just for symmetry ;-)
908 static void pop_auth_from_exosip() {
909 eXosip_clear_authentication_info();
912 int sal_call_terminate(SalOp *h){
914 if (h == NULL) return -1;
915 if (h->auth_info) push_auth_to_exosip(h->auth_info);
917 err=eXosip_call_terminate(h->cid,h->did);
919 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
921 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
927 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
928 if (h->terminated) return;
929 if (h->pending_auth){
930 push_auth_to_exosip(info);
932 /*FIXME exosip does not take into account this update register message*/
934 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
938 update_contact_from_response(h,h->pending_auth->response);
940 eXosip_default_action(h->pending_auth);
942 ms_message("eXosip_default_action() done");
943 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
945 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
946 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
949 void sal_op_cancel_authentication(SalOp *h) {
951 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
952 } else if (h->cid >0) {
953 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
955 ms_warning("Auth failure not handled");
959 static void set_network_origin(SalOp *op, osip_message_t *req){
960 const char *received=NULL;
963 SalTransport transport;
964 if (extract_received_rport(req,&received,&rport,&transport)!=0){
965 osip_via_t *via=NULL;
967 osip_message_get_via(req,0,&via);
968 received=osip_via_get_host(via);
969 tmp=osip_via_get_port(via);
970 if (tmp) rport=atoi(tmp);
972 if (transport != SalTransportUDP) {
973 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
975 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
977 __sal_op_set_network_origin(op,origin);
980 static void set_remote_ua(SalOp* op, osip_message_t *req){
981 if (op->base.remote_ua==NULL){
982 osip_header_t *h=NULL;
983 osip_message_get_user_agent(req,0,&h);
985 op->base.remote_ua=ms_strdup(h->hvalue);
990 static void set_replaces(SalOp *op, osip_message_t *req){
991 osip_header_t *h=NULL;
994 ms_free(op->replaces);
997 osip_message_header_get_byname(req,"replaces",0,&h);
999 if (h->hvalue && h->hvalue[0]!='\0'){
1000 op->replaces=ms_strdup(h->hvalue);
1005 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1007 return sal_find_call(sal,ev->cid);
1010 return sal_find_register(sal,ev->rid);
1013 return sal_find_out_subscribe(sal,ev->sid);
1016 return sal_find_in_subscribe(sal,ev->nid);
1018 if (ev->response) return sal_find_other(sal,ev->response);
1019 else if (ev->request) return sal_find_other(sal,ev->request);
1023 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1024 SalOp *op=sal_op_new(sal);
1025 osip_from_t *from,*to;
1026 osip_call_info_t *call_info;
1028 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1029 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1030 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1032 set_network_origin(op,ev->request);
1033 set_remote_ua(op,ev->request);
1034 set_replaces(op,ev->request);
1037 op->sdp_offering=FALSE;
1038 op->base.remote_media=sal_media_description_new();
1039 sdp_to_media_description(sdp,op->base.remote_media);
1040 sdp_message_free(sdp);
1041 }else op->sdp_offering=TRUE;
1043 from=osip_message_get_from(ev->request);
1044 to=osip_message_get_to(ev->request);
1045 osip_from_to_str(from,&tmp);
1046 sal_op_set_from(op,tmp);
1048 osip_from_to_str(to,&tmp);
1049 sal_op_set_to(op,tmp);
1052 osip_message_get_call_info(ev->request,0,&call_info);
1055 osip_call_info_to_str(call_info,&tmp);
1056 if( strstr(tmp,"answer-after=") != NULL)
1058 op->auto_answer_asked=TRUE;
1059 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1067 sal_add_call(op->base.root,op);
1068 sal->callbacks.call_received(op);
1071 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1072 SalOp *op=find_op(sal,ev);
1076 ms_warning("Reinvite for non-existing operation !");
1081 sdp=eXosip_get_sdp_info(ev->request);
1082 if (op->base.remote_media){
1083 sal_media_description_unref(op->base.remote_media);
1084 op->base.remote_media=NULL;
1087 sal_media_description_unref(op->result);
1091 op->sdp_offering=FALSE;
1092 op->base.remote_media=sal_media_description_new();
1093 sdp_to_media_description(sdp,op->base.remote_media);
1094 sdp_message_free(sdp);
1097 op->sdp_offering=TRUE;
1099 sal->callbacks.call_updating(op);
1102 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1103 SalOp *op=find_op(sal,ev);
1107 ms_warning("ack for non-existing call !");
1110 if (op->terminated) {
1111 ms_warning("ack for terminated call, ignoring");
1115 if (op->sdp_offering){
1116 sdp=eXosip_get_sdp_info(ev->ack);
1118 if (op->base.remote_media)
1119 sal_media_description_unref(op->base.remote_media);
1120 op->base.remote_media=sal_media_description_new();
1121 sdp_to_media_description(sdp,op->base.remote_media);
1123 sdp_message_free(sdp);
1129 sal->callbacks.call_ack(op);
1132 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1133 const char *received;
1135 SalTransport transport;
1136 if (extract_received_rport(response,&received,&rport,&transport)==0){
1137 const char *contact=sal_op_get_contact(op);
1139 /*no contact given yet, use from instead*/
1140 contact=sal_op_get_from(op);
1143 SalAddress *addr=sal_address_new(contact);
1145 sal_address_set_domain(addr,received);
1146 sal_address_set_port_int(addr,rport);
1147 if (transport!=SalTransportUDP)
1148 sal_address_set_transport(addr,transport);
1149 tmp=sal_address_as_string(addr);
1150 ms_message("Contact address updated to %s",tmp);
1151 sal_op_set_contact(op,tmp);
1152 sal_address_destroy(addr);
1158 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1159 SalOp *op=find_op(sal,ev);
1161 if (op==NULL || op->terminated==TRUE) {
1162 ms_warning("This call has been canceled.");
1164 eXosip_call_terminate(ev->cid,ev->did);
1172 /* update contact if received and rport are set by the server
1173 note: will only be used by remote for next INVITE, if any...*/
1174 update_contact_from_response(op,ev->response);
1178 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1180 SalOp *op=find_op(sal,ev);
1181 if (call_proceeding(sal, ev)==-1) return;
1183 set_remote_ua(op,ev->response);
1184 sdp=eXosip_get_sdp_info(ev->response);
1186 op->base.remote_media=sal_media_description_new();
1187 sdp_to_media_description(sdp,op->base.remote_media);
1188 sdp_message_free(sdp);
1189 if (op->base.local_media) sdp_process(op);
1191 sal->callbacks.call_ringing(op);
1194 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1196 osip_message_t *msg=NULL;
1197 SalOp *op=find_op(sal,ev);
1198 const char *contact;
1200 if (op==NULL || op->terminated==TRUE) {
1201 ms_warning("This call has been already terminated.");
1203 eXosip_call_terminate(ev->cid,ev->did);
1209 set_remote_ua(op,ev->response);
1211 sdp=eXosip_get_sdp_info(ev->response);
1213 op->base.remote_media=sal_media_description_new();
1214 sdp_to_media_description(sdp,op->base.remote_media);
1215 sdp_message_free(sdp);
1216 if (op->base.local_media) sdp_process(op);
1218 eXosip_call_build_ack(ev->did,&msg);
1220 ms_warning("This call has been already terminated.");
1222 eXosip_call_terminate(ev->cid,ev->did);
1226 contact=sal_op_get_contact(op);
1228 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1229 osip_message_set_contact(msg,contact);
1231 if (op->sdp_answer){
1232 set_sdp(msg,op->sdp_answer);
1233 sdp_message_free(op->sdp_answer);
1234 op->sdp_answer=NULL;
1236 eXosip_call_send_ack(ev->did,msg);
1237 sal->callbacks.call_accepted(op);
1240 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1242 SalOp *op=find_op(sal,ev);
1244 ms_warning("Call terminated for already closed call ?");
1248 osip_from_to_str(ev->request->from,&from);
1250 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1251 if (from) osip_free(from);
1252 op->terminated=TRUE;
1255 static void call_released(Sal *sal, eXosip_event_t *ev){
1256 SalOp *op=find_op(sal,ev);
1258 ms_warning("No op associated to this call_released()");
1261 if (!op->terminated){
1262 /* no response received so far */
1263 call_failure(sal,ev);
1265 sal->callbacks.call_released(op);
1268 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1269 const char *prx_realm=NULL,*www_realm=NULL;
1270 osip_proxy_authenticate_t *prx_auth;
1271 osip_www_authenticate_t *www_auth;
1273 *username=osip_uri_get_username(resp->from->url);
1274 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1275 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1277 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1279 www_realm=osip_www_authenticate_get_realm(www_auth);
1283 }else if (www_realm){
1291 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1292 osip_authorization_t *auth=NULL;
1293 osip_proxy_authorization_t *prx_auth=NULL;
1295 *username=osip_uri_get_username(msg->from->url);
1296 osip_message_get_authorization(msg, 0, &auth);
1298 *realm=osip_authorization_get_realm(auth);
1301 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1303 *realm=osip_proxy_authorization_get_realm(prx_auth);
1309 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1310 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1311 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1315 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1316 if (op->pending_auth){
1317 return get_auth_data(op->pending_auth,realm,username);
1322 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1324 const char *username,*realm;
1327 ms_warning("No operation associated with this authentication !");
1330 if (get_auth_data(ev,&realm,&username)==0){
1331 if (op->pending_auth!=NULL){
1332 eXosip_event_free(op->pending_auth);
1333 op->pending_auth=ev;
1335 op->pending_auth=ev;
1336 sal_add_pending_auth(sal,op);
1339 sal->callbacks.auth_requested(op,realm,username);
1345 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1347 const char *username,*realm;
1350 ms_warning("No operation associated with this authentication_ok!");
1353 if (op->pending_auth){
1354 eXosip_event_free(op->pending_auth);
1355 sal_remove_pending_auth(sal,op);
1356 op->pending_auth=NULL;
1358 if (get_auth_data(ev,&realm,&username)==0){
1359 sal->callbacks.auth_success(op,realm,username);
1363 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1366 char* computedReason=NULL;
1367 const char *reason=NULL;
1368 SalError error=SalErrorUnknown;
1369 SalReason sr=SalReasonUnknown;
1372 op=(SalOp*)find_op(sal,ev);
1375 ms_warning("Call failure reported for a closed call, ignored.");
1380 code=osip_message_get_status_code(ev->response);
1381 reason=osip_message_get_reason_phrase(ev->response);
1382 osip_header_t *h=NULL;
1383 if (!osip_message_header_get_byname( ev->response
1387 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1388 reason = computedReason;
1396 return process_authentication(sal,ev);
1399 error=SalErrorUnknown;
1402 error=SalErrorFailure;
1403 sr=SalReasonNotFound;
1406 error=SalErrorFailure;
1410 eXosip_default_action(ev);
1414 error=SalErrorFailure;
1415 sr=SalReasonTemporarilyUnavailable;
1417 error=SalErrorFailure;
1423 error=SalErrorFailure;
1424 sr=SalReasonDoNotDisturb;
1427 error=SalErrorFailure;
1428 sr=SalReasonDeclined;
1432 error=SalErrorFailure;
1433 sr=SalReasonUnknown;
1434 }else error=SalErrorNoResponse;
1436 op->terminated=TRUE;
1437 sal->callbacks.call_failure(op,error,sr,reason,code);
1438 if (computedReason != NULL){
1439 ms_free(computedReason);
1444 /* Request remote side to send us VFU */
1445 void sal_call_send_vfu_request(SalOp *h){
1446 osip_message_t *msg=NULL;
1448 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1452 " <picture_fast_update></picture_fast_update>"
1460 eXosip_call_build_info(h->did,&msg);
1462 osip_message_set_body(msg,info_body,strlen(info_body));
1463 osip_message_set_content_type(msg,"application/media_control+xml");
1464 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1465 osip_message_set_content_length(msg,clen);
1466 eXosip_call_send_request(h->did,msg);
1467 ms_message("Sending VFU request !");
1472 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1473 SalOp *op=find_op(sal,ev);
1474 osip_body_t *body=NULL;
1477 ms_warning("media control xml received without operation context!");
1481 osip_message_get_body(ev->request,0,&body);
1482 if (body && body->body!=NULL &&
1483 strstr(body->body,"picture_fast_update")){
1484 osip_message_t *ans=NULL;
1485 ms_message("Receiving VFU request !");
1486 if (sal->callbacks.vfu_request){
1487 sal->callbacks.vfu_request(op);
1488 eXosip_call_build_answer(ev->tid,200,&ans);
1490 eXosip_call_send_answer(ev->tid,200,ans);
1494 /*in all other cases we must say it is not implemented.*/
1496 osip_message_t *ans=NULL;
1498 eXosip_call_build_answer(ev->tid,501,&ans);
1500 eXosip_call_send_answer(ev->tid,501,ans);
1505 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1506 SalOp *op=find_op(sal,ev);
1507 osip_body_t *body=NULL;
1510 ms_warning("media dtmf relay received without operation context!");
1514 osip_message_get_body(ev->request,0,&body);
1515 if (body && body->body!=NULL){
1516 osip_message_t *ans=NULL;
1517 const char *name=strstr(body->body,"Signal");
1518 if (name==NULL) name=strstr(body->body,"signal");
1520 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1523 name+=strlen("signal");
1524 if (sscanf(name," = %1s",tmp)==1){
1525 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1526 if (sal->callbacks.dtmf_received != NULL)
1527 sal->callbacks.dtmf_received(op, tmp[0]);
1531 eXosip_call_build_answer(ev->tid,200,&ans);
1533 eXosip_call_send_answer(ev->tid,200,ans);
1538 static void fill_options_answer(osip_message_t *options){
1539 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1540 osip_message_set_accept(options,"application/sdp");
1543 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1544 osip_header_t *h=NULL;
1545 osip_message_t *ans=NULL;
1546 ms_message("Receiving REFER request !");
1547 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1550 osip_from_t *from=NULL;
1552 osip_from_init(&from);
1554 if (osip_from_parse(from,h->hvalue)==0){
1556 osip_uri_header_t *uh=NULL;
1557 osip_header_t *referred_by=NULL;
1558 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1559 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1560 ms_message("Found replaces in Refer-To");
1562 ms_free(op->replaces);
1564 op->replaces=ms_strdup(uh->gvalue);
1566 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1567 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1568 if (op->referred_by)
1569 ms_free(op->referred_by);
1570 op->referred_by=ms_strdup(referred_by->hvalue);
1573 osip_uri_header_freelist(&from->url->url_headers);
1574 osip_from_to_str(from,&tmp);
1575 sal->callbacks.refer_received(sal,op,tmp);
1577 osip_from_free(from);
1580 eXosip_call_build_answer(ev->tid,202,&ans);
1582 eXosip_call_send_answer(ev->tid,202,ans);
1587 ms_warning("cannot do anything with the refer without destination\n");
1591 static void process_notify(Sal *sal, eXosip_event_t *ev){
1592 osip_header_t *h=NULL;
1594 SalOp *op=find_op(sal,ev);
1595 osip_message_t *ans=NULL;
1597 ms_message("Receiving NOTIFY request !");
1598 osip_from_to_str(ev->request->from,&from);
1599 osip_message_header_get_byname(ev->request,"Event",0,&h);
1601 osip_body_t *body=NULL;
1602 //osip_content_type_t *ct=NULL;
1603 osip_message_get_body(ev->request,0,&body);
1604 //ct=osip_message_get_content_type(ev->request);
1605 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1606 /*special handling of refer events*/
1607 if (body && body->body){
1608 osip_message_t *msg;
1609 osip_message_init(&msg);
1610 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1611 int code=osip_message_get_status_code(msg);
1613 sal->callbacks.notify_refer(op,SalReferTrying);
1614 }else if (code==200){
1615 sal->callbacks.notify_refer(op,SalReferSuccess);
1616 }else if (code>=400){
1617 sal->callbacks.notify_refer(op,SalReferFailed);
1620 osip_message_free(msg);
1623 /*generic handling*/
1624 sal->callbacks.notify(op,from,h->hvalue);
1627 /*answer that we received the notify*/
1629 eXosip_call_build_answer(ev->tid,200,&ans);
1631 eXosip_call_send_answer(ev->tid,200,ans);
1636 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1637 osip_message_t *ans=NULL;
1639 if (MSG_IS_INFO(ev->request)){
1640 osip_content_type_t *ct;
1641 ct=osip_message_get_content_type(ev->request);
1642 if (ct && ct->subtype){
1643 if (strcmp(ct->subtype,"media_control+xml")==0)
1644 process_media_control_xml(sal,ev);
1645 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1646 process_dtmf_relay(sal,ev);
1648 ms_message("Unhandled SIP INFO.");
1649 /*send an "Not implemented" answer*/
1651 eXosip_call_build_answer(ev->tid,501,&ans);
1653 eXosip_call_send_answer(ev->tid,501,ans);
1657 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1659 eXosip_call_build_answer(ev->tid,200,&ans);
1661 eXosip_call_send_answer(ev->tid,200,ans);
1664 }else if(MSG_IS_MESSAGE(ev->request)){
1665 /* SIP messages could be received into call */
1666 text_received(sal, ev);
1668 eXosip_call_build_answer(ev->tid,200,&ans);
1670 eXosip_call_send_answer(ev->tid,200,ans);
1672 }else if(MSG_IS_REFER(ev->request)){
1673 SalOp *op=find_op(sal,ev);
1675 ms_message("Receiving REFER request !");
1676 process_refer(sal,op,ev);
1677 }else if(MSG_IS_NOTIFY(ev->request)){
1678 process_notify(sal,ev);
1679 }else if (MSG_IS_OPTIONS(ev->request)){
1681 eXosip_call_build_answer(ev->tid,200,&ans);
1683 fill_options_answer(ans);
1684 eXosip_call_send_answer(ev->tid,200,ans);
1688 }else ms_warning("call_message_new: No request ?");
1691 static void inc_update(Sal *sal, eXosip_event_t *ev){
1692 osip_message_t *msg=NULL;
1693 ms_message("Processing incoming UPDATE");
1695 eXosip_message_build_answer(ev->tid,200,&msg);
1697 eXosip_message_send_answer(ev->tid,200,msg);
1701 static bool_t comes_from_local_if(osip_message_t *msg){
1702 osip_via_t *via=NULL;
1703 osip_message_get_via(msg,0,&via);
1706 host=osip_via_get_host(via);
1707 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1708 osip_generic_param_t *param=NULL;
1709 osip_via_param_get_byname(via,"received",¶m);
1710 if (param==NULL) return TRUE;
1711 if (param->gvalue &&
1712 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1720 static void text_received(Sal *sal, eXosip_event_t *ev){
1721 osip_body_t *body=NULL;
1722 char *from=NULL,*msg;
1723 osip_content_type_t* content_type;
1724 osip_uri_param_t* external_body_url;
1725 char unquoted_external_body_url [256];
1726 int external_body_size=0;
1728 content_type= osip_message_get_content_type(ev->request);
1729 if (!content_type) {
1730 ms_error("Could not get message because no content type");
1733 osip_from_to_str(ev->request->from,&from);
1734 if (content_type->type
1735 && strcmp(content_type->type, "text")==0
1736 && content_type->subtype
1737 && strcmp(content_type->subtype, "plain")==0 ) {
1738 osip_message_get_body(ev->request,0,&body);
1740 ms_error("Could not get text message from SIP body");
1744 sal->callbacks.text_received(sal,from,msg);
1745 } if (content_type->type
1746 && strcmp(content_type->type, "message")==0
1747 && content_type->subtype
1748 && strcmp(content_type->subtype, "external-body")==0 ) {
1750 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1751 /*remove both first and last character*/
1752 strncpy(unquoted_external_body_url
1753 ,&external_body_url->gvalue[1]
1754 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1755 unquoted_external_body_url[external_body_size-1]='\0';
1756 sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
1759 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1766 static void other_request(Sal *sal, eXosip_event_t *ev){
1767 ms_message("in other_request");
1768 if (ev->request==NULL) return;
1769 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1770 text_received(sal,ev);
1771 eXosip_message_send_answer(ev->tid,200,NULL);
1772 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1773 osip_message_t *options=NULL;
1774 eXosip_options_build_answer(ev->tid,200,&options);
1775 fill_options_answer(options);
1776 eXosip_options_send_answer(ev->tid,200,options);
1777 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1778 ms_message("Receiving REFER request !");
1779 if (comes_from_local_if(ev->request)) {
1780 process_refer(sal,NULL,ev);
1781 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1782 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1787 osip_message_to_str(ev->request,&tmp,&msglen);
1789 ms_message("Unsupported request received:\n%s",tmp);
1792 /*answer with a 501 Not implemented*/
1793 eXosip_message_send_answer(ev->tid,501,NULL);
1797 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1798 osip_via_t *via=NULL;
1799 osip_message_get_via(msg,0,&via);
1801 osip_free(via->port);
1802 via->port=osip_strdup(port);
1803 osip_free(via->host);
1804 via->host=osip_strdup(ip);
1809 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1810 osip_contact_t *ctt=NULL;
1811 const char *received;
1813 SalTransport transport;
1816 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1817 osip_message_get_contact(request,0,&ctt);
1819 ms_warning("fix_message_contact(): no contact to update");
1822 if (expire_last_contact){
1823 osip_contact_t *oldct=NULL,*prevct;
1824 osip_generic_param_t *param=NULL;
1825 osip_contact_clone(ctt,&oldct);
1826 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1827 osip_contact_free(prevct);
1828 osip_list_remove(&request->contacts,1);
1830 osip_list_add(&request->contacts,oldct,1);
1831 osip_contact_param_get_byname(oldct,"expires",¶m);
1833 if (param->gvalue) osip_free(param->gvalue);
1834 param->gvalue=osip_strdup("0");
1836 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1839 if (ctt->url->host!=NULL){
1840 osip_free(ctt->url->host);
1842 ctt->url->host=osip_strdup(received);
1843 if (ctt->url->port!=NULL){
1844 osip_free(ctt->url->port);
1846 snprintf(port,sizeof(port),"%i",rport);
1847 ctt->url->port=osip_strdup(port);
1848 if (op->masquerade_via) masquerade_via(request,received,port);
1850 if (transport != SalTransportUDP) {
1851 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1856 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1857 osip_contact_t *ctt=NULL;
1858 SalAddress* ori_contact_address=NULL;
1859 const char *received;
1861 SalTransport transport;
1863 osip_message_t *msg=NULL;
1864 Sal* sal=op->base.root;
1866 bool_t found_valid_contact=FALSE;
1867 bool_t from_request=FALSE;
1869 if (sal->double_reg==FALSE ) return FALSE;
1871 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1874 osip_message_get_contact(last_answer,i,&ctt);
1875 if (!from_request && ctt==NULL) {
1876 osip_message_get_contact(orig_request,0,&ctt);
1880 osip_contact_to_str(ctt,&tmp);
1881 ori_contact_address = sal_address_new(tmp);
1883 /*check if contact is up to date*/
1884 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1885 && sal_address_get_port_int(ori_contact_address) == rport
1886 && sal_address_get_transport(ori_contact_address) == transport) {
1888 ms_message("Register response has up to date contact, doing nothing.");
1890 ms_warning("Register response does not have up to date contact, but last request had."
1891 "Stupid registrar detected, giving up.");
1893 found_valid_contact=TRUE;
1896 sal_address_destroy(ori_contact_address);
1899 }while(!found_valid_contact);
1900 if (!found_valid_contact)
1901 ms_message("Contact do not match, resending register.");
1905 eXosip_register_build_register(op->rid,op->expires,&msg);
1908 ms_warning("Fail to create a contact updated register.");
1911 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1912 eXosip_register_send_register(op->rid,msg);
1914 ms_message("Resending new register with updated contact");
1915 update_contact_from_response(op,last_answer);
1918 ms_warning("Fail to send updated register.");
1926 static void registration_success(Sal *sal, eXosip_event_t *ev){
1927 SalOp *op=sal_find_register(sal,ev->rid);
1928 osip_header_t *h=NULL;
1931 ms_error("Receiving register response for unknown operation");
1934 osip_message_get_expires(ev->request,0,&h);
1935 if (h!=NULL && atoi(h->hvalue)!=0){
1937 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1938 sal->callbacks.register_success(op,registered);
1941 sal->callbacks.register_success(op,FALSE);
1945 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1947 const char *reason=NULL;
1948 SalOp *op=sal_find_register(sal,ev->rid);
1949 SalReason sr=SalReasonUnknown;
1950 SalError se=SalErrorUnknown;
1953 ms_error("Receiving register failure for unknown operation");
1957 status_code=osip_message_get_status_code(ev->response);
1958 reason=osip_message_get_reason_phrase(ev->response);
1960 switch(status_code){
1963 return process_authentication(sal,ev);
1965 case 423: /*interval too brief*/
1966 {/*retry with greater interval */
1967 osip_header_t *h=NULL;
1968 osip_message_t *msg=NULL;
1969 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1970 if (h && h->hvalue && h->hvalue[0]!='\0'){
1971 int val=atoi(h->hvalue);
1972 if (val>op->expires)
1974 }else op->expires*=2;
1976 eXosip_register_build_register(op->rid,op->expires,&msg);
1977 eXosip_register_send_register(op->rid,msg);
1981 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1982 in vias, such as ekiga.net
1983 On the opposite, freephonie.net bugs when via are masqueraded.
1985 op->masquerade_via=TRUE;
1987 /* if contact is up to date, process the failure, otherwise resend a new register with
1988 updated contact first, just in case the faillure is due to incorrect contact */
1989 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1990 return TRUE; /*we are retrying with an updated contact*/
1991 if (status_code==403){
1993 sr=SalReasonForbidden;
1994 }else if (status_code==0){
1995 se=SalErrorNoResponse;
1997 sal->callbacks.register_failure(op,se,sr,reason);
2002 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2003 SalOp *op=find_op(sal,ev);
2005 ms_warning("other_request_reply(): Receiving response to unknown request.");
2009 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2010 update_contact_from_response(op,ev->response);
2011 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2012 sal->callbacks.ping_reply(op);
2014 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2015 /*out of call message acknolegment*/
2016 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2018 if (ev->response->status_code<200){
2019 status=SalTextDeliveryInProgress;
2020 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2021 status=SalTextDeliveryDone;
2024 sal->callbacks.text_delivery_update(op,status);
2028 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2029 SalOp *op=find_op(sal,ev);
2031 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2032 if (op->sipfrag_pending){
2033 send_notify_for_refer(op->did,op->sipfrag_pending);
2034 op->sipfrag_pending=NULL;
2040 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2041 ms_message("linphone process event get a message %d\n",ev->type);
2043 case EXOSIP_CALL_ANSWERED:
2044 ms_message("CALL_ANSWERED\n");
2045 call_accepted(sal,ev);
2046 authentication_ok(sal,ev);
2048 case EXOSIP_CALL_CLOSED:
2049 case EXOSIP_CALL_CANCELLED:
2050 ms_message("CALL_CLOSED or CANCELLED\n");
2051 call_terminated(sal,ev);
2053 case EXOSIP_CALL_TIMEOUT:
2054 case EXOSIP_CALL_NOANSWER:
2055 ms_message("CALL_TIMEOUT or NOANSWER\n");
2056 return call_failure(sal,ev);
2058 case EXOSIP_CALL_REQUESTFAILURE:
2059 case EXOSIP_CALL_GLOBALFAILURE:
2060 case EXOSIP_CALL_SERVERFAILURE:
2061 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2062 return call_failure(sal,ev);
2064 case EXOSIP_CALL_RELEASED:
2065 ms_message("CALL_RELEASED\n");
2066 call_released(sal, ev);
2068 case EXOSIP_CALL_INVITE:
2069 ms_message("CALL_NEW\n");
2070 inc_new_call(sal,ev);
2072 case EXOSIP_CALL_REINVITE:
2073 handle_reinvite(sal,ev);
2075 case EXOSIP_CALL_ACK:
2076 ms_message("CALL_ACK");
2079 case EXOSIP_CALL_REDIRECTED:
2080 ms_message("CALL_REDIRECTED");
2081 eXosip_default_action(ev);
2083 case EXOSIP_CALL_PROCEEDING:
2084 ms_message("CALL_PROCEEDING");
2085 call_proceeding(sal,ev);
2087 case EXOSIP_CALL_RINGING:
2088 ms_message("CALL_RINGING");
2089 call_ringing(sal,ev);
2090 authentication_ok(sal,ev);
2092 case EXOSIP_CALL_MESSAGE_NEW:
2093 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2094 call_message_new(sal,ev);
2096 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2098 (ev->response->status_code==407 || ev->response->status_code==401)){
2099 return process_authentication(sal,ev);
2102 case EXOSIP_CALL_MESSAGE_ANSWERED:
2103 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2104 process_in_call_reply(sal,ev);
2106 case EXOSIP_IN_SUBSCRIPTION_NEW:
2107 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2108 sal_exosip_subscription_recv(sal,ev);
2110 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2111 ms_message("CALL_SUBSCRIPTION_NEW ");
2112 sal_exosip_in_subscription_closed(sal,ev);
2114 case EXOSIP_SUBSCRIPTION_UPDATE:
2115 ms_message("CALL_SUBSCRIPTION_UPDATE");
2117 case EXOSIP_SUBSCRIPTION_NOTIFY:
2118 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2119 sal_exosip_notify_recv(sal,ev);
2121 case EXOSIP_SUBSCRIPTION_ANSWERED:
2122 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2123 sal_exosip_subscription_answered(sal,ev);
2125 case EXOSIP_SUBSCRIPTION_CLOSED:
2126 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2127 sal_exosip_subscription_closed(sal,ev);
2129 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2130 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2131 return process_authentication(sal,ev);
2133 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2134 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2135 sal_exosip_subscription_closed(sal,ev);
2137 case EXOSIP_REGISTRATION_FAILURE:
2138 ms_message("REGISTRATION_FAILURE\n");
2139 return registration_failure(sal,ev);
2141 case EXOSIP_REGISTRATION_SUCCESS:
2142 authentication_ok(sal,ev);
2143 registration_success(sal,ev);
2145 case EXOSIP_MESSAGE_NEW:
2146 other_request(sal,ev);
2148 case EXOSIP_MESSAGE_PROCEEDING:
2149 case EXOSIP_MESSAGE_ANSWERED:
2150 case EXOSIP_MESSAGE_REDIRECTED:
2151 case EXOSIP_MESSAGE_SERVERFAILURE:
2152 case EXOSIP_MESSAGE_GLOBALFAILURE:
2153 other_request_reply(sal,ev);
2155 case EXOSIP_MESSAGE_REQUESTFAILURE:
2156 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2158 switch (ev->response->status_code) {
2161 return process_authentication(sal,ev);
2163 eXosip_automatic_action ();
2168 other_request_reply(sal,ev);
2171 ms_message("Unhandled exosip event ! %i",ev->type);
2177 int sal_iterate(Sal *sal){
2179 while((ev=eXosip_event_wait(0,0))!=NULL){
2180 if (process_event(sal,ev))
2181 eXosip_event_free(ev);
2183 #ifdef HAVE_EXOSIP_TRYLOCK
2184 if (eXosip_trylock()==0){
2185 eXosip_automatic_refresh();
2188 ms_warning("eXosip_trylock busy.");
2192 eXosip_automatic_refresh();
2198 static void register_set_contact(osip_message_t *msg, const char *contact){
2199 osip_uri_param_t *param = NULL;
2200 osip_contact_t *ct=NULL;
2202 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2203 osip_message_get_contact(msg,0,&ct);
2205 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2206 if (param && param->gvalue)
2207 line=osip_strdup(param->gvalue);
2209 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2210 osip_message_set_contact(msg,contact);
2211 osip_message_get_contact(msg,0,&ct);
2212 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2215 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2217 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2219 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2220 osip_message_set_route(msg,tmp);
2223 static const char *days[]={"Sun","Mon","Tue","Wed","Thu","Fri","Sat"};
2224 static const char *months[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
2226 static void sal_register_set_date(osip_message_t *msg){
2228 time_t curtime=time(NULL);
2232 ret=gmtime_r(&curtime,&gmt);
2234 ret=gmtime(&curtime);
2236 /*cannot use strftime because it is locale dependant*/
2237 snprintf(tmp,sizeof(tmp)-1,"%s, %i %s %i %02i:%02i:%02i GMT",
2238 days[ret->tm_wday],ret->tm_mday,months[ret->tm_mon],1900+ret->tm_year,ret->tm_hour,ret->tm_min,ret->tm_sec);
2239 osip_message_replace_header(msg,"Date",tmp);
2242 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2243 osip_message_t *msg;
2244 const char *contact=sal_op_get_contact(h);
2246 sal_op_set_route(h,proxy);
2248 SalAddress *from_parsed=sal_address_new(from);
2250 char *uri, *domain_ptr = NULL;
2251 if (from_parsed==NULL) {
2252 ms_warning("sal_register() bad from %s",from);
2255 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2256 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2257 uri = sal_address_as_string_uri_only(from_parsed);
2258 if (uri) domain_ptr = strchr(uri, '@');
2260 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2262 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2264 if (uri) ms_free(uri);
2265 sal_address_destroy(from_parsed);
2267 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2269 if (contact) register_set_contact(msg,contact);
2270 sal_register_add_route(msg,proxy);
2271 sal_add_register(h->base.root,h);
2273 ms_error("Could not build initial register.");
2279 eXosip_register_build_register(h->rid,expires,&msg);
2280 sal_register_add_route(msg,proxy);
2283 if (h->base.root->add_dates) sal_register_set_date(msg);
2284 eXosip_register_send_register(h->rid,msg);
2288 return (msg != NULL) ? 0 : -1;
2291 int sal_register_refresh(SalOp *op, int expires){
2292 osip_message_t *msg=NULL;
2293 const char *contact=sal_op_get_contact(op);
2296 ms_error("Unexistant registration context, not possible to refresh.");
2299 #ifdef HAVE_EXOSIP_TRYLOCK
2302 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2303 * 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
2304 * the exosip lock in a non blocking way, and give up if it takes too long*/
2305 while (eXosip_trylock()!=0){
2307 if (tries>30) {/*after 3 seconds, give up*/
2308 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2316 eXosip_register_build_register(op->rid,expires,&msg);
2318 if (contact) register_set_contact(msg,contact);
2319 sal_register_add_route(msg,sal_op_get_route(op));
2320 eXosip_register_send_register(op->rid,msg);
2321 }else ms_error("Could not build REGISTER refresh message.");
2323 return (msg != NULL) ? 0 : -1;
2327 int sal_unregister(SalOp *h){
2328 osip_message_t *msg=NULL;
2330 eXosip_register_build_register(h->rid,0,&msg);
2331 if (msg) eXosip_register_send_register(h->rid,msg);
2332 else ms_warning("Could not build unREGISTER !");
2337 SalAddress * sal_address_new(const char *uri){
2339 osip_from_init(&from);
2341 // Remove front spaces
2342 while (uri[0]==' ') {
2346 if (osip_from_parse(from,uri)!=0){
2347 osip_from_free(from);
2350 if (from->displayname!=NULL && from->displayname[0]=='"'){
2351 char *unquoted=osip_strdup_without_quote(from->displayname);
2352 osip_free(from->displayname);
2353 from->displayname=unquoted;
2355 return (SalAddress*)from;
2358 SalAddress * sal_address_clone(const SalAddress *addr){
2359 osip_from_t *ret=NULL;
2360 osip_from_clone((osip_from_t*)addr,&ret);
2361 return (SalAddress*)ret;
2364 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2366 const char *sal_address_get_scheme(const SalAddress *addr){
2367 const osip_from_t *u=(const osip_from_t*)addr;
2368 return null_if_empty(u->url->scheme);
2371 const char *sal_address_get_display_name(const SalAddress* addr){
2372 const osip_from_t *u=(const osip_from_t*)addr;
2373 return null_if_empty(u->displayname);
2376 const char *sal_address_get_username(const SalAddress *addr){
2377 const osip_from_t *u=(const osip_from_t*)addr;
2378 return null_if_empty(u->url->username);
2381 const char *sal_address_get_domain(const SalAddress *addr){
2382 const osip_from_t *u=(const osip_from_t*)addr;
2383 return null_if_empty(u->url->host);
2386 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2387 osip_from_t *u=(osip_from_t*)addr;
2388 if (u->displayname!=NULL){
2389 osip_free(u->displayname);
2390 u->displayname=NULL;
2392 if (display_name!=NULL && display_name[0]!='\0'){
2393 u->displayname=osip_strdup(display_name);
2397 void sal_address_set_username(SalAddress *addr, const char *username){
2398 osip_from_t *uri=(osip_from_t*)addr;
2399 if (uri->url->username!=NULL){
2400 osip_free(uri->url->username);
2401 uri->url->username=NULL;
2404 uri->url->username=osip_strdup(username);
2407 void sal_address_set_domain(SalAddress *addr, const char *host){
2408 osip_from_t *uri=(osip_from_t*)addr;
2409 if (uri->url->host!=NULL){
2410 osip_free(uri->url->host);
2411 uri->url->host=NULL;
2414 uri->url->host=osip_strdup(host);
2417 void sal_address_set_port(SalAddress *addr, const char *port){
2418 osip_from_t *uri=(osip_from_t*)addr;
2419 if (uri->url->port!=NULL){
2420 osip_free(uri->url->port);
2421 uri->url->port=NULL;
2424 uri->url->port=osip_strdup(port);
2427 void sal_address_set_port_int(SalAddress *uri, int port){
2430 /*this is the default, special case to leave the port field blank*/
2431 sal_address_set_port(uri,NULL);
2434 snprintf(tmp,sizeof(tmp),"%i",port);
2435 sal_address_set_port(uri,tmp);
2438 void sal_address_clean(SalAddress *addr){
2439 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2440 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2443 char *sal_address_as_string(const SalAddress *u){
2445 osip_from_t *from=(osip_from_t *)u;
2446 char *old_displayname=NULL;
2447 /* hack to force use of quotes around the displayname*/
2448 if (from->displayname!=NULL
2449 && from->displayname[0]!='"'){
2450 old_displayname=from->displayname;
2451 from->displayname=osip_enquote(from->displayname);
2453 osip_from_to_str(from,&tmp);
2454 if (old_displayname!=NULL){
2455 ms_free(from->displayname);
2456 from->displayname=old_displayname;
2463 char *sal_address_as_string_uri_only(const SalAddress *u){
2464 char *tmp=NULL,*ret;
2465 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2470 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2471 osip_uri_param_t *param=NULL;
2472 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2474 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2476 osip_free(param->gvalue);
2477 param->gvalue=value ? osip_strdup(value) : NULL;
2482 void sal_address_destroy(SalAddress *u){
2483 osip_from_free((osip_from_t*)u);
2486 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2487 ctx->keepalive_period=value;
2488 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2490 unsigned int sal_get_keepalive_period(Sal *ctx) {
2491 return ctx->keepalive_period;
2494 const char * sal_address_get_port(const SalAddress *addr) {
2495 const osip_from_t *u=(const osip_from_t*)addr;
2496 return null_if_empty(u->url->port);
2499 int sal_address_get_port_int(const SalAddress *uri) {
2500 const char* port = sal_address_get_port(uri);
2507 SalTransport sal_address_get_transport(const SalAddress* addr) {
2508 const osip_from_t *u=(const osip_from_t*)addr;
2509 osip_uri_param_t *transport_param=NULL;
2510 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2511 if (transport_param == NULL){
2512 return SalTransportUDP;
2514 return sal_transport_parse(transport_param->gvalue);
2517 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2518 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2521 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2522 int sal_call_update(SalOp *h, const char *subject){
2524 osip_message_t *reinvite=NULL;
2527 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2532 osip_message_set_subject(reinvite,subject);
2533 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2534 if (h->base.contact){
2535 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2536 osip_message_set_contact(reinvite,h->base.contact);
2538 if (h->base.root->session_expires!=0){
2539 osip_message_set_header(reinvite, "Session-expires", "200");
2540 osip_message_set_supported(reinvite, "timer");
2542 if (h->base.local_media){
2543 h->sdp_offering=TRUE;
2544 set_sdp_from_desc(reinvite,h->base.local_media);
2545 }else h->sdp_offering=FALSE;
2547 err = eXosip_call_send_request(h->did, reinvite);
2551 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2552 ctx->reuse_authorization=value;