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;
287 sal->exosip_has_ssl=eXosip_tls_verify_certificate(0) != -1;
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_rport(Sal *ctx, bool_t use_rports){
465 ctx->use_rports=use_rports;
467 void sal_use_101(Sal *ctx, bool_t use_101){
468 ctx->use_101=use_101;
471 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
473 ms_free(ctx->rootCa);
474 ctx->rootCa = ms_strdup(rootCa);
475 set_tls_options(ctx);
478 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
479 ctx->verify_server_certs=verify;
480 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
481 eXosip_tls_verify_certificate(verify);
485 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
486 osip_via_t *via=NULL;
487 osip_generic_param_t *param=NULL;
488 const char *rport=NULL;
492 osip_message_get_via(msg,0,&via);
494 ms_warning("extract_received_rport(): no via.");
498 *transport = sal_transport_parse(via->protocol);
500 if (via->port && via->port[0]!='\0')
501 *rportval=atoi(via->port);
503 osip_via_param_get_byname(via,"rport",¶m);
506 if (rport && rport[0]!='\0') *rportval=atoi(rport);
510 osip_via_param_get_byname(via,"received",¶m);
511 if (param) *received=param->gvalue;
513 if (rport==NULL && *received==NULL){
514 ms_warning("extract_received_rport(): no rport and no received parameters.");
520 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
524 sdp_message_to_str(msg,&sdp);
526 snprintf(clen,sizeof(clen),"%i",sdplen);
527 osip_message_set_body(sip,sdp,sdplen);
528 osip_message_set_content_type(sip,"application/sdp");
529 osip_message_set_content_length(sip,clen);
533 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
534 sdp_message_t *msg=media_description_to_sdp(desc);
536 ms_error("Fail to print sdp message !");
540 sdp_message_free(msg);
543 static void sdp_process(SalOp *h){
544 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
546 sal_media_description_unref(h->result);
548 h->result=sal_media_description_new();
549 if (h->sdp_offering){
550 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
554 sdp_message_free(h->sdp_answer);
556 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
557 h->sdp_answer=media_description_to_sdp(h->result);
558 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
559 It should contains media parameters constraint from the remote offer, not our response*/
560 strcpy(h->result->addr,h->base.remote_media->addr);
561 h->result->bandwidth=h->base.remote_media->bandwidth;
563 for(i=0;i<h->result->nstreams;++i){
564 if (h->result->streams[i].rtp_port>0){
565 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
566 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
567 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
568 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
569 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
570 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
572 if (h->result->streams[i].proto == SalProtoRtpSavp) {
573 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
581 int sal_call_is_offerer(const SalOp *h){
582 return h->sdp_offering;
585 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
587 sal_media_description_ref(desc);
588 if (h->base.local_media)
589 sal_media_description_unref(h->base.local_media);
590 h->base.local_media=desc;
591 if (h->base.remote_media){
592 /*case of an incoming call where we modify the local capabilities between the time
593 * the call is ringing and it is accepted (for example if you want to accept without video*/
594 /*reset the sdp answer so that it is computed again*/
596 sdp_message_free(h->sdp_answer);
603 int sal_call(SalOp *h, const char *from, const char *to){
606 osip_message_t *invite=NULL;
607 sal_op_set_from(h,from);
609 sal_exosip_fix_route(h);
611 h->terminated = FALSE;
613 route = sal_op_get_route(h);
614 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
616 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
617 err, from, to, route);
620 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
621 if (h->base.contact){
622 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
623 osip_message_set_contact(invite,h->base.contact);
625 if (h->base.root->session_expires!=0){
626 osip_message_set_header(invite, "Session-expires", "200");
627 osip_message_set_supported(invite, "timer");
629 if (h->base.local_media){
630 h->sdp_offering=TRUE;
631 set_sdp_from_desc(invite,h->base.local_media);
632 }else h->sdp_offering=FALSE;
634 osip_message_set_header(invite,"Replaces",h->replaces);
636 osip_message_set_header(invite,"Referred-By",h->referred_by);
640 err=eXosip_call_send_initial_invite(invite);
644 ms_error("Fail to send invite ! Error code %d", err);
647 sal_add_call(h->base.root,h);
652 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
655 /*if early media send also 180 and 183 */
659 eXosip_call_build_answer(h->tid,183,&msg);
663 set_sdp(msg,h->sdp_answer);
664 sdp_message_free(h->sdp_answer);
667 eXosip_call_send_answer(h->tid,183,msg);
672 eXosip_call_send_answer(h->tid,180,NULL);
678 int sal_call_accept(SalOp * h){
680 const char *contact=sal_op_get_contact(h);
682 int err=eXosip_call_build_answer(h->tid,200,&msg);
683 if (err<0 || msg==NULL){
684 ms_error("Fail to build answer for call: err=%i",err);
687 if (h->base.root->session_expires!=0){
688 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
692 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
693 osip_message_set_contact(msg,contact);
696 if (h->base.local_media){
697 /*this is the case where we received an invite without SDP*/
698 if (h->sdp_offering) {
699 set_sdp_from_desc(msg,h->base.local_media);
701 if (h->sdp_answer==NULL) sdp_process(h);
703 set_sdp(msg,h->sdp_answer);
704 sdp_message_free(h->sdp_answer);
709 ms_error("You are accepting a call but not defined any media capabilities !");
711 eXosip_call_send_answer(h->tid,200,msg);
715 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
716 if (reason==SalReasonBusy){
718 eXosip_call_send_answer(h->tid,486,NULL);
721 else if (reason==SalReasonTemporarilyUnavailable){
723 eXosip_call_send_answer(h->tid,480,NULL);
725 }else if (reason==SalReasonDoNotDisturb){
727 eXosip_call_send_answer(h->tid,600,NULL);
729 }else if (reason==SalReasonMedia){
731 eXosip_call_send_answer(h->tid,415,NULL);
733 }else if (redirect!=NULL && reason==SalReasonRedirect){
736 if (strstr(redirect,"sip:")!=0) code=302;
739 eXosip_call_build_answer(h->tid,code,&msg);
740 osip_message_set_contact(msg,redirect);
741 eXosip_call_send_answer(h->tid,code,msg);
743 }else sal_call_terminate(h);
747 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
748 return h->base.remote_media;
751 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
752 if (h->base.local_media && h->base.remote_media && !h->result){
758 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
759 if (refered_call->replaces)
760 h->replaces=ms_strdup(refered_call->replaces);
761 if (refered_call->referred_by)
762 h->referred_by=ms_strdup(refered_call->referred_by);
766 static int send_notify_for_refer(int did, const char *sipfrag){
769 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
772 ms_warning("Could not build NOTIFY for refer.");
775 osip_message_set_content_type(msg,"message/sipfrag");
776 osip_message_set_header(msg,"Event","refer");
777 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
778 eXosip_call_send_request(did,msg);
783 /* currently only support to notify trying and 200Ok*/
784 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
787 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
789 else if (newcall->cid!=-1){
790 if (newcall->did==-1){
791 /* not yet established*/
792 if (!newcall->terminated){
794 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
797 if (!newcall->terminated){
798 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
799 /* we need previous notify transaction to complete, so buffer the request for later*/
800 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
808 int sal_ping(SalOp *op, const char *from, const char *to){
809 osip_message_t *options=NULL;
811 sal_op_set_from(op,from);
812 sal_op_set_to(op,to);
813 sal_exosip_fix_route(op);
815 eXosip_options_build_request (&options, sal_op_get_to(op),
816 sal_op_get_from(op),sal_op_get_route(op));
818 if (op->base.root->session_expires!=0){
819 osip_message_set_header(options, "Session-expires", "200");
820 osip_message_set_supported(options, "timer");
822 sal_add_other(sal_op_get_sal(op),op,options);
823 return eXosip_options_send_request(options);
828 int sal_call_refer(SalOp *h, const char *refer_to){
829 osip_message_t *msg=NULL;
832 eXosip_call_build_refer(h->did,refer_to, &msg);
833 if (msg) err=eXosip_call_send_request(h->did, msg);
839 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
840 osip_message_t *msg=NULL;
841 char referto[256]={0};
844 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
845 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
849 eXosip_call_build_refer(h->did,referto, &msg);
850 osip_message_set_header(msg,"Referred-By",h->base.from);
851 if (msg) err=eXosip_call_send_request(h->did, msg);
857 SalOp *sal_call_get_replaces(SalOp *h){
858 if (h!=NULL && h->replaces!=NULL){
861 cid=eXosip_call_find_by_replaces(h->replaces);
864 SalOp *ret=sal_find_call(h->base.root,cid);
871 int sal_call_send_dtmf(SalOp *h, char dtmf){
872 osip_message_t *msg=NULL;
877 eXosip_call_build_info(h->did,&msg);
879 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
880 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
881 osip_message_set_content_type(msg,"application/dtmf-relay");
882 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
883 osip_message_set_content_length(msg,clen);
884 eXosip_call_send_request(h->did,msg);
890 static void push_auth_to_exosip(const SalAuthInfo *info){
892 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
893 else userid=info->userid;
894 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
895 eXosip_add_authentication_info (info->username,userid,
896 info->password, NULL,info->realm);
899 * Just for symmetry ;-)
901 static void pop_auth_from_exosip() {
902 eXosip_clear_authentication_info();
905 int sal_call_terminate(SalOp *h){
907 if (h == NULL) return -1;
908 if (h->auth_info) push_auth_to_exosip(h->auth_info);
910 err=eXosip_call_terminate(h->cid,h->did);
912 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
914 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
920 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
921 if (h->terminated) return;
922 if (h->pending_auth){
923 push_auth_to_exosip(info);
925 /*FIXME exosip does not take into account this update register message*/
927 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
931 update_contact_from_response(h,h->pending_auth->response);
933 eXosip_default_action(h->pending_auth);
935 ms_message("eXosip_default_action() done");
936 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
938 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
939 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
942 void sal_op_cancel_authentication(SalOp *h) {
944 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
945 } else if (h->cid >0) {
946 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
948 ms_warning("Auth failure not handled");
952 static void set_network_origin(SalOp *op, osip_message_t *req){
953 const char *received=NULL;
956 SalTransport transport;
957 if (extract_received_rport(req,&received,&rport,&transport)!=0){
958 osip_via_t *via=NULL;
960 osip_message_get_via(req,0,&via);
961 received=osip_via_get_host(via);
962 tmp=osip_via_get_port(via);
963 if (tmp) rport=atoi(tmp);
965 if (transport != SalTransportUDP) {
966 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
968 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
970 __sal_op_set_network_origin(op,origin);
973 static void set_remote_ua(SalOp* op, osip_message_t *req){
974 if (op->base.remote_ua==NULL){
975 osip_header_t *h=NULL;
976 osip_message_get_user_agent(req,0,&h);
978 op->base.remote_ua=ms_strdup(h->hvalue);
983 static void set_replaces(SalOp *op, osip_message_t *req){
984 osip_header_t *h=NULL;
987 ms_free(op->replaces);
990 osip_message_header_get_byname(req,"replaces",0,&h);
992 if (h->hvalue && h->hvalue[0]!='\0'){
993 op->replaces=ms_strdup(h->hvalue);
998 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1000 return sal_find_call(sal,ev->cid);
1003 return sal_find_register(sal,ev->rid);
1006 return sal_find_out_subscribe(sal,ev->sid);
1009 return sal_find_in_subscribe(sal,ev->nid);
1011 if (ev->response) return sal_find_other(sal,ev->response);
1012 else if (ev->request) return sal_find_other(sal,ev->request);
1016 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1017 SalOp *op=sal_op_new(sal);
1018 osip_from_t *from,*to;
1019 osip_call_info_t *call_info;
1021 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1023 set_network_origin(op,ev->request);
1024 set_remote_ua(op,ev->request);
1025 set_replaces(op,ev->request);
1028 op->sdp_offering=FALSE;
1029 op->base.remote_media=sal_media_description_new();
1030 sdp_to_media_description(sdp,op->base.remote_media);
1031 sdp_message_free(sdp);
1032 }else op->sdp_offering=TRUE;
1034 from=osip_message_get_from(ev->request);
1035 to=osip_message_get_to(ev->request);
1036 osip_from_to_str(from,&tmp);
1037 sal_op_set_from(op,tmp);
1039 osip_from_to_str(to,&tmp);
1040 sal_op_set_to(op,tmp);
1043 osip_message_get_call_info(ev->request,0,&call_info);
1046 osip_call_info_to_str(call_info,&tmp);
1047 if( strstr(tmp,"answer-after=") != NULL)
1049 op->auto_answer_asked=TRUE;
1050 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1059 sal_add_call(op->base.root,op);
1060 sal->callbacks.call_received(op);
1063 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1064 SalOp *op=find_op(sal,ev);
1068 ms_warning("Reinvite for non-existing operation !");
1073 sdp=eXosip_get_sdp_info(ev->request);
1074 if (op->base.remote_media){
1075 sal_media_description_unref(op->base.remote_media);
1076 op->base.remote_media=NULL;
1079 sal_media_description_unref(op->result);
1083 op->sdp_offering=FALSE;
1084 op->base.remote_media=sal_media_description_new();
1085 sdp_to_media_description(sdp,op->base.remote_media);
1086 sdp_message_free(sdp);
1089 op->sdp_offering=TRUE;
1091 sal->callbacks.call_updating(op);
1094 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1095 SalOp *op=find_op(sal,ev);
1099 ms_warning("ack for non-existing call !");
1102 if (op->terminated) {
1103 ms_warning("ack for terminated call, ignoring");
1107 if (op->sdp_offering){
1108 sdp=eXosip_get_sdp_info(ev->ack);
1110 if (op->base.remote_media)
1111 sal_media_description_unref(op->base.remote_media);
1112 op->base.remote_media=sal_media_description_new();
1113 sdp_to_media_description(sdp,op->base.remote_media);
1115 sdp_message_free(sdp);
1121 sal->callbacks.call_ack(op);
1124 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1125 const char *received;
1127 SalTransport transport;
1128 if (extract_received_rport(response,&received,&rport,&transport)==0){
1129 const char *contact=sal_op_get_contact(op);
1131 /*no contact given yet, use from instead*/
1132 contact=sal_op_get_from(op);
1135 SalAddress *addr=sal_address_new(contact);
1137 sal_address_set_domain(addr,received);
1138 sal_address_set_port_int(addr,rport);
1139 if (transport!=SalTransportUDP)
1140 sal_address_set_transport(addr,transport);
1141 tmp=sal_address_as_string(addr);
1142 ms_message("Contact address updated to %s",tmp);
1143 sal_op_set_contact(op,tmp);
1144 sal_address_destroy(addr);
1150 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1151 SalOp *op=find_op(sal,ev);
1153 if (op==NULL || op->terminated==TRUE) {
1154 ms_warning("This call has been canceled.");
1156 eXosip_call_terminate(ev->cid,ev->did);
1164 /* update contact if received and rport are set by the server
1165 note: will only be used by remote for next INVITE, if any...*/
1166 update_contact_from_response(op,ev->response);
1170 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1172 SalOp *op=find_op(sal,ev);
1173 if (call_proceeding(sal, ev)==-1) return;
1175 set_remote_ua(op,ev->response);
1176 sdp=eXosip_get_sdp_info(ev->response);
1178 op->base.remote_media=sal_media_description_new();
1179 sdp_to_media_description(sdp,op->base.remote_media);
1180 sdp_message_free(sdp);
1181 if (op->base.local_media) sdp_process(op);
1183 sal->callbacks.call_ringing(op);
1186 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1188 osip_message_t *msg=NULL;
1189 SalOp *op=find_op(sal,ev);
1190 const char *contact;
1192 if (op==NULL || op->terminated==TRUE) {
1193 ms_warning("This call has been already terminated.");
1195 eXosip_call_terminate(ev->cid,ev->did);
1201 set_remote_ua(op,ev->response);
1203 sdp=eXosip_get_sdp_info(ev->response);
1205 op->base.remote_media=sal_media_description_new();
1206 sdp_to_media_description(sdp,op->base.remote_media);
1207 sdp_message_free(sdp);
1208 if (op->base.local_media) sdp_process(op);
1210 eXosip_call_build_ack(ev->did,&msg);
1212 ms_warning("This call has been already terminated.");
1214 eXosip_call_terminate(ev->cid,ev->did);
1218 contact=sal_op_get_contact(op);
1220 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1221 osip_message_set_contact(msg,contact);
1223 if (op->sdp_answer){
1224 set_sdp(msg,op->sdp_answer);
1225 sdp_message_free(op->sdp_answer);
1226 op->sdp_answer=NULL;
1228 eXosip_call_send_ack(ev->did,msg);
1229 sal->callbacks.call_accepted(op);
1232 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1234 SalOp *op=find_op(sal,ev);
1236 ms_warning("Call terminated for already closed call ?");
1240 osip_from_to_str(ev->request->from,&from);
1242 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1243 if (from) osip_free(from);
1244 op->terminated=TRUE;
1247 static void call_released(Sal *sal, eXosip_event_t *ev){
1248 SalOp *op=find_op(sal,ev);
1250 ms_warning("No op associated to this call_released()");
1253 if (!op->terminated){
1254 /* no response received so far */
1255 call_failure(sal,ev);
1257 sal->callbacks.call_released(op);
1260 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1261 const char *prx_realm=NULL,*www_realm=NULL;
1262 osip_proxy_authenticate_t *prx_auth;
1263 osip_www_authenticate_t *www_auth;
1265 *username=osip_uri_get_username(resp->from->url);
1266 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1267 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1269 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1271 www_realm=osip_www_authenticate_get_realm(www_auth);
1275 }else if (www_realm){
1283 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1284 osip_authorization_t *auth=NULL;
1285 osip_proxy_authorization_t *prx_auth=NULL;
1287 *username=osip_uri_get_username(msg->from->url);
1288 osip_message_get_authorization(msg, 0, &auth);
1290 *realm=osip_authorization_get_realm(auth);
1293 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1295 *realm=osip_proxy_authorization_get_realm(prx_auth);
1301 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1302 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1303 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1307 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1308 if (op->pending_auth){
1309 return get_auth_data(op->pending_auth,realm,username);
1314 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1316 const char *username,*realm;
1319 ms_warning("No operation associated with this authentication !");
1322 if (get_auth_data(ev,&realm,&username)==0){
1323 if (op->pending_auth!=NULL){
1324 eXosip_event_free(op->pending_auth);
1325 op->pending_auth=ev;
1327 op->pending_auth=ev;
1328 sal_add_pending_auth(sal,op);
1331 sal->callbacks.auth_requested(op,realm,username);
1337 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1339 const char *username,*realm;
1342 ms_warning("No operation associated with this authentication_ok!");
1345 if (op->pending_auth){
1346 eXosip_event_free(op->pending_auth);
1347 sal_remove_pending_auth(sal,op);
1348 op->pending_auth=NULL;
1350 if (get_auth_data(ev,&realm,&username)==0){
1351 sal->callbacks.auth_success(op,realm,username);
1355 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1358 char* computedReason=NULL;
1359 const char *reason=NULL;
1360 SalError error=SalErrorUnknown;
1361 SalReason sr=SalReasonUnknown;
1364 op=(SalOp*)find_op(sal,ev);
1367 ms_warning("Call failure reported for a closed call, ignored.");
1372 code=osip_message_get_status_code(ev->response);
1373 reason=osip_message_get_reason_phrase(ev->response);
1374 osip_header_t *h=NULL;
1375 if (!osip_message_header_get_byname( ev->response
1379 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1380 reason = computedReason;
1388 return process_authentication(sal,ev);
1391 error=SalErrorUnknown;
1394 error=SalErrorFailure;
1395 sr=SalReasonNotFound;
1398 error=SalErrorFailure;
1402 eXosip_default_action(ev);
1406 error=SalErrorFailure;
1407 sr=SalReasonTemporarilyUnavailable;
1409 error=SalErrorFailure;
1415 error=SalErrorFailure;
1416 sr=SalReasonDoNotDisturb;
1419 error=SalErrorFailure;
1420 sr=SalReasonDeclined;
1424 error=SalErrorFailure;
1425 sr=SalReasonUnknown;
1426 }else error=SalErrorNoResponse;
1428 op->terminated=TRUE;
1429 sal->callbacks.call_failure(op,error,sr,reason,code);
1430 if (computedReason != NULL){
1431 ms_free(computedReason);
1436 /* Request remote side to send us VFU */
1437 void sal_call_send_vfu_request(SalOp *h){
1438 osip_message_t *msg=NULL;
1440 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1444 " <picture_fast_update></picture_fast_update>"
1452 eXosip_call_build_info(h->did,&msg);
1454 osip_message_set_body(msg,info_body,strlen(info_body));
1455 osip_message_set_content_type(msg,"application/media_control+xml");
1456 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1457 osip_message_set_content_length(msg,clen);
1458 eXosip_call_send_request(h->did,msg);
1459 ms_message("Sending VFU request !");
1464 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1465 SalOp *op=find_op(sal,ev);
1466 osip_body_t *body=NULL;
1469 ms_warning("media control xml received without operation context!");
1473 osip_message_get_body(ev->request,0,&body);
1474 if (body && body->body!=NULL &&
1475 strstr(body->body,"picture_fast_update")){
1476 osip_message_t *ans=NULL;
1477 ms_message("Receiving VFU request !");
1478 if (sal->callbacks.vfu_request){
1479 sal->callbacks.vfu_request(op);
1480 eXosip_call_build_answer(ev->tid,200,&ans);
1482 eXosip_call_send_answer(ev->tid,200,ans);
1486 /*in all other cases we must say it is not implemented.*/
1488 osip_message_t *ans=NULL;
1490 eXosip_call_build_answer(ev->tid,501,&ans);
1492 eXosip_call_send_answer(ev->tid,501,ans);
1497 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1498 SalOp *op=find_op(sal,ev);
1499 osip_body_t *body=NULL;
1502 ms_warning("media dtmf relay received without operation context!");
1506 osip_message_get_body(ev->request,0,&body);
1507 if (body && body->body!=NULL){
1508 osip_message_t *ans=NULL;
1509 const char *name=strstr(body->body,"Signal");
1510 if (name==NULL) name=strstr(body->body,"signal");
1512 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1515 name+=strlen("signal");
1516 if (sscanf(name," = %1s",tmp)==1){
1517 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1518 if (sal->callbacks.dtmf_received != NULL)
1519 sal->callbacks.dtmf_received(op, tmp[0]);
1523 eXosip_call_build_answer(ev->tid,200,&ans);
1525 eXosip_call_send_answer(ev->tid,200,ans);
1530 static void fill_options_answer(osip_message_t *options){
1531 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1532 osip_message_set_accept(options,"application/sdp");
1535 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1536 osip_header_t *h=NULL;
1537 osip_message_t *ans=NULL;
1538 ms_message("Receiving REFER request !");
1539 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1542 osip_from_t *from=NULL;
1544 osip_from_init(&from);
1546 if (osip_from_parse(from,h->hvalue)==0){
1548 osip_uri_header_t *uh=NULL;
1549 osip_header_t *referred_by=NULL;
1550 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1551 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1552 ms_message("Found replaces in Refer-To");
1554 ms_free(op->replaces);
1556 op->replaces=ms_strdup(uh->gvalue);
1558 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1559 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1560 if (op->referred_by)
1561 ms_free(op->referred_by);
1562 op->referred_by=ms_strdup(referred_by->hvalue);
1565 osip_uri_header_freelist(&from->url->url_headers);
1566 osip_from_to_str(from,&tmp);
1567 sal->callbacks.refer_received(sal,op,tmp);
1569 osip_from_free(from);
1572 eXosip_call_build_answer(ev->tid,202,&ans);
1574 eXosip_call_send_answer(ev->tid,202,ans);
1579 ms_warning("cannot do anything with the refer without destination\n");
1583 static void process_notify(Sal *sal, eXosip_event_t *ev){
1584 osip_header_t *h=NULL;
1586 SalOp *op=find_op(sal,ev);
1587 osip_message_t *ans=NULL;
1589 ms_message("Receiving NOTIFY request !");
1590 osip_from_to_str(ev->request->from,&from);
1591 osip_message_header_get_byname(ev->request,"Event",0,&h);
1593 osip_body_t *body=NULL;
1594 //osip_content_type_t *ct=NULL;
1595 osip_message_get_body(ev->request,0,&body);
1596 //ct=osip_message_get_content_type(ev->request);
1597 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1598 /*special handling of refer events*/
1599 if (body && body->body){
1600 osip_message_t *msg;
1601 osip_message_init(&msg);
1602 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1603 int code=osip_message_get_status_code(msg);
1605 sal->callbacks.notify_refer(op,SalReferTrying);
1606 }else if (code==200){
1607 sal->callbacks.notify_refer(op,SalReferSuccess);
1608 }else if (code>=400){
1609 sal->callbacks.notify_refer(op,SalReferFailed);
1612 osip_message_free(msg);
1615 /*generic handling*/
1616 sal->callbacks.notify(op,from,h->hvalue);
1619 /*answer that we received the notify*/
1621 eXosip_call_build_answer(ev->tid,200,&ans);
1623 eXosip_call_send_answer(ev->tid,200,ans);
1628 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1629 osip_message_t *ans=NULL;
1631 if (MSG_IS_INFO(ev->request)){
1632 osip_content_type_t *ct;
1633 ct=osip_message_get_content_type(ev->request);
1634 if (ct && ct->subtype){
1635 if (strcmp(ct->subtype,"media_control+xml")==0)
1636 process_media_control_xml(sal,ev);
1637 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1638 process_dtmf_relay(sal,ev);
1640 ms_message("Unhandled SIP INFO.");
1641 /*send an "Not implemented" answer*/
1643 eXosip_call_build_answer(ev->tid,501,&ans);
1645 eXosip_call_send_answer(ev->tid,501,ans);
1649 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1651 eXosip_call_build_answer(ev->tid,200,&ans);
1653 eXosip_call_send_answer(ev->tid,200,ans);
1656 }else if(MSG_IS_MESSAGE(ev->request)){
1657 /* SIP messages could be received into call */
1658 text_received(sal, ev);
1660 eXosip_call_build_answer(ev->tid,200,&ans);
1662 eXosip_call_send_answer(ev->tid,200,ans);
1664 }else if(MSG_IS_REFER(ev->request)){
1665 SalOp *op=find_op(sal,ev);
1667 ms_message("Receiving REFER request !");
1668 process_refer(sal,op,ev);
1669 }else if(MSG_IS_NOTIFY(ev->request)){
1670 process_notify(sal,ev);
1671 }else if (MSG_IS_OPTIONS(ev->request)){
1673 eXosip_call_build_answer(ev->tid,200,&ans);
1675 fill_options_answer(ans);
1676 eXosip_call_send_answer(ev->tid,200,ans);
1680 }else ms_warning("call_message_new: No request ?");
1683 static void inc_update(Sal *sal, eXosip_event_t *ev){
1684 osip_message_t *msg=NULL;
1685 ms_message("Processing incoming UPDATE");
1687 eXosip_message_build_answer(ev->tid,200,&msg);
1689 eXosip_message_send_answer(ev->tid,200,msg);
1693 static bool_t comes_from_local_if(osip_message_t *msg){
1694 osip_via_t *via=NULL;
1695 osip_message_get_via(msg,0,&via);
1698 host=osip_via_get_host(via);
1699 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1700 osip_generic_param_t *param=NULL;
1701 osip_via_param_get_byname(via,"received",¶m);
1702 if (param==NULL) return TRUE;
1703 if (param->gvalue &&
1704 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1712 static void text_received(Sal *sal, eXosip_event_t *ev){
1713 osip_body_t *body=NULL;
1714 char *from=NULL,*msg;
1715 osip_content_type_t* content_type;
1716 osip_uri_param_t* external_body_url;
1717 char unquoted_external_body_url [256];
1718 int external_body_size=0;
1720 content_type= osip_message_get_content_type(ev->request);
1721 if (!content_type) {
1722 ms_error("Could not get message because no content type");
1725 osip_from_to_str(ev->request->from,&from);
1726 if (content_type->type
1727 && strcmp(content_type->type, "text")==0
1728 && content_type->subtype
1729 && strcmp(content_type->subtype, "plain")==0 ) {
1730 osip_message_get_body(ev->request,0,&body);
1732 ms_error("Could not get text message from SIP body");
1736 sal->callbacks.text_received(sal,from,msg);
1737 } if (content_type->type
1738 && strcmp(content_type->type, "message")==0
1739 && content_type->subtype
1740 && strcmp(content_type->subtype, "external-body")==0 ) {
1742 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1743 /*remove both first and last character*/
1744 strncpy(unquoted_external_body_url
1745 ,&external_body_url->gvalue[1]
1746 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1747 unquoted_external_body_url[external_body_size-1]='\0';
1748 sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
1751 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1758 static void other_request(Sal *sal, eXosip_event_t *ev){
1759 ms_message("in other_request");
1760 if (ev->request==NULL) return;
1761 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1762 text_received(sal,ev);
1763 eXosip_message_send_answer(ev->tid,200,NULL);
1764 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1765 osip_message_t *options=NULL;
1766 eXosip_options_build_answer(ev->tid,200,&options);
1767 fill_options_answer(options);
1768 eXosip_options_send_answer(ev->tid,200,options);
1769 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1770 ms_message("Receiving REFER request !");
1771 if (comes_from_local_if(ev->request)) {
1772 process_refer(sal,NULL,ev);
1773 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1774 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1779 osip_message_to_str(ev->request,&tmp,&msglen);
1781 ms_message("Unsupported request received:\n%s",tmp);
1784 /*answer with a 501 Not implemented*/
1785 eXosip_message_send_answer(ev->tid,501,NULL);
1789 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1790 osip_via_t *via=NULL;
1791 osip_message_get_via(msg,0,&via);
1793 osip_free(via->port);
1794 via->port=osip_strdup(port);
1795 osip_free(via->host);
1796 via->host=osip_strdup(ip);
1801 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1802 osip_contact_t *ctt=NULL;
1803 const char *received;
1805 SalTransport transport;
1808 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1809 osip_message_get_contact(request,0,&ctt);
1811 ms_warning("fix_message_contact(): no contact to update");
1814 if (expire_last_contact){
1815 osip_contact_t *oldct=NULL,*prevct;
1816 osip_generic_param_t *param=NULL;
1817 osip_contact_clone(ctt,&oldct);
1818 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1819 osip_contact_free(prevct);
1820 osip_list_remove(&request->contacts,1);
1822 osip_list_add(&request->contacts,oldct,1);
1823 osip_contact_param_get_byname(oldct,"expires",¶m);
1825 if (param->gvalue) osip_free(param->gvalue);
1826 param->gvalue=osip_strdup("0");
1828 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1831 if (ctt->url->host!=NULL){
1832 osip_free(ctt->url->host);
1834 ctt->url->host=osip_strdup(received);
1835 if (ctt->url->port!=NULL){
1836 osip_free(ctt->url->port);
1838 snprintf(port,sizeof(port),"%i",rport);
1839 ctt->url->port=osip_strdup(port);
1840 if (op->masquerade_via) masquerade_via(request,received,port);
1842 if (transport != SalTransportUDP) {
1843 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1848 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1849 osip_contact_t *ctt=NULL;
1850 SalAddress* ori_contact_address=NULL;
1851 const char *received;
1853 SalTransport transport;
1855 osip_message_t *msg=NULL;
1856 Sal* sal=op->base.root;
1858 bool_t found_valid_contact=FALSE;
1859 bool_t from_request=FALSE;
1861 if (sal->double_reg==FALSE ) return FALSE;
1863 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1866 osip_message_get_contact(last_answer,i,&ctt);
1867 if (!from_request && ctt==NULL) {
1868 osip_message_get_contact(orig_request,0,&ctt);
1872 osip_contact_to_str(ctt,&tmp);
1873 ori_contact_address = sal_address_new(tmp);
1875 /*check if contact is up to date*/
1876 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1877 && sal_address_get_port_int(ori_contact_address) == rport
1878 && sal_address_get_transport(ori_contact_address) == transport) {
1880 ms_message("Register response has up to date contact, doing nothing.");
1882 ms_warning("Register response does not have up to date contact, but last request had."
1883 "Stupid registrar detected, giving up.");
1885 found_valid_contact=TRUE;
1888 sal_address_destroy(ori_contact_address);
1891 }while(!found_valid_contact);
1892 if (!found_valid_contact)
1893 ms_message("Contact do not match, resending register.");
1897 eXosip_register_build_register(op->rid,op->expires,&msg);
1900 ms_warning("Fail to create a contact updated register.");
1903 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1904 eXosip_register_send_register(op->rid,msg);
1906 ms_message("Resending new register with updated contact");
1907 update_contact_from_response(op,last_answer);
1910 ms_warning("Fail to send updated register.");
1918 static void registration_success(Sal *sal, eXosip_event_t *ev){
1919 SalOp *op=sal_find_register(sal,ev->rid);
1920 osip_header_t *h=NULL;
1923 ms_error("Receiving register response for unknown operation");
1926 osip_message_get_expires(ev->request,0,&h);
1927 if (h!=NULL && atoi(h->hvalue)!=0){
1929 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1930 sal->callbacks.register_success(op,registered);
1933 sal->callbacks.register_success(op,FALSE);
1937 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1939 const char *reason=NULL;
1940 SalOp *op=sal_find_register(sal,ev->rid);
1941 SalReason sr=SalReasonUnknown;
1942 SalError se=SalErrorUnknown;
1945 ms_error("Receiving register failure for unknown operation");
1949 status_code=osip_message_get_status_code(ev->response);
1950 reason=osip_message_get_reason_phrase(ev->response);
1952 switch(status_code){
1955 return process_authentication(sal,ev);
1957 case 423: /*interval too brief*/
1958 {/*retry with greater interval */
1959 osip_header_t *h=NULL;
1960 osip_message_t *msg=NULL;
1961 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1962 if (h && h->hvalue && h->hvalue[0]!='\0'){
1963 int val=atoi(h->hvalue);
1964 if (val>op->expires)
1966 }else op->expires*=2;
1968 eXosip_register_build_register(op->rid,op->expires,&msg);
1969 eXosip_register_send_register(op->rid,msg);
1973 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1974 in vias, such as ekiga.net
1975 On the opposite, freephonie.net bugs when via are masqueraded.
1977 op->masquerade_via=TRUE;
1979 /* if contact is up to date, process the failure, otherwise resend a new register with
1980 updated contact first, just in case the faillure is due to incorrect contact */
1981 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1982 return TRUE; /*we are retrying with an updated contact*/
1983 if (status_code==403){
1985 sr=SalReasonForbidden;
1986 }else if (status_code==0){
1987 se=SalErrorNoResponse;
1989 sal->callbacks.register_failure(op,se,sr,reason);
1994 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1995 SalOp *op=find_op(sal,ev);
1997 ms_warning("other_request_reply(): Receiving response to unknown request.");
2001 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2002 update_contact_from_response(op,ev->response);
2003 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2004 sal->callbacks.ping_reply(op);
2006 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2007 /*out of call message acknolegment*/
2008 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2010 if (ev->response->status_code<200){
2011 status=SalTextDeliveryInProgress;
2012 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2013 status=SalTextDeliveryDone;
2016 sal->callbacks.text_delivery_update(op,status);
2020 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2021 SalOp *op=find_op(sal,ev);
2023 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2024 if (op->sipfrag_pending){
2025 send_notify_for_refer(op->did,op->sipfrag_pending);
2026 op->sipfrag_pending=NULL;
2032 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2033 ms_message("linphone process event get a message %d\n",ev->type);
2035 case EXOSIP_CALL_ANSWERED:
2036 ms_message("CALL_ANSWERED\n");
2037 call_accepted(sal,ev);
2038 authentication_ok(sal,ev);
2040 case EXOSIP_CALL_CLOSED:
2041 case EXOSIP_CALL_CANCELLED:
2042 ms_message("CALL_CLOSED or CANCELLED\n");
2043 call_terminated(sal,ev);
2045 case EXOSIP_CALL_TIMEOUT:
2046 case EXOSIP_CALL_NOANSWER:
2047 ms_message("CALL_TIMEOUT or NOANSWER\n");
2048 return call_failure(sal,ev);
2050 case EXOSIP_CALL_REQUESTFAILURE:
2051 case EXOSIP_CALL_GLOBALFAILURE:
2052 case EXOSIP_CALL_SERVERFAILURE:
2053 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2054 return call_failure(sal,ev);
2056 case EXOSIP_CALL_RELEASED:
2057 ms_message("CALL_RELEASED\n");
2058 call_released(sal, ev);
2060 case EXOSIP_CALL_INVITE:
2061 ms_message("CALL_NEW\n");
2062 inc_new_call(sal,ev);
2064 case EXOSIP_CALL_REINVITE:
2065 handle_reinvite(sal,ev);
2067 case EXOSIP_CALL_ACK:
2068 ms_message("CALL_ACK");
2071 case EXOSIP_CALL_REDIRECTED:
2072 ms_message("CALL_REDIRECTED");
2073 eXosip_default_action(ev);
2075 case EXOSIP_CALL_PROCEEDING:
2076 ms_message("CALL_PROCEEDING");
2077 call_proceeding(sal,ev);
2079 case EXOSIP_CALL_RINGING:
2080 ms_message("CALL_RINGING");
2081 call_ringing(sal,ev);
2082 authentication_ok(sal,ev);
2084 case EXOSIP_CALL_MESSAGE_NEW:
2085 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2086 call_message_new(sal,ev);
2088 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2090 (ev->response->status_code==407 || ev->response->status_code==401)){
2091 return process_authentication(sal,ev);
2094 case EXOSIP_CALL_MESSAGE_ANSWERED:
2095 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2096 process_in_call_reply(sal,ev);
2098 case EXOSIP_IN_SUBSCRIPTION_NEW:
2099 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2100 sal_exosip_subscription_recv(sal,ev);
2102 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2103 ms_message("CALL_SUBSCRIPTION_NEW ");
2104 sal_exosip_in_subscription_closed(sal,ev);
2106 case EXOSIP_SUBSCRIPTION_UPDATE:
2107 ms_message("CALL_SUBSCRIPTION_UPDATE");
2109 case EXOSIP_SUBSCRIPTION_NOTIFY:
2110 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2111 sal_exosip_notify_recv(sal,ev);
2113 case EXOSIP_SUBSCRIPTION_ANSWERED:
2114 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2115 sal_exosip_subscription_answered(sal,ev);
2117 case EXOSIP_SUBSCRIPTION_CLOSED:
2118 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2119 sal_exosip_subscription_closed(sal,ev);
2121 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2122 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2123 return process_authentication(sal,ev);
2125 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2126 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2127 sal_exosip_subscription_closed(sal,ev);
2129 case EXOSIP_REGISTRATION_FAILURE:
2130 ms_message("REGISTRATION_FAILURE\n");
2131 return registration_failure(sal,ev);
2133 case EXOSIP_REGISTRATION_SUCCESS:
2134 authentication_ok(sal,ev);
2135 registration_success(sal,ev);
2137 case EXOSIP_MESSAGE_NEW:
2138 other_request(sal,ev);
2140 case EXOSIP_MESSAGE_PROCEEDING:
2141 case EXOSIP_MESSAGE_ANSWERED:
2142 case EXOSIP_MESSAGE_REDIRECTED:
2143 case EXOSIP_MESSAGE_SERVERFAILURE:
2144 case EXOSIP_MESSAGE_GLOBALFAILURE:
2145 other_request_reply(sal,ev);
2147 case EXOSIP_MESSAGE_REQUESTFAILURE:
2148 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2150 switch (ev->response->status_code) {
2153 return process_authentication(sal,ev);
2155 eXosip_automatic_action ();
2160 other_request_reply(sal,ev);
2163 ms_message("Unhandled exosip event ! %i",ev->type);
2169 int sal_iterate(Sal *sal){
2171 while((ev=eXosip_event_wait(0,0))!=NULL){
2172 if (process_event(sal,ev))
2173 eXosip_event_free(ev);
2175 #ifdef HAVE_EXOSIP_TRYLOCK
2176 if (eXosip_trylock()==0){
2177 eXosip_automatic_refresh();
2180 ms_warning("eXosip_trylock busy.");
2184 eXosip_automatic_refresh();
2190 static void register_set_contact(osip_message_t *msg, const char *contact){
2191 osip_uri_param_t *param = NULL;
2192 osip_contact_t *ct=NULL;
2194 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2195 osip_message_get_contact(msg,0,&ct);
2197 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2198 if (param && param->gvalue)
2199 line=osip_strdup(param->gvalue);
2201 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2202 osip_message_set_contact(msg,contact);
2203 osip_message_get_contact(msg,0,&ct);
2204 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2207 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2209 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2211 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2212 osip_message_set_route(msg,tmp);
2215 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2216 osip_message_t *msg;
2217 const char *contact=sal_op_get_contact(h);
2219 sal_op_set_route(h,proxy);
2221 SalAddress *from_parsed=sal_address_new(from);
2223 char *uri, *domain_ptr = NULL;
2224 if (from_parsed==NULL) {
2225 ms_warning("sal_register() bad from %s",from);
2228 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2229 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2230 uri = sal_address_as_string_uri_only(from_parsed);
2231 if (uri) domain_ptr = strchr(uri, '@');
2233 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2235 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2237 if (uri) ms_free(uri);
2238 sal_address_destroy(from_parsed);
2240 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2242 if (contact) register_set_contact(msg,contact);
2243 sal_register_add_route(msg,proxy);
2244 sal_add_register(h->base.root,h);
2246 ms_error("Could not build initial register.");
2252 eXosip_register_build_register(h->rid,expires,&msg);
2253 sal_register_add_route(msg,proxy);
2256 eXosip_register_send_register(h->rid,msg);
2259 return (msg != NULL) ? 0 : -1;
2262 int sal_register_refresh(SalOp *op, int expires){
2263 osip_message_t *msg=NULL;
2264 const char *contact=sal_op_get_contact(op);
2267 ms_error("Unexistant registration context, not possible to refresh.");
2270 #ifdef HAVE_EXOSIP_TRYLOCK
2273 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2274 * 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
2275 * the exosip lock in a non blocking way, and give up if it takes too long*/
2276 while (eXosip_trylock()!=0){
2278 if (tries>30) {/*after 3 seconds, give up*/
2279 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2287 eXosip_register_build_register(op->rid,expires,&msg);
2289 if (contact) register_set_contact(msg,contact);
2290 sal_register_add_route(msg,sal_op_get_route(op));
2291 eXosip_register_send_register(op->rid,msg);
2292 }else ms_error("Could not build REGISTER refresh message.");
2294 return (msg != NULL) ? 0 : -1;
2298 int sal_unregister(SalOp *h){
2299 osip_message_t *msg=NULL;
2301 eXosip_register_build_register(h->rid,0,&msg);
2302 if (msg) eXosip_register_send_register(h->rid,msg);
2303 else ms_warning("Could not build unREGISTER !");
2308 SalAddress * sal_address_new(const char *uri){
2310 osip_from_init(&from);
2312 // Remove front spaces
2313 while (uri[0]==' ') {
2317 if (osip_from_parse(from,uri)!=0){
2318 osip_from_free(from);
2321 if (from->displayname!=NULL && from->displayname[0]=='"'){
2322 char *unquoted=osip_strdup_without_quote(from->displayname);
2323 osip_free(from->displayname);
2324 from->displayname=unquoted;
2326 return (SalAddress*)from;
2329 SalAddress * sal_address_clone(const SalAddress *addr){
2330 osip_from_t *ret=NULL;
2331 osip_from_clone((osip_from_t*)addr,&ret);
2332 return (SalAddress*)ret;
2335 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2337 const char *sal_address_get_scheme(const SalAddress *addr){
2338 const osip_from_t *u=(const osip_from_t*)addr;
2339 return null_if_empty(u->url->scheme);
2342 const char *sal_address_get_display_name(const SalAddress* addr){
2343 const osip_from_t *u=(const osip_from_t*)addr;
2344 return null_if_empty(u->displayname);
2347 const char *sal_address_get_username(const SalAddress *addr){
2348 const osip_from_t *u=(const osip_from_t*)addr;
2349 return null_if_empty(u->url->username);
2352 const char *sal_address_get_domain(const SalAddress *addr){
2353 const osip_from_t *u=(const osip_from_t*)addr;
2354 return null_if_empty(u->url->host);
2357 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2358 osip_from_t *u=(osip_from_t*)addr;
2359 if (u->displayname!=NULL){
2360 osip_free(u->displayname);
2361 u->displayname=NULL;
2363 if (display_name!=NULL && display_name[0]!='\0'){
2364 u->displayname=osip_strdup(display_name);
2368 void sal_address_set_username(SalAddress *addr, const char *username){
2369 osip_from_t *uri=(osip_from_t*)addr;
2370 if (uri->url->username!=NULL){
2371 osip_free(uri->url->username);
2372 uri->url->username=NULL;
2375 uri->url->username=osip_strdup(username);
2378 void sal_address_set_domain(SalAddress *addr, const char *host){
2379 osip_from_t *uri=(osip_from_t*)addr;
2380 if (uri->url->host!=NULL){
2381 osip_free(uri->url->host);
2382 uri->url->host=NULL;
2385 uri->url->host=osip_strdup(host);
2388 void sal_address_set_port(SalAddress *addr, const char *port){
2389 osip_from_t *uri=(osip_from_t*)addr;
2390 if (uri->url->port!=NULL){
2391 osip_free(uri->url->port);
2392 uri->url->port=NULL;
2395 uri->url->port=osip_strdup(port);
2398 void sal_address_set_port_int(SalAddress *uri, int port){
2401 /*this is the default, special case to leave the port field blank*/
2402 sal_address_set_port(uri,NULL);
2405 snprintf(tmp,sizeof(tmp),"%i",port);
2406 sal_address_set_port(uri,tmp);
2409 void sal_address_clean(SalAddress *addr){
2410 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2411 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2414 char *sal_address_as_string(const SalAddress *u){
2416 osip_from_t *from=(osip_from_t *)u;
2417 char *old_displayname=NULL;
2418 /* hack to force use of quotes around the displayname*/
2419 if (from->displayname!=NULL
2420 && from->displayname[0]!='"'){
2421 old_displayname=from->displayname;
2422 from->displayname=osip_enquote(from->displayname);
2424 osip_from_to_str(from,&tmp);
2425 if (old_displayname!=NULL){
2426 ms_free(from->displayname);
2427 from->displayname=old_displayname;
2434 char *sal_address_as_string_uri_only(const SalAddress *u){
2435 char *tmp=NULL,*ret;
2436 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2441 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2442 osip_uri_param_t *param=NULL;
2443 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2445 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2447 osip_free(param->gvalue);
2448 param->gvalue=value ? osip_strdup(value) : NULL;
2453 void sal_address_destroy(SalAddress *u){
2454 osip_from_free((osip_from_t*)u);
2457 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2458 ctx->keepalive_period=value;
2459 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2461 unsigned int sal_get_keepalive_period(Sal *ctx) {
2462 return ctx->keepalive_period;
2465 const char * sal_address_get_port(const SalAddress *addr) {
2466 const osip_from_t *u=(const osip_from_t*)addr;
2467 return null_if_empty(u->url->port);
2470 int sal_address_get_port_int(const SalAddress *uri) {
2471 const char* port = sal_address_get_port(uri);
2478 SalTransport sal_address_get_transport(const SalAddress* addr) {
2479 const osip_from_t *u=(const osip_from_t*)addr;
2480 osip_uri_param_t *transport_param=NULL;
2481 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2482 if (transport_param == NULL){
2483 return SalTransportUDP;
2485 return sal_transport_parse(transport_param->gvalue);
2488 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2489 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2492 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2493 int sal_call_update(SalOp *h, const char *subject){
2495 osip_message_t *reinvite=NULL;
2498 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2503 osip_message_set_subject(reinvite,subject);
2504 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2505 if (h->base.contact){
2506 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2507 osip_message_set_contact(reinvite,h->base.contact);
2509 if (h->base.root->session_expires!=0){
2510 osip_message_set_header(reinvite, "Session-expires", "200");
2511 osip_message_set_supported(reinvite, "timer");
2513 if (h->base.local_media){
2514 h->sdp_offering=TRUE;
2515 set_sdp_from_desc(reinvite,h->base.local_media);
2516 }else h->sdp_offering=FALSE;
2518 err = eXosip_call_send_request(h->did, reinvite);
2522 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2523 ctx->reuse_authorization=value;
2526 bool_t sal_is_transport_enabled(Sal *sal, SalTransport transport) {
2527 if (transport == SalTransportTLS || transport == SalTransportDTLS) {
2528 return sal->exosip_has_ssl;