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;
348 int sal_unlisten_ports(Sal *ctx){
357 int sal_reset_transports(Sal *ctx){
358 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
360 ms_message("Exosip transports reset.");
361 eXosip_reset_transports();
365 ms_warning("sal_reset_transports() not implemented in this version.");
371 static void set_tls_options(Sal *ctx){
373 eXosip_tls_ctx_t tlsCtx;
374 memset(&tlsCtx, 0, sizeof(tlsCtx));
375 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
376 eXosip_set_tls_ctx(&tlsCtx);
378 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
379 eXosip_tls_verify_certificate(ctx->verify_server_certs);
383 void sal_set_dscp(Sal *ctx, int dscp){
386 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
389 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
392 int proto=IPPROTO_UDP;
393 int keepalive = ctx->keepalive_period;
396 case SalTransportUDP:
398 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
400 case SalTransportTCP:
401 case SalTransportTLS:
404 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
405 set_tls_options(ctx);
408 ms_warning("unexpected proto, using datagram");
410 /*see if it looks like an IPv6 address*/
411 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
412 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
413 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
414 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
415 sal_set_dscp(ctx,ctx->dscp);
416 sal_use_dates(ctx,ctx->add_dates);
418 ipv6=strchr(addr,':')!=NULL;
419 eXosip_enable_ipv6(ipv6);
421 if (is_secure && tr == SalTransportUDP){
422 ms_fatal("SIP over DTLS is not supported yet.");
425 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
430 ortp_socket_t sal_get_socket(Sal *ctx){
431 #ifdef HAVE_EXOSIP_GET_SOCKET
432 return eXosip_get_socket(IPPROTO_UDP);
434 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
439 void sal_set_user_agent(Sal *ctx, const char *user_agent){
440 eXosip_set_user_agent(user_agent);
443 void sal_use_session_timers(Sal *ctx, int expires){
444 ctx->session_expires=expires;
447 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
448 ctx->one_matching_codec=one_matching_codec;
451 MSList *sal_get_pending_auths(Sal *sal){
452 return ms_list_copy(sal->pending_auths);
455 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
456 ctx->double_reg=enabled;
459 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
460 ctx->expire_old_contact=enabled;
463 void sal_use_dates(Sal *ctx, bool_t enabled){
464 ctx->add_dates=enabled;
465 #ifdef EXOSIP_OPT_REGISTER_WITH_DATE
468 eXosip_set_option(EXOSIP_OPT_REGISTER_WITH_DATE,&tmp);
471 if (enabled) ms_warning("Exosip does not support EXOSIP_OPT_REGISTER_WITH_DATE option.");
475 void sal_use_rport(Sal *ctx, bool_t use_rports){
476 ctx->use_rports=use_rports;
478 void sal_use_101(Sal *ctx, bool_t use_101){
479 ctx->use_101=use_101;
482 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
484 ms_free(ctx->rootCa);
485 ctx->rootCa = ms_strdup(rootCa);
486 set_tls_options(ctx);
489 const char *sal_get_root_ca(Sal* ctx) {
493 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
494 ctx->verify_server_certs=verify;
495 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
496 eXosip_tls_verify_certificate(verify);
500 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
501 osip_via_t *via=NULL;
502 osip_generic_param_t *param=NULL;
503 const char *rport=NULL;
507 osip_message_get_via(msg,0,&via);
509 ms_warning("extract_received_rport(): no via.");
513 *transport = sal_transport_parse(via->protocol);
515 if (via->port && via->port[0]!='\0')
516 *rportval=atoi(via->port);
518 osip_via_param_get_byname(via,"rport",¶m);
521 if (rport && rport[0]!='\0') *rportval=atoi(rport);
525 osip_via_param_get_byname(via,"received",¶m);
526 if (param) *received=param->gvalue;
528 if (rport==NULL && *received==NULL){
529 ms_warning("extract_received_rport(): no rport and no received parameters.");
535 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
539 sdp_message_to_str(msg,&sdp);
541 snprintf(clen,sizeof(clen),"%i",sdplen);
542 osip_message_set_body(sip,sdp,sdplen);
543 osip_message_set_content_type(sip,"application/sdp");
544 osip_message_set_content_length(sip,clen);
548 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
549 sdp_message_t *msg=media_description_to_sdp(desc);
551 ms_error("Fail to print sdp message !");
555 sdp_message_free(msg);
558 static void sdp_process(SalOp *h){
559 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
561 sal_media_description_unref(h->result);
563 h->result=sal_media_description_new();
564 if (h->sdp_offering){
565 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
569 sdp_message_free(h->sdp_answer);
571 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
572 h->sdp_answer=media_description_to_sdp(h->result);
573 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
574 It should contains media parameters constraint from the remote offer, not our response*/
575 strcpy(h->result->addr,h->base.remote_media->addr);
576 h->result->bandwidth=h->base.remote_media->bandwidth;
578 for(i=0;i<h->result->nstreams;++i){
579 if (h->result->streams[i].rtp_port>0){
580 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
581 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
582 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
583 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
584 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
585 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
587 if (h->result->streams[i].proto == SalProtoRtpSavp) {
588 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
596 int sal_call_is_offerer(const SalOp *h){
597 return h->sdp_offering;
600 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
602 sal_media_description_ref(desc);
603 if (h->base.local_media)
604 sal_media_description_unref(h->base.local_media);
605 h->base.local_media=desc;
606 if (h->base.remote_media){
607 /*case of an incoming call where we modify the local capabilities between the time
608 * the call is ringing and it is accepted (for example if you want to accept without video*/
609 /*reset the sdp answer so that it is computed again*/
611 sdp_message_free(h->sdp_answer);
618 int sal_call(SalOp *h, const char *from, const char *to){
621 osip_message_t *invite=NULL;
622 osip_call_id_t *callid;
623 sal_op_set_from(h,from);
625 sal_exosip_fix_route(h);
627 h->terminated = FALSE;
629 route = sal_op_get_route(h);
630 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
632 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
633 err, from, to, route);
636 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
637 if (h->base.contact){
638 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
639 osip_message_set_contact(invite,h->base.contact);
641 if (h->base.root->session_expires!=0){
642 osip_message_set_header(invite, "Session-expires", "200");
643 osip_message_set_supported(invite, "timer");
645 if (h->base.local_media){
646 h->sdp_offering=TRUE;
647 set_sdp_from_desc(invite,h->base.local_media);
648 }else h->sdp_offering=FALSE;
650 osip_message_set_header(invite,"Replaces",h->replaces);
652 osip_message_set_header(invite,"Referred-By",h->referred_by);
656 err=eXosip_call_send_initial_invite(invite);
660 ms_error("Fail to send invite ! Error code %d", err);
663 callid=osip_message_get_call_id(invite);
664 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
665 sal_add_call(h->base.root,h);
670 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
673 /*if early media send also 180 and 183 */
677 eXosip_call_build_answer(h->tid,183,&msg);
681 set_sdp(msg,h->sdp_answer);
682 sdp_message_free(h->sdp_answer);
685 eXosip_call_send_answer(h->tid,183,msg);
690 eXosip_call_send_answer(h->tid,180,NULL);
696 int sal_call_accept(SalOp * h){
698 const char *contact=sal_op_get_contact(h);
700 int err=eXosip_call_build_answer(h->tid,200,&msg);
701 if (err<0 || msg==NULL){
702 ms_error("Fail to build answer for call: err=%i",err);
705 if (h->base.root->session_expires!=0){
706 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
710 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
711 osip_message_set_contact(msg,contact);
714 if (h->base.local_media){
715 /*this is the case where we received an invite without SDP*/
716 if (h->sdp_offering) {
717 set_sdp_from_desc(msg,h->base.local_media);
719 if (h->sdp_answer==NULL) sdp_process(h);
721 set_sdp(msg,h->sdp_answer);
722 sdp_message_free(h->sdp_answer);
727 ms_error("You are accepting a call but not defined any media capabilities !");
729 eXosip_call_send_answer(h->tid,200,msg);
733 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
734 if (reason==SalReasonBusy){
736 eXosip_call_send_answer(h->tid,486,NULL);
739 else if (reason==SalReasonTemporarilyUnavailable){
741 eXosip_call_send_answer(h->tid,480,NULL);
743 }else if (reason==SalReasonDoNotDisturb){
745 eXosip_call_send_answer(h->tid,600,NULL);
747 }else if (reason==SalReasonMedia){
749 eXosip_call_send_answer(h->tid,415,NULL);
751 }else if (redirect!=NULL && reason==SalReasonRedirect){
754 if (strstr(redirect,"sip:")!=0) code=302;
757 eXosip_call_build_answer(h->tid,code,&msg);
758 osip_message_set_contact(msg,redirect);
759 eXosip_call_send_answer(h->tid,code,msg);
761 }else sal_call_terminate(h);
765 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
766 return h->base.remote_media;
769 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
770 if (h->base.local_media && h->base.remote_media && !h->result){
776 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
777 if (refered_call->replaces)
778 h->replaces=ms_strdup(refered_call->replaces);
779 if (refered_call->referred_by)
780 h->referred_by=ms_strdup(refered_call->referred_by);
784 static int send_notify_for_refer(int did, const char *sipfrag){
787 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
790 ms_warning("Could not build NOTIFY for refer.");
793 osip_message_set_content_type(msg,"message/sipfrag");
794 osip_message_set_header(msg,"Event","refer");
795 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
796 eXosip_call_send_request(did,msg);
801 /* currently only support to notify trying and 200Ok*/
802 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
805 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
807 else if (newcall->cid!=-1){
808 if (newcall->did==-1){
809 /* not yet established*/
810 if (!newcall->terminated){
812 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
815 if (!newcall->terminated){
816 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
817 /* we need previous notify transaction to complete, so buffer the request for later*/
818 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
826 int sal_ping(SalOp *op, const char *from, const char *to){
827 osip_message_t *options=NULL;
829 sal_op_set_from(op,from);
830 sal_op_set_to(op,to);
831 sal_exosip_fix_route(op);
833 eXosip_options_build_request (&options, sal_op_get_to(op),
834 sal_op_get_from(op),sal_op_get_route(op));
836 if (op->base.root->session_expires!=0){
837 osip_message_set_header(options, "Session-expires", "200");
838 osip_message_set_supported(options, "timer");
840 sal_add_other(sal_op_get_sal(op),op,options);
841 return eXosip_options_send_request(options);
846 int sal_call_refer(SalOp *h, const char *refer_to){
847 osip_message_t *msg=NULL;
850 eXosip_call_build_refer(h->did,refer_to, &msg);
851 if (msg) err=eXosip_call_send_request(h->did, msg);
857 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
858 osip_message_t *msg=NULL;
859 char referto[256]={0};
862 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
863 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
867 eXosip_call_build_refer(h->did,referto, &msg);
868 osip_message_set_header(msg,"Referred-By",h->base.from);
869 if (msg) err=eXosip_call_send_request(h->did, msg);
875 SalOp *sal_call_get_replaces(SalOp *h){
876 if (h!=NULL && h->replaces!=NULL){
879 cid=eXosip_call_find_by_replaces(h->replaces);
882 SalOp *ret=sal_find_call(h->base.root,cid);
889 int sal_call_send_dtmf(SalOp *h, char dtmf){
890 osip_message_t *msg=NULL;
895 eXosip_call_build_info(h->did,&msg);
897 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
898 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
899 osip_message_set_content_type(msg,"application/dtmf-relay");
900 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
901 osip_message_set_content_length(msg,clen);
902 eXosip_call_send_request(h->did,msg);
908 static void push_auth_to_exosip(const SalAuthInfo *info){
910 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
911 else userid=info->userid;
912 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
913 eXosip_add_authentication_info (info->username,userid,
914 info->password, NULL,info->realm);
917 * Just for symmetry ;-)
919 static void pop_auth_from_exosip() {
920 eXosip_clear_authentication_info();
923 int sal_call_terminate(SalOp *h){
925 if (h == NULL) return -1;
926 if (h->auth_info) push_auth_to_exosip(h->auth_info);
928 err=eXosip_call_terminate(h->cid,h->did);
930 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
932 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
938 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
939 if (h->terminated) return;
940 if (h->pending_auth){
941 push_auth_to_exosip(info);
943 /*FIXME exosip does not take into account this update register message*/
945 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
949 update_contact_from_response(h,h->pending_auth->response);
951 eXosip_default_action(h->pending_auth);
953 ms_message("eXosip_default_action() done");
954 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
956 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
957 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
960 void sal_op_cancel_authentication(SalOp *h) {
962 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
963 } else if (h->cid >0) {
964 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
966 ms_warning("Auth failure not handled");
970 static void set_network_origin(SalOp *op, osip_message_t *req){
971 const char *received=NULL;
974 SalTransport transport;
975 if (extract_received_rport(req,&received,&rport,&transport)!=0){
976 osip_via_t *via=NULL;
978 osip_message_get_via(req,0,&via);
979 received=osip_via_get_host(via);
980 tmp=osip_via_get_port(via);
981 if (tmp) rport=atoi(tmp);
983 if (transport != SalTransportUDP) {
984 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
986 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
988 __sal_op_set_network_origin(op,origin);
991 static void set_remote_ua(SalOp* op, osip_message_t *req){
992 if (op->base.remote_ua==NULL){
993 osip_header_t *h=NULL;
994 osip_message_get_user_agent(req,0,&h);
996 op->base.remote_ua=ms_strdup(h->hvalue);
1001 static void set_replaces(SalOp *op, osip_message_t *req){
1002 osip_header_t *h=NULL;
1005 ms_free(op->replaces);
1008 osip_message_header_get_byname(req,"replaces",0,&h);
1010 if (h->hvalue && h->hvalue[0]!='\0'){
1011 op->replaces=ms_strdup(h->hvalue);
1016 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1018 return sal_find_call(sal,ev->cid);
1021 return sal_find_register(sal,ev->rid);
1024 return sal_find_out_subscribe(sal,ev->sid);
1027 return sal_find_in_subscribe(sal,ev->nid);
1029 if (ev->response) return sal_find_other(sal,ev->response);
1030 else if (ev->request) return sal_find_other(sal,ev->request);
1034 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1035 SalOp *op=sal_op_new(sal);
1036 osip_from_t *from,*to;
1037 osip_call_info_t *call_info;
1039 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1040 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1041 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1043 set_network_origin(op,ev->request);
1044 set_remote_ua(op,ev->request);
1045 set_replaces(op,ev->request);
1048 op->sdp_offering=FALSE;
1049 op->base.remote_media=sal_media_description_new();
1050 sdp_to_media_description(sdp,op->base.remote_media);
1051 sdp_message_free(sdp);
1052 }else op->sdp_offering=TRUE;
1054 from=osip_message_get_from(ev->request);
1055 to=osip_message_get_to(ev->request);
1056 osip_from_to_str(from,&tmp);
1057 sal_op_set_from(op,tmp);
1059 osip_from_to_str(to,&tmp);
1060 sal_op_set_to(op,tmp);
1063 osip_message_get_call_info(ev->request,0,&call_info);
1066 osip_call_info_to_str(call_info,&tmp);
1067 if( strstr(tmp,"answer-after=") != NULL)
1069 op->auto_answer_asked=TRUE;
1070 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1078 sal_add_call(op->base.root,op);
1079 sal->callbacks.call_received(op);
1082 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1083 SalOp *op=find_op(sal,ev);
1087 ms_warning("Reinvite for non-existing operation !");
1092 sdp=eXosip_get_sdp_info(ev->request);
1093 if (op->base.remote_media){
1094 sal_media_description_unref(op->base.remote_media);
1095 op->base.remote_media=NULL;
1098 sal_media_description_unref(op->result);
1102 op->sdp_offering=FALSE;
1103 op->base.remote_media=sal_media_description_new();
1104 sdp_to_media_description(sdp,op->base.remote_media);
1105 sdp_message_free(sdp);
1108 op->sdp_offering=TRUE;
1110 sal->callbacks.call_updating(op);
1113 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1114 SalOp *op=find_op(sal,ev);
1118 ms_warning("ack for non-existing call !");
1121 if (op->terminated) {
1122 ms_warning("ack for terminated call, ignoring");
1126 if (op->sdp_offering){
1127 sdp=eXosip_get_sdp_info(ev->ack);
1129 if (op->base.remote_media)
1130 sal_media_description_unref(op->base.remote_media);
1131 op->base.remote_media=sal_media_description_new();
1132 sdp_to_media_description(sdp,op->base.remote_media);
1134 sdp_message_free(sdp);
1140 sal->callbacks.call_ack(op);
1143 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1144 const char *received;
1146 SalTransport transport;
1147 if (extract_received_rport(response,&received,&rport,&transport)==0){
1148 const char *contact=sal_op_get_contact(op);
1150 /*no contact given yet, use from instead*/
1151 contact=sal_op_get_from(op);
1154 SalAddress *addr=sal_address_new(contact);
1156 sal_address_set_domain(addr,received);
1157 sal_address_set_port_int(addr,rport);
1158 if (transport!=SalTransportUDP)
1159 sal_address_set_transport(addr,transport);
1160 tmp=sal_address_as_string(addr);
1161 ms_message("Contact address updated to %s",tmp);
1162 sal_op_set_contact(op,tmp);
1163 sal_address_destroy(addr);
1169 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1170 SalOp *op=find_op(sal,ev);
1172 if (op==NULL || op->terminated==TRUE) {
1173 ms_warning("This call has been canceled.");
1175 eXosip_call_terminate(ev->cid,ev->did);
1183 /* update contact if received and rport are set by the server
1184 note: will only be used by remote for next INVITE, if any...*/
1185 update_contact_from_response(op,ev->response);
1189 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1191 SalOp *op=find_op(sal,ev);
1192 if (call_proceeding(sal, ev)==-1) return;
1194 set_remote_ua(op,ev->response);
1195 sdp=eXosip_get_sdp_info(ev->response);
1197 op->base.remote_media=sal_media_description_new();
1198 sdp_to_media_description(sdp,op->base.remote_media);
1199 sdp_message_free(sdp);
1200 if (op->base.local_media) sdp_process(op);
1202 sal->callbacks.call_ringing(op);
1205 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1207 osip_message_t *msg=NULL;
1208 SalOp *op=find_op(sal,ev);
1209 const char *contact;
1211 if (op==NULL || op->terminated==TRUE) {
1212 ms_warning("This call has been already terminated.");
1214 eXosip_call_terminate(ev->cid,ev->did);
1220 set_remote_ua(op,ev->response);
1222 sdp=eXosip_get_sdp_info(ev->response);
1224 op->base.remote_media=sal_media_description_new();
1225 sdp_to_media_description(sdp,op->base.remote_media);
1226 sdp_message_free(sdp);
1227 if (op->base.local_media) sdp_process(op);
1229 eXosip_call_build_ack(ev->did,&msg);
1231 ms_warning("This call has been already terminated.");
1233 eXosip_call_terminate(ev->cid,ev->did);
1237 contact=sal_op_get_contact(op);
1239 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1240 osip_message_set_contact(msg,contact);
1242 if (op->sdp_answer){
1243 set_sdp(msg,op->sdp_answer);
1244 sdp_message_free(op->sdp_answer);
1245 op->sdp_answer=NULL;
1247 eXosip_call_send_ack(ev->did,msg);
1248 sal->callbacks.call_accepted(op);
1251 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1253 SalOp *op=find_op(sal,ev);
1255 ms_warning("Call terminated for already closed call ?");
1259 osip_from_to_str(ev->request->from,&from);
1261 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1262 if (from) osip_free(from);
1263 op->terminated=TRUE;
1266 static void call_released(Sal *sal, eXosip_event_t *ev){
1267 SalOp *op=find_op(sal,ev);
1269 ms_warning("No op associated to this call_released()");
1272 if (!op->terminated){
1273 /* no response received so far */
1274 call_failure(sal,ev);
1276 sal->callbacks.call_released(op);
1279 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1280 const char *prx_realm=NULL,*www_realm=NULL;
1281 osip_proxy_authenticate_t *prx_auth;
1282 osip_www_authenticate_t *www_auth;
1284 *username=osip_uri_get_username(resp->from->url);
1285 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1286 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1288 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1290 www_realm=osip_www_authenticate_get_realm(www_auth);
1294 }else if (www_realm){
1302 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1303 osip_authorization_t *auth=NULL;
1304 osip_proxy_authorization_t *prx_auth=NULL;
1306 *username=osip_uri_get_username(msg->from->url);
1307 osip_message_get_authorization(msg, 0, &auth);
1309 *realm=osip_authorization_get_realm(auth);
1312 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1314 *realm=osip_proxy_authorization_get_realm(prx_auth);
1320 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1321 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1322 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1326 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1327 if (op->pending_auth){
1328 return get_auth_data(op->pending_auth,realm,username);
1333 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1335 const char *username,*realm;
1338 ms_warning("No operation associated with this authentication !");
1341 if (get_auth_data(ev,&realm,&username)==0){
1342 if (op->pending_auth!=NULL){
1343 eXosip_event_free(op->pending_auth);
1344 op->pending_auth=ev;
1346 op->pending_auth=ev;
1347 sal_add_pending_auth(sal,op);
1350 sal->callbacks.auth_requested(op,realm,username);
1356 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1358 const char *username,*realm;
1361 ms_warning("No operation associated with this authentication_ok!");
1364 if (op->pending_auth){
1365 eXosip_event_free(op->pending_auth);
1366 sal_remove_pending_auth(sal,op);
1367 op->pending_auth=NULL;
1369 if (get_auth_data(ev,&realm,&username)==0){
1370 sal->callbacks.auth_success(op,realm,username);
1374 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1377 char* computedReason=NULL;
1378 const char *reason=NULL;
1379 SalError error=SalErrorUnknown;
1380 SalReason sr=SalReasonUnknown;
1383 op=(SalOp*)find_op(sal,ev);
1386 ms_warning("Call failure reported for a closed call, ignored.");
1391 code=osip_message_get_status_code(ev->response);
1392 reason=osip_message_get_reason_phrase(ev->response);
1393 osip_header_t *h=NULL;
1394 if (!osip_message_header_get_byname( ev->response
1398 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1399 reason = computedReason;
1407 return process_authentication(sal,ev);
1410 error=SalErrorUnknown;
1413 error=SalErrorFailure;
1414 sr=SalReasonNotFound;
1417 error=SalErrorFailure;
1421 eXosip_default_action(ev);
1425 error=SalErrorFailure;
1426 sr=SalReasonTemporarilyUnavailable;
1428 error=SalErrorFailure;
1434 error=SalErrorFailure;
1435 sr=SalReasonDoNotDisturb;
1438 error=SalErrorFailure;
1439 sr=SalReasonDeclined;
1443 error=SalErrorFailure;
1444 sr=SalReasonUnknown;
1445 }else error=SalErrorNoResponse;
1447 op->terminated=TRUE;
1448 sal->callbacks.call_failure(op,error,sr,reason,code);
1449 if (computedReason != NULL){
1450 ms_free(computedReason);
1455 /* Request remote side to send us VFU */
1456 void sal_call_send_vfu_request(SalOp *h){
1457 osip_message_t *msg=NULL;
1459 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1463 " <picture_fast_update></picture_fast_update>"
1471 eXosip_call_build_info(h->did,&msg);
1473 osip_message_set_body(msg,info_body,strlen(info_body));
1474 osip_message_set_content_type(msg,"application/media_control+xml");
1475 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1476 osip_message_set_content_length(msg,clen);
1477 eXosip_call_send_request(h->did,msg);
1478 ms_message("Sending VFU request !");
1483 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1484 SalOp *op=find_op(sal,ev);
1485 osip_body_t *body=NULL;
1488 ms_warning("media control xml received without operation context!");
1492 osip_message_get_body(ev->request,0,&body);
1493 if (body && body->body!=NULL &&
1494 strstr(body->body,"picture_fast_update")){
1495 osip_message_t *ans=NULL;
1496 ms_message("Receiving VFU request !");
1497 if (sal->callbacks.vfu_request){
1498 sal->callbacks.vfu_request(op);
1499 eXosip_call_build_answer(ev->tid,200,&ans);
1501 eXosip_call_send_answer(ev->tid,200,ans);
1505 /*in all other cases we must say it is not implemented.*/
1507 osip_message_t *ans=NULL;
1509 eXosip_call_build_answer(ev->tid,501,&ans);
1511 eXosip_call_send_answer(ev->tid,501,ans);
1516 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1517 SalOp *op=find_op(sal,ev);
1518 osip_body_t *body=NULL;
1521 ms_warning("media dtmf relay received without operation context!");
1525 osip_message_get_body(ev->request,0,&body);
1526 if (body && body->body!=NULL){
1527 osip_message_t *ans=NULL;
1528 const char *name=strstr(body->body,"Signal");
1529 if (name==NULL) name=strstr(body->body,"signal");
1531 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1534 name+=strlen("signal");
1535 if (sscanf(name," = %1s",tmp)==1){
1536 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1537 if (sal->callbacks.dtmf_received != NULL)
1538 sal->callbacks.dtmf_received(op, tmp[0]);
1542 eXosip_call_build_answer(ev->tid,200,&ans);
1544 eXosip_call_send_answer(ev->tid,200,ans);
1549 static void fill_options_answer(osip_message_t *options){
1550 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1551 osip_message_set_accept(options,"application/sdp");
1554 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1555 osip_header_t *h=NULL;
1556 osip_message_t *ans=NULL;
1557 ms_message("Receiving REFER request !");
1558 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1561 osip_from_t *from=NULL;
1563 osip_from_init(&from);
1565 if (osip_from_parse(from,h->hvalue)==0){
1567 osip_uri_header_t *uh=NULL;
1568 osip_header_t *referred_by=NULL;
1569 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1570 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1571 ms_message("Found replaces in Refer-To");
1573 ms_free(op->replaces);
1575 op->replaces=ms_strdup(uh->gvalue);
1577 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1578 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1579 if (op->referred_by)
1580 ms_free(op->referred_by);
1581 op->referred_by=ms_strdup(referred_by->hvalue);
1584 osip_uri_header_freelist(&from->url->url_headers);
1585 osip_from_to_str(from,&tmp);
1586 sal->callbacks.refer_received(sal,op,tmp);
1588 osip_from_free(from);
1591 eXosip_call_build_answer(ev->tid,202,&ans);
1593 eXosip_call_send_answer(ev->tid,202,ans);
1598 ms_warning("cannot do anything with the refer without destination\n");
1602 static void process_notify(Sal *sal, eXosip_event_t *ev){
1603 osip_header_t *h=NULL;
1605 SalOp *op=find_op(sal,ev);
1606 osip_message_t *ans=NULL;
1608 ms_message("Receiving NOTIFY request !");
1609 osip_from_to_str(ev->request->from,&from);
1610 osip_message_header_get_byname(ev->request,"Event",0,&h);
1612 osip_body_t *body=NULL;
1613 //osip_content_type_t *ct=NULL;
1614 osip_message_get_body(ev->request,0,&body);
1615 //ct=osip_message_get_content_type(ev->request);
1616 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1617 /*special handling of refer events*/
1618 if (body && body->body){
1619 osip_message_t *msg;
1620 osip_message_init(&msg);
1621 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1622 int code=osip_message_get_status_code(msg);
1624 sal->callbacks.notify_refer(op,SalReferTrying);
1625 }else if (code==200){
1626 sal->callbacks.notify_refer(op,SalReferSuccess);
1627 }else if (code>=400){
1628 sal->callbacks.notify_refer(op,SalReferFailed);
1631 osip_message_free(msg);
1634 /*generic handling*/
1635 sal->callbacks.notify(op,from,h->hvalue);
1638 /*answer that we received the notify*/
1640 eXosip_call_build_answer(ev->tid,200,&ans);
1642 eXosip_call_send_answer(ev->tid,200,ans);
1647 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1648 osip_message_t *ans=NULL;
1650 if (MSG_IS_INFO(ev->request)){
1651 osip_content_type_t *ct;
1652 ct=osip_message_get_content_type(ev->request);
1653 if (ct && ct->subtype){
1654 if (strcmp(ct->subtype,"media_control+xml")==0)
1655 process_media_control_xml(sal,ev);
1656 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1657 process_dtmf_relay(sal,ev);
1659 ms_message("Unhandled SIP INFO.");
1660 /*send an "Not implemented" answer*/
1662 eXosip_call_build_answer(ev->tid,501,&ans);
1664 eXosip_call_send_answer(ev->tid,501,ans);
1668 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1670 eXosip_call_build_answer(ev->tid,200,&ans);
1672 eXosip_call_send_answer(ev->tid,200,ans);
1675 }else if(MSG_IS_MESSAGE(ev->request)){
1676 /* SIP messages could be received into call */
1677 text_received(sal, ev);
1679 eXosip_call_build_answer(ev->tid,200,&ans);
1681 eXosip_call_send_answer(ev->tid,200,ans);
1683 }else if(MSG_IS_REFER(ev->request)){
1684 SalOp *op=find_op(sal,ev);
1686 ms_message("Receiving REFER request !");
1687 process_refer(sal,op,ev);
1688 }else if(MSG_IS_NOTIFY(ev->request)){
1689 process_notify(sal,ev);
1690 }else if (MSG_IS_OPTIONS(ev->request)){
1692 eXosip_call_build_answer(ev->tid,200,&ans);
1694 fill_options_answer(ans);
1695 eXosip_call_send_answer(ev->tid,200,ans);
1699 }else ms_warning("call_message_new: No request ?");
1702 static void inc_update(Sal *sal, eXosip_event_t *ev){
1703 osip_message_t *msg=NULL;
1704 ms_message("Processing incoming UPDATE");
1706 eXosip_message_build_answer(ev->tid,200,&msg);
1708 eXosip_message_send_answer(ev->tid,200,msg);
1712 static bool_t comes_from_local_if(osip_message_t *msg){
1713 osip_via_t *via=NULL;
1714 osip_message_get_via(msg,0,&via);
1717 host=osip_via_get_host(via);
1718 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1719 osip_generic_param_t *param=NULL;
1720 osip_via_param_get_byname(via,"received",¶m);
1721 if (param==NULL) return TRUE;
1722 if (param->gvalue &&
1723 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1731 static void text_received(Sal *sal, eXosip_event_t *ev){
1732 osip_body_t *body=NULL;
1733 char *from=NULL,*msg=NULL;
1734 osip_content_type_t* content_type;
1735 osip_uri_param_t* external_body_url;
1736 char unquoted_external_body_url [256];
1737 int external_body_size=0;
1739 char message_id[256]={0};
1741 content_type= osip_message_get_content_type(ev->request);
1742 if (!content_type) {
1743 ms_error("Could not get message because no content type");
1746 osip_from_to_str(ev->request->from,&from);
1747 if (content_type->type
1748 && strcmp(content_type->type, "text")==0
1749 && content_type->subtype
1750 && strcmp(content_type->subtype, "plain")==0 ) {
1751 osip_message_get_body(ev->request,0,&body);
1753 ms_error("Could not get text message from SIP body");
1758 }else if (content_type->type
1759 && strcmp(content_type->type, "message")==0
1760 && content_type->subtype
1761 && strcmp(content_type->subtype, "external-body")==0 ) {
1763 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1764 /*remove both first and last character*/
1765 strncpy(unquoted_external_body_url
1766 ,&external_body_url->gvalue[1]
1767 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1768 unquoted_external_body_url[external_body_size-1]='\0';
1770 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1774 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1778 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1779 salmsg.message_id=message_id;
1780 sal->callbacks.text_received(sal,&salmsg);
1786 static void other_request(Sal *sal, eXosip_event_t *ev){
1787 ms_message("in other_request");
1788 if (ev->request==NULL) return;
1789 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1790 text_received(sal,ev);
1791 eXosip_message_send_answer(ev->tid,200,NULL);
1792 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1793 osip_message_t *options=NULL;
1794 eXosip_options_build_answer(ev->tid,200,&options);
1795 fill_options_answer(options);
1796 eXosip_options_send_answer(ev->tid,200,options);
1797 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1798 ms_message("Receiving REFER request !");
1799 if (comes_from_local_if(ev->request)) {
1800 process_refer(sal,NULL,ev);
1801 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1802 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1807 osip_message_to_str(ev->request,&tmp,&msglen);
1809 ms_message("Unsupported request received:\n%s",tmp);
1812 /*answer with a 501 Not implemented*/
1813 eXosip_message_send_answer(ev->tid,501,NULL);
1817 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1818 osip_via_t *via=NULL;
1819 osip_message_get_via(msg,0,&via);
1821 osip_free(via->port);
1822 via->port=osip_strdup(port);
1823 osip_free(via->host);
1824 via->host=osip_strdup(ip);
1829 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1830 osip_contact_t *ctt=NULL;
1831 const char *received;
1833 SalTransport transport;
1836 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1837 osip_message_get_contact(request,0,&ctt);
1839 ms_warning("fix_message_contact(): no contact to update");
1842 if (expire_last_contact){
1843 osip_contact_t *oldct=NULL,*prevct;
1844 osip_generic_param_t *param=NULL;
1845 osip_contact_clone(ctt,&oldct);
1846 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1847 osip_contact_free(prevct);
1848 osip_list_remove(&request->contacts,1);
1850 osip_list_add(&request->contacts,oldct,1);
1851 osip_contact_param_get_byname(oldct,"expires",¶m);
1853 if (param->gvalue) osip_free(param->gvalue);
1854 param->gvalue=osip_strdup("0");
1856 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1859 if (ctt->url->host!=NULL){
1860 osip_free(ctt->url->host);
1862 ctt->url->host=osip_strdup(received);
1863 if (ctt->url->port!=NULL){
1864 osip_free(ctt->url->port);
1866 snprintf(port,sizeof(port),"%i",rport);
1867 ctt->url->port=osip_strdup(port);
1868 if (op->masquerade_via) masquerade_via(request,received,port);
1870 if (transport != SalTransportUDP) {
1871 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1876 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1877 osip_contact_t *ctt=NULL;
1878 SalAddress* ori_contact_address=NULL;
1879 const char *received;
1881 SalTransport transport;
1883 osip_message_t *msg=NULL;
1884 Sal* sal=op->base.root;
1886 bool_t found_valid_contact=FALSE;
1887 bool_t from_request=FALSE;
1889 if (sal->double_reg==FALSE ) return FALSE;
1891 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1894 osip_message_get_contact(last_answer,i,&ctt);
1895 if (!from_request && ctt==NULL) {
1896 osip_message_get_contact(orig_request,0,&ctt);
1900 osip_contact_to_str(ctt,&tmp);
1901 ori_contact_address = sal_address_new(tmp);
1903 /*check if contact is up to date*/
1904 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1905 && sal_address_get_port_int(ori_contact_address) == rport
1906 && sal_address_get_transport(ori_contact_address) == transport) {
1908 ms_message("Register response has up to date contact, doing nothing.");
1910 ms_warning("Register response does not have up to date contact, but last request had."
1911 "Stupid registrar detected, giving up.");
1913 found_valid_contact=TRUE;
1916 sal_address_destroy(ori_contact_address);
1919 }while(!found_valid_contact);
1920 if (!found_valid_contact)
1921 ms_message("Contact do not match, resending register.");
1925 eXosip_register_build_register(op->rid,op->expires,&msg);
1928 ms_warning("Fail to create a contact updated register.");
1931 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1932 eXosip_register_send_register(op->rid,msg);
1934 ms_message("Resending new register with updated contact");
1935 update_contact_from_response(op,last_answer);
1938 ms_warning("Fail to send updated register.");
1946 static void registration_success(Sal *sal, eXosip_event_t *ev){
1947 SalOp *op=sal_find_register(sal,ev->rid);
1948 osip_header_t *h=NULL;
1951 ms_error("Receiving register response for unknown operation");
1954 osip_message_get_expires(ev->request,0,&h);
1955 if (h!=NULL && atoi(h->hvalue)!=0){
1957 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1958 sal->callbacks.register_success(op,registered);
1961 sal->callbacks.register_success(op,FALSE);
1965 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1967 const char *reason=NULL;
1968 SalOp *op=sal_find_register(sal,ev->rid);
1969 SalReason sr=SalReasonUnknown;
1970 SalError se=SalErrorUnknown;
1973 ms_error("Receiving register failure for unknown operation");
1977 status_code=osip_message_get_status_code(ev->response);
1978 reason=osip_message_get_reason_phrase(ev->response);
1980 switch(status_code){
1983 return process_authentication(sal,ev);
1985 case 423: /*interval too brief*/
1986 {/*retry with greater interval */
1987 osip_header_t *h=NULL;
1988 osip_message_t *msg=NULL;
1989 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1990 if (h && h->hvalue && h->hvalue[0]!='\0'){
1991 int val=atoi(h->hvalue);
1992 if (val>op->expires)
1994 }else op->expires*=2;
1996 eXosip_register_build_register(op->rid,op->expires,&msg);
1997 eXosip_register_send_register(op->rid,msg);
2001 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2002 in vias, such as ekiga.net
2003 On the opposite, freephonie.net bugs when via are masqueraded.
2005 op->masquerade_via=TRUE;
2007 /* if contact is up to date, process the failure, otherwise resend a new register with
2008 updated contact first, just in case the faillure is due to incorrect contact */
2009 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2010 return TRUE; /*we are retrying with an updated contact*/
2011 if (status_code==403){
2013 sr=SalReasonForbidden;
2014 }else if (status_code==0){
2015 se=SalErrorNoResponse;
2017 sal->callbacks.register_failure(op,se,sr,reason);
2022 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2023 SalOp *op=find_op(sal,ev);
2025 ms_warning("other_request_reply(): Receiving response to unknown request.");
2029 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2030 update_contact_from_response(op,ev->response);
2031 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2032 sal->callbacks.ping_reply(op);
2034 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2035 /*out of call message acknolegment*/
2036 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2038 if (ev->response->status_code<200){
2039 status=SalTextDeliveryInProgress;
2040 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2041 status=SalTextDeliveryDone;
2044 sal->callbacks.text_delivery_update(op,status);
2048 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2049 SalOp *op=find_op(sal,ev);
2051 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2052 if (op->sipfrag_pending){
2053 send_notify_for_refer(op->did,op->sipfrag_pending);
2054 op->sipfrag_pending=NULL;
2060 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2061 ms_message("linphone process event get a message %d\n",ev->type);
2063 case EXOSIP_CALL_ANSWERED:
2064 ms_message("CALL_ANSWERED\n");
2065 call_accepted(sal,ev);
2066 authentication_ok(sal,ev);
2068 case EXOSIP_CALL_CLOSED:
2069 case EXOSIP_CALL_CANCELLED:
2070 ms_message("CALL_CLOSED or CANCELLED\n");
2071 call_terminated(sal,ev);
2073 case EXOSIP_CALL_TIMEOUT:
2074 case EXOSIP_CALL_NOANSWER:
2075 ms_message("CALL_TIMEOUT or NOANSWER\n");
2076 return call_failure(sal,ev);
2078 case EXOSIP_CALL_REQUESTFAILURE:
2079 case EXOSIP_CALL_GLOBALFAILURE:
2080 case EXOSIP_CALL_SERVERFAILURE:
2081 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2082 return call_failure(sal,ev);
2084 case EXOSIP_CALL_RELEASED:
2085 ms_message("CALL_RELEASED\n");
2086 call_released(sal, ev);
2088 case EXOSIP_CALL_INVITE:
2089 ms_message("CALL_NEW\n");
2090 inc_new_call(sal,ev);
2092 case EXOSIP_CALL_REINVITE:
2093 handle_reinvite(sal,ev);
2095 case EXOSIP_CALL_ACK:
2096 ms_message("CALL_ACK");
2099 case EXOSIP_CALL_REDIRECTED:
2100 ms_message("CALL_REDIRECTED");
2101 eXosip_default_action(ev);
2103 case EXOSIP_CALL_PROCEEDING:
2104 ms_message("CALL_PROCEEDING");
2105 call_proceeding(sal,ev);
2107 case EXOSIP_CALL_RINGING:
2108 ms_message("CALL_RINGING");
2109 call_ringing(sal,ev);
2110 authentication_ok(sal,ev);
2112 case EXOSIP_CALL_MESSAGE_NEW:
2113 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2114 call_message_new(sal,ev);
2116 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2118 (ev->response->status_code==407 || ev->response->status_code==401)){
2119 return process_authentication(sal,ev);
2122 case EXOSIP_CALL_MESSAGE_ANSWERED:
2123 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2124 process_in_call_reply(sal,ev);
2126 case EXOSIP_IN_SUBSCRIPTION_NEW:
2127 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2128 sal_exosip_subscription_recv(sal,ev);
2130 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2131 ms_message("CALL_SUBSCRIPTION_NEW ");
2132 sal_exosip_in_subscription_closed(sal,ev);
2134 case EXOSIP_SUBSCRIPTION_UPDATE:
2135 ms_message("CALL_SUBSCRIPTION_UPDATE");
2137 case EXOSIP_SUBSCRIPTION_NOTIFY:
2138 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2139 sal_exosip_notify_recv(sal,ev);
2141 case EXOSIP_SUBSCRIPTION_ANSWERED:
2142 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2143 sal_exosip_subscription_answered(sal,ev);
2145 case EXOSIP_SUBSCRIPTION_CLOSED:
2146 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2147 sal_exosip_subscription_closed(sal,ev);
2149 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2150 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2151 return process_authentication(sal,ev);
2153 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2154 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2155 sal_exosip_subscription_closed(sal,ev);
2157 case EXOSIP_REGISTRATION_FAILURE:
2158 ms_message("REGISTRATION_FAILURE\n");
2159 return registration_failure(sal,ev);
2161 case EXOSIP_REGISTRATION_SUCCESS:
2162 authentication_ok(sal,ev);
2163 registration_success(sal,ev);
2165 case EXOSIP_MESSAGE_NEW:
2166 other_request(sal,ev);
2168 case EXOSIP_MESSAGE_PROCEEDING:
2169 case EXOSIP_MESSAGE_ANSWERED:
2170 case EXOSIP_MESSAGE_REDIRECTED:
2171 case EXOSIP_MESSAGE_SERVERFAILURE:
2172 case EXOSIP_MESSAGE_GLOBALFAILURE:
2173 other_request_reply(sal,ev);
2175 case EXOSIP_MESSAGE_REQUESTFAILURE:
2176 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2178 switch (ev->response->status_code) {
2181 return process_authentication(sal,ev);
2183 eXosip_automatic_action ();
2188 other_request_reply(sal,ev);
2191 ms_message("Unhandled exosip event ! %i",ev->type);
2197 int sal_iterate(Sal *sal){
2199 while((ev=eXosip_event_wait(0,0))!=NULL){
2200 if (process_event(sal,ev))
2201 eXosip_event_free(ev);
2203 #ifdef HAVE_EXOSIP_TRYLOCK
2204 if (eXosip_trylock()==0){
2205 eXosip_automatic_refresh();
2208 ms_warning("eXosip_trylock busy.");
2212 eXosip_automatic_refresh();
2218 static void register_set_contact(osip_message_t *msg, const char *contact){
2219 osip_uri_param_t *param = NULL;
2220 osip_contact_t *ct=NULL;
2222 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2223 osip_message_get_contact(msg,0,&ct);
2225 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2226 if (param && param->gvalue)
2227 line=osip_strdup(param->gvalue);
2229 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2230 osip_message_set_contact(msg,contact);
2231 osip_message_get_contact(msg,0,&ct);
2232 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2235 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2236 osip_route_t *route;
2238 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2240 osip_route_init(&route);
2241 if (osip_route_parse(route,proxy)==0){
2242 osip_uri_param_t *lr_param = NULL;
2243 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2244 if (lr_param == NULL){
2245 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2247 osip_list_add(&msg->routes,route,0);
2250 osip_route_free(route);
2254 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2255 osip_message_t *msg;
2256 const char *contact=sal_op_get_contact(h);
2258 sal_op_set_route(h,proxy);
2260 SalAddress *from_parsed=sal_address_new(from);
2262 char *uri, *domain_ptr = NULL;
2263 if (from_parsed==NULL) {
2264 ms_warning("sal_register() bad from %s",from);
2267 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2268 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2269 uri = sal_address_as_string_uri_only(from_parsed);
2270 if (uri) domain_ptr = strchr(uri, '@');
2272 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2274 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2276 if (uri) ms_free(uri);
2277 sal_address_destroy(from_parsed);
2279 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2281 if (contact) register_set_contact(msg,contact);
2282 sal_register_add_route(msg,proxy);
2283 sal_add_register(h->base.root,h);
2285 ms_error("Could not build initial register.");
2291 eXosip_register_build_register(h->rid,expires,&msg);
2292 sal_register_add_route(msg,proxy);
2295 eXosip_register_send_register(h->rid,msg);
2299 return (msg != NULL) ? 0 : -1;
2302 int sal_register_refresh(SalOp *op, int expires){
2303 osip_message_t *msg=NULL;
2304 const char *contact=sal_op_get_contact(op);
2307 ms_error("Unexistant registration context, not possible to refresh.");
2310 #ifdef HAVE_EXOSIP_TRYLOCK
2313 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2314 * 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
2315 * the exosip lock in a non blocking way, and give up if it takes too long*/
2316 while (eXosip_trylock()!=0){
2318 if (tries>30) {/*after 3 seconds, give up*/
2319 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2327 eXosip_register_build_register(op->rid,expires,&msg);
2329 if (contact) register_set_contact(msg,contact);
2330 sal_register_add_route(msg,sal_op_get_route(op));
2331 eXosip_register_send_register(op->rid,msg);
2332 }else ms_error("Could not build REGISTER refresh message.");
2334 return (msg != NULL) ? 0 : -1;
2338 int sal_unregister(SalOp *h){
2339 osip_message_t *msg=NULL;
2341 eXosip_register_build_register(h->rid,0,&msg);
2342 if (msg) eXosip_register_send_register(h->rid,msg);
2343 else ms_warning("Could not build unREGISTER !");
2348 SalAddress * sal_address_new(const char *uri){
2350 osip_from_init(&from);
2352 // Remove front spaces
2353 while (uri[0]==' ') {
2357 if (osip_from_parse(from,uri)!=0){
2358 osip_from_free(from);
2361 if (from->displayname!=NULL && from->displayname[0]=='"'){
2362 char *unquoted=osip_strdup_without_quote(from->displayname);
2363 osip_free(from->displayname);
2364 from->displayname=unquoted;
2366 return (SalAddress*)from;
2369 SalAddress * sal_address_clone(const SalAddress *addr){
2370 osip_from_t *ret=NULL;
2371 osip_from_clone((osip_from_t*)addr,&ret);
2372 return (SalAddress*)ret;
2375 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2377 const char *sal_address_get_scheme(const SalAddress *addr){
2378 const osip_from_t *u=(const osip_from_t*)addr;
2379 return null_if_empty(u->url->scheme);
2382 const char *sal_address_get_display_name(const SalAddress* addr){
2383 const osip_from_t *u=(const osip_from_t*)addr;
2384 return null_if_empty(u->displayname);
2387 const char *sal_address_get_username(const SalAddress *addr){
2388 const osip_from_t *u=(const osip_from_t*)addr;
2389 return null_if_empty(u->url->username);
2392 const char *sal_address_get_domain(const SalAddress *addr){
2393 const osip_from_t *u=(const osip_from_t*)addr;
2394 return null_if_empty(u->url->host);
2397 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2398 osip_from_t *u=(osip_from_t*)addr;
2399 if (u->displayname!=NULL){
2400 osip_free(u->displayname);
2401 u->displayname=NULL;
2403 if (display_name!=NULL && display_name[0]!='\0'){
2404 u->displayname=osip_strdup(display_name);
2408 void sal_address_set_username(SalAddress *addr, const char *username){
2409 osip_from_t *uri=(osip_from_t*)addr;
2410 if (uri->url->username!=NULL){
2411 osip_free(uri->url->username);
2412 uri->url->username=NULL;
2415 uri->url->username=osip_strdup(username);
2418 void sal_address_set_domain(SalAddress *addr, const char *host){
2419 osip_from_t *uri=(osip_from_t*)addr;
2420 if (uri->url->host!=NULL){
2421 osip_free(uri->url->host);
2422 uri->url->host=NULL;
2425 uri->url->host=osip_strdup(host);
2428 void sal_address_set_port(SalAddress *addr, const char *port){
2429 osip_from_t *uri=(osip_from_t*)addr;
2430 if (uri->url->port!=NULL){
2431 osip_free(uri->url->port);
2432 uri->url->port=NULL;
2435 uri->url->port=osip_strdup(port);
2438 void sal_address_set_port_int(SalAddress *uri, int port){
2441 /*this is the default, special case to leave the port field blank*/
2442 sal_address_set_port(uri,NULL);
2445 snprintf(tmp,sizeof(tmp),"%i",port);
2446 sal_address_set_port(uri,tmp);
2449 void sal_address_clean(SalAddress *addr){
2450 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2451 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2454 char *sal_address_as_string(const SalAddress *u){
2456 osip_from_t *from=(osip_from_t *)u;
2457 char *old_displayname=NULL;
2458 /* hack to force use of quotes around the displayname*/
2459 if (from->displayname!=NULL
2460 && from->displayname[0]!='"'){
2461 old_displayname=from->displayname;
2462 from->displayname=osip_enquote(from->displayname);
2464 osip_from_to_str(from,&tmp);
2465 if (old_displayname!=NULL){
2466 ms_free(from->displayname);
2467 from->displayname=old_displayname;
2474 char *sal_address_as_string_uri_only(const SalAddress *u){
2475 char *tmp=NULL,*ret;
2476 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2481 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2482 osip_uri_param_t *param=NULL;
2483 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2485 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2487 osip_free(param->gvalue);
2488 param->gvalue=value ? osip_strdup(value) : NULL;
2493 void sal_address_destroy(SalAddress *u){
2494 osip_from_free((osip_from_t*)u);
2497 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2498 ctx->keepalive_period=value;
2499 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2501 unsigned int sal_get_keepalive_period(Sal *ctx) {
2502 return ctx->keepalive_period;
2505 const char * sal_address_get_port(const SalAddress *addr) {
2506 const osip_from_t *u=(const osip_from_t*)addr;
2507 return null_if_empty(u->url->port);
2510 int sal_address_get_port_int(const SalAddress *uri) {
2511 const char* port = sal_address_get_port(uri);
2518 SalTransport sal_address_get_transport(const SalAddress* addr) {
2519 const osip_from_t *u=(const osip_from_t*)addr;
2520 osip_uri_param_t *transport_param=NULL;
2521 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2522 if (transport_param == NULL){
2523 return SalTransportUDP;
2525 return sal_transport_parse(transport_param->gvalue);
2528 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2529 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2532 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2533 int sal_call_update(SalOp *h, const char *subject){
2535 osip_message_t *reinvite=NULL;
2538 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2543 osip_message_set_subject(reinvite,subject);
2544 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2545 if (h->base.contact){
2546 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2547 osip_message_set_contact(reinvite,h->base.contact);
2549 if (h->base.root->session_expires!=0){
2550 osip_message_set_header(reinvite, "Session-expires", "200");
2551 osip_message_set_supported(reinvite, "timer");
2553 if (h->base.local_media){
2554 h->sdp_offering=TRUE;
2555 set_sdp_from_desc(reinvite,h->base.local_media);
2556 }else h->sdp_offering=FALSE;
2558 err = eXosip_call_send_request(h->did, reinvite);
2562 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2563 ctx->reuse_authorization=value;