3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "sal_eXosip2.h"
24 #include "offeranswer.h"
27 // Necessary to make it linked
28 static void for_linker() { eXosip_transport_hook_register(NULL); }
30 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
32 static void text_received(Sal *sal, eXosip_event_t *ev);
34 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
35 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact);
36 static void update_contact_from_response(SalOp *op, osip_message_t *response);
38 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
40 while(!osip_list_eol(l,0)) {
41 data=osip_list_get(l,0);
42 osip_list_remove(l,0);
43 if (data) freefunc(data);
47 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
48 if (eXosip_guess_localip(address_family,ip,iplen)<0){
49 /*default to something */
50 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
51 ms_error("Could not find default routable ip address !");
56 static SalOp * sal_find_call(Sal *sal, int cid){
59 for(elem=sal->calls;elem!=NULL;elem=elem->next){
60 op=(SalOp*)elem->data;
61 if (op->cid==cid) return op;
66 static void sal_add_call(Sal *sal, SalOp *op){
67 sal->calls=ms_list_append(sal->calls,op);
70 static void sal_remove_call(Sal *sal, SalOp *op){
71 sal->calls=ms_list_remove(sal->calls, op);
74 static SalOp * sal_find_register(Sal *sal, int rid){
77 for(elem=sal->registers;elem!=NULL;elem=elem->next){
78 op=(SalOp*)elem->data;
79 if (op->rid==rid) return op;
84 static void sal_add_register(Sal *sal, SalOp *op){
85 sal->registers=ms_list_append(sal->registers,op);
88 static void sal_remove_register(Sal *sal, int rid){
91 for(elem=sal->registers;elem!=NULL;elem=elem->next){
92 op=(SalOp*)elem->data;
94 sal->registers=ms_list_remove_link(sal->registers,elem);
100 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
103 osip_call_id_t *callid=osip_message_get_call_id(message);
105 ms_error("There is no call-id in this message !");
108 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
109 op=(SalOp*)elem->data;
110 if (osip_call_id_match(callid,op->call_id)==0) return op;
115 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
116 osip_call_id_t *callid=osip_message_get_call_id(request);
118 ms_error("There is no call id in the request !");
121 osip_call_id_clone(callid,&op->call_id);
122 sal->other_transactions=ms_list_append(sal->other_transactions,op);
125 static void sal_remove_other(Sal *sal, SalOp *op){
126 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
130 static void sal_add_pending_auth(Sal *sal, SalOp *op){
131 sal->pending_auths=ms_list_append(sal->pending_auths,op);
135 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
136 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
139 void sal_exosip_fix_route(SalOp *op){
140 if (sal_op_get_route(op)!=NULL){
141 osip_route_t *rt=NULL;
142 osip_uri_param_t *lr_param=NULL;
144 osip_route_init(&rt);
145 if (osip_route_parse(rt,sal_op_get_route(op))<0){
146 ms_warning("Bad route %s!",sal_op_get_route(op));
147 sal_op_set_route(op,NULL);
149 /* check if the lr parameter is set , if not add it */
150 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
153 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
154 osip_route_to_str(rt,&tmproute);
155 sal_op_set_route(op,tmproute);
163 SalOp * sal_op_new(Sal *sal){
164 SalOp *op=ms_new0(SalOp,1);
165 __sal_op_init(op,sal);
166 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
168 op->supports_session_timers=FALSE;
169 op->sdp_offering=TRUE;
170 op->pending_auth=NULL;
175 op->referred_by=NULL;
176 op->masquerade_via=FALSE;
177 op->auto_answer_asked=FALSE;
179 op->terminated=FALSE;
183 bool_t sal_call_autoanswer_asked(SalOp *op)
185 return op->auto_answer_asked;
188 void sal_op_release(SalOp *op){
190 sdp_message_free(op->sdp_answer);
191 if (op->pending_auth)
192 eXosip_event_free(op->pending_auth);
194 sal_remove_register(op->base.root,op->rid);
195 eXosip_register_remove(op->rid);
198 ms_message("Cleaning cid %i",op->cid);
199 sal_remove_call(op->base.root,op);
202 sal_remove_out_subscribe(op->base.root,op);
205 sal_remove_in_subscribe(op->base.root,op);
207 osip_call_id_free(op->call_id);
210 if (op->pending_auth){
211 sal_remove_pending_auth(op->base.root,op);
214 sal_media_description_unref(op->result);
216 sal_remove_other(op->base.root,op);
217 osip_call_id_free(op->call_id);
220 ms_free(op->replaces);
222 if (op->referred_by){
223 ms_free(op->referred_by);
226 sal_auth_info_delete(op->auth_info);
231 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
232 int ortp_level=ORTP_DEBUG;
238 ortp_level=ORTP_MESSAGE;
241 ortp_level=ORTP_WARNING;
245 ortp_level=ORTP_ERROR;
248 ortp_level=ORTP_FATAL;
250 case END_TRACE_LEVEL:
253 if (ortp_log_level_enabled(level)){
254 int len=strlen(chfr);
255 char *chfrdup=ortp_strdup(chfr);
256 /*need to remove endline*/
258 if (chfrdup[len-1]=='\n')
260 if (chfrdup[len-2]=='\r')
263 ortp_logv(ortp_level,chfrdup,ap);
270 static bool_t firsttime=TRUE;
273 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
278 sal->keepalive_period=30;
279 sal->double_reg=TRUE;
280 sal->use_rports=TRUE;
282 sal->reuse_authorization=FALSE;
284 sal->verify_server_certs=TRUE;
285 sal->verify_server_cn=TRUE;
286 sal->expire_old_contact=FALSE;
287 sal->add_dates=FALSE;
292 void sal_uninit(Sal* sal){
295 ms_free(sal->rootCa);
299 void sal_set_user_pointer(Sal *sal, void *user_data){
303 void *sal_get_user_pointer(const Sal *sal){
307 static void unimplemented_stub(){
308 ms_warning("Unimplemented SAL callback");
311 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
312 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
313 if (ctx->callbacks.call_received==NULL)
314 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
315 if (ctx->callbacks.call_ringing==NULL)
316 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
317 if (ctx->callbacks.call_accepted==NULL)
318 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
319 if (ctx->callbacks.call_failure==NULL)
320 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
321 if (ctx->callbacks.call_terminated==NULL)
322 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
323 if (ctx->callbacks.call_released==NULL)
324 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
325 if (ctx->callbacks.call_updating==NULL)
326 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
327 if (ctx->callbacks.auth_requested==NULL)
328 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
329 if (ctx->callbacks.auth_success==NULL)
330 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
331 if (ctx->callbacks.register_success==NULL)
332 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
333 if (ctx->callbacks.register_failure==NULL)
334 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
335 if (ctx->callbacks.dtmf_received==NULL)
336 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
337 if (ctx->callbacks.notify==NULL)
338 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
339 if (ctx->callbacks.notify_presence==NULL)
340 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
341 if (ctx->callbacks.subscribe_received==NULL)
342 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
343 if (ctx->callbacks.text_received==NULL)
344 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
345 if (ctx->callbacks.ping_reply==NULL)
346 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
349 int sal_unlisten_ports(Sal *ctx){
358 int sal_reset_transports(Sal *ctx){
359 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
361 ms_message("Exosip transports reset.");
362 eXosip_reset_transports();
366 ms_warning("sal_reset_transports() not implemented in this version.");
372 static void set_tls_options(Sal *ctx){
374 eXosip_tls_ctx_t tlsCtx;
375 memset(&tlsCtx, 0, sizeof(tlsCtx));
376 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
377 eXosip_set_tls_ctx(&tlsCtx);
379 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
380 eXosip_tls_verify_certificate(ctx->verify_server_certs);
382 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
383 eXosip_tls_verify_cn(ctx->verify_server_cn);
387 void sal_set_dscp(Sal *ctx, int dscp){
389 #ifdef HAVE_EXOSIP_DSCP
391 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
395 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
398 int proto=IPPROTO_UDP;
399 int keepalive = ctx->keepalive_period;
402 case SalTransportUDP:
404 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
406 case SalTransportTCP:
407 case SalTransportTLS:
410 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
411 set_tls_options(ctx);
414 ms_warning("unexpected proto, using datagram");
416 /*see if it looks like an IPv6 address*/
417 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
418 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
419 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
420 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
421 sal_set_dscp(ctx,ctx->dscp);
422 sal_use_dates(ctx,ctx->add_dates);
424 ipv6=strchr(addr,':')!=NULL;
425 eXosip_enable_ipv6(ipv6);
427 if (is_secure && tr == SalTransportUDP){
428 ms_fatal("SIP over DTLS is not supported yet.");
431 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
436 ortp_socket_t sal_get_socket(Sal *ctx){
437 #ifdef HAVE_EXOSIP_GET_SOCKET
438 return eXosip_get_socket(IPPROTO_UDP);
440 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
445 void sal_set_user_agent(Sal *ctx, const char *user_agent){
446 eXosip_set_user_agent(user_agent);
449 void sal_use_session_timers(Sal *ctx, int expires){
450 ctx->session_expires=expires;
453 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
454 ctx->one_matching_codec=one_matching_codec;
457 MSList *sal_get_pending_auths(Sal *sal){
458 return ms_list_copy(sal->pending_auths);
461 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
462 ctx->double_reg=enabled;
465 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
466 ctx->expire_old_contact=enabled;
469 void sal_use_dates(Sal *ctx, bool_t enabled){
470 ctx->add_dates=enabled;
471 #ifdef EXOSIP_OPT_REGISTER_WITH_DATE
474 eXosip_set_option(EXOSIP_OPT_REGISTER_WITH_DATE,&tmp);
477 if (enabled) ms_warning("Exosip does not support EXOSIP_OPT_REGISTER_WITH_DATE option.");
481 void sal_use_rport(Sal *ctx, bool_t use_rports){
482 ctx->use_rports=use_rports;
484 void sal_use_101(Sal *ctx, bool_t use_101){
485 ctx->use_101=use_101;
488 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
490 ms_free(ctx->rootCa);
491 ctx->rootCa = ms_strdup(rootCa);
492 set_tls_options(ctx);
495 const char *sal_get_root_ca(Sal* ctx) {
499 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
500 ctx->verify_server_certs=verify;
501 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
502 eXosip_tls_verify_certificate(verify);
506 void sal_verify_server_cn(Sal *ctx, bool_t verify){
507 ctx->verify_server_cn=verify;
508 #ifdef HAVE_EXOSIP_TLS_VERIFY_CN
509 eXosip_tls_verify_cn(verify);
513 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
514 osip_via_t *via=NULL;
515 osip_generic_param_t *param=NULL;
516 const char *rport=NULL;
520 osip_message_get_via(msg,0,&via);
522 ms_warning("extract_received_rport(): no via.");
526 *transport = sal_transport_parse(via->protocol);
528 if (via->port && via->port[0]!='\0')
529 *rportval=atoi(via->port);
531 osip_via_param_get_byname(via,"rport",¶m);
534 if (rport && rport[0]!='\0') *rportval=atoi(rport);
538 osip_via_param_get_byname(via,"received",¶m);
539 if (param) *received=param->gvalue;
541 if (rport==NULL && *received==NULL){
542 ms_warning("extract_received_rport(): no rport and no received parameters.");
548 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
552 sdp_message_to_str(msg,&sdp);
554 snprintf(clen,sizeof(clen),"%i",sdplen);
555 osip_message_set_body(sip,sdp,sdplen);
556 osip_message_set_content_type(sip,"application/sdp");
557 osip_message_set_content_length(sip,clen);
561 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
562 sdp_message_t *msg=media_description_to_sdp(desc);
564 ms_error("Fail to print sdp message !");
568 sdp_message_free(msg);
571 static void sdp_process(SalOp *h){
572 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
574 sal_media_description_unref(h->result);
576 h->result=sal_media_description_new();
577 if (h->sdp_offering){
578 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
582 sdp_message_free(h->sdp_answer);
584 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
585 h->sdp_answer=media_description_to_sdp(h->result);
586 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
587 It should contains media parameters constraint from the remote offer, not our response*/
588 strcpy(h->result->addr,h->base.remote_media->addr);
589 h->result->bandwidth=h->base.remote_media->bandwidth;
591 for(i=0;i<h->result->nstreams;++i){
592 if (h->result->streams[i].rtp_port>0){
593 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
594 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
595 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
596 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
597 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
598 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
600 if (h->result->streams[i].proto == SalProtoRtpSavp) {
601 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
609 int sal_call_is_offerer(const SalOp *h){
610 return h->sdp_offering;
613 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
615 sal_media_description_ref(desc);
616 if (h->base.local_media)
617 sal_media_description_unref(h->base.local_media);
618 h->base.local_media=desc;
619 if (h->base.remote_media){
620 /*case of an incoming call where we modify the local capabilities between the time
621 * the call is ringing and it is accepted (for example if you want to accept without video*/
622 /*reset the sdp answer so that it is computed again*/
624 sdp_message_free(h->sdp_answer);
631 int sal_call(SalOp *h, const char *from, const char *to){
634 osip_message_t *invite=NULL;
635 osip_call_id_t *callid;
636 sal_op_set_from(h,from);
638 sal_exosip_fix_route(h);
640 h->terminated = FALSE;
642 route = sal_op_get_route(h);
643 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
645 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
646 err, from, to, route);
649 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
650 if (h->base.contact){
651 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
652 osip_message_set_contact(invite,h->base.contact);
654 if (h->base.root->session_expires!=0){
655 osip_message_set_header(invite, "Session-expires", "200");
656 osip_message_set_supported(invite, "timer");
658 if (h->base.local_media){
659 h->sdp_offering=TRUE;
660 set_sdp_from_desc(invite,h->base.local_media);
661 }else h->sdp_offering=FALSE;
663 osip_message_set_header(invite,"Replaces",h->replaces);
665 osip_message_set_header(invite,"Referred-By",h->referred_by);
669 err=eXosip_call_send_initial_invite(invite);
673 ms_error("Fail to send invite ! Error code %d", err);
676 callid=osip_message_get_call_id(invite);
677 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
678 sal_add_call(h->base.root,h);
683 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
686 /*if early media send also 180 and 183 */
690 eXosip_call_build_answer(h->tid,183,&msg);
694 set_sdp(msg,h->sdp_answer);
695 sdp_message_free(h->sdp_answer);
698 eXosip_call_send_answer(h->tid,183,msg);
703 eXosip_call_send_answer(h->tid,180,NULL);
709 int sal_call_accept(SalOp * h){
711 const char *contact=sal_op_get_contact(h);
713 int err=eXosip_call_build_answer(h->tid,200,&msg);
714 if (err<0 || msg==NULL){
715 ms_error("Fail to build answer for call: err=%i",err);
718 if (h->base.root->session_expires!=0){
719 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
723 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
724 osip_message_set_contact(msg,contact);
727 if (h->base.local_media){
728 /*this is the case where we received an invite without SDP*/
729 if (h->sdp_offering) {
730 set_sdp_from_desc(msg,h->base.local_media);
732 if (h->sdp_answer==NULL) sdp_process(h);
734 set_sdp(msg,h->sdp_answer);
735 sdp_message_free(h->sdp_answer);
740 ms_error("You are accepting a call but not defined any media capabilities !");
742 eXosip_call_send_answer(h->tid,200,msg);
746 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
747 if (reason==SalReasonBusy){
749 eXosip_call_send_answer(h->tid,486,NULL);
752 else if (reason==SalReasonTemporarilyUnavailable){
754 eXosip_call_send_answer(h->tid,480,NULL);
756 }else if (reason==SalReasonDoNotDisturb){
758 eXosip_call_send_answer(h->tid,600,NULL);
760 }else if (reason==SalReasonMedia){
762 eXosip_call_send_answer(h->tid,415,NULL);
764 }else if (redirect!=NULL && reason==SalReasonRedirect){
767 if (strstr(redirect,"sip:")!=0) code=302;
770 eXosip_call_build_answer(h->tid,code,&msg);
771 osip_message_set_contact(msg,redirect);
772 eXosip_call_send_answer(h->tid,code,msg);
774 }else sal_call_terminate(h);
778 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
779 return h->base.remote_media;
782 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
783 if (h->base.local_media && h->base.remote_media && !h->result){
789 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
790 if (refered_call->replaces)
791 h->replaces=ms_strdup(refered_call->replaces);
792 if (refered_call->referred_by)
793 h->referred_by=ms_strdup(refered_call->referred_by);
797 static int send_notify_for_refer(int did, const char *sipfrag){
800 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
803 ms_warning("Could not build NOTIFY for refer.");
806 osip_message_set_content_type(msg,"message/sipfrag");
807 osip_message_set_header(msg,"Event","refer");
808 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
809 eXosip_call_send_request(did,msg);
814 /* currently only support to notify trying and 200Ok*/
815 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
818 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
820 else if (newcall->cid!=-1){
821 if (newcall->did==-1){
822 /* not yet established*/
823 if (!newcall->terminated){
825 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
828 if (!newcall->terminated){
829 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
830 /* we need previous notify transaction to complete, so buffer the request for later*/
831 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
839 int sal_ping(SalOp *op, const char *from, const char *to){
840 osip_message_t *options=NULL;
842 sal_op_set_from(op,from);
843 sal_op_set_to(op,to);
844 sal_exosip_fix_route(op);
846 eXosip_options_build_request (&options, sal_op_get_to(op),
847 sal_op_get_from(op),sal_op_get_route(op));
849 if (op->base.root->session_expires!=0){
850 osip_message_set_header(options, "Session-expires", "200");
851 osip_message_set_supported(options, "timer");
853 sal_add_other(sal_op_get_sal(op),op,options);
854 return eXosip_options_send_request(options);
859 int sal_call_refer(SalOp *h, const char *refer_to){
860 osip_message_t *msg=NULL;
863 eXosip_call_build_refer(h->did,refer_to, &msg);
864 if (msg) err=eXosip_call_send_request(h->did, msg);
870 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
871 osip_message_t *msg=NULL;
872 char referto[256]={0};
875 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
876 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
880 eXosip_call_build_refer(h->did,referto, &msg);
881 osip_message_set_header(msg,"Referred-By",h->base.from);
882 if (msg) err=eXosip_call_send_request(h->did, msg);
888 SalOp *sal_call_get_replaces(SalOp *h){
889 if (h!=NULL && h->replaces!=NULL){
892 cid=eXosip_call_find_by_replaces(h->replaces);
895 SalOp *ret=sal_find_call(h->base.root,cid);
902 int sal_call_send_dtmf(SalOp *h, char dtmf){
903 osip_message_t *msg=NULL;
908 eXosip_call_build_info(h->did,&msg);
910 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
911 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
912 osip_message_set_content_type(msg,"application/dtmf-relay");
913 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
914 osip_message_set_content_length(msg,clen);
915 eXosip_call_send_request(h->did,msg);
921 static void push_auth_to_exosip(const SalAuthInfo *info){
923 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
924 else userid=info->userid;
925 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
926 eXosip_add_authentication_info (info->username,userid,
927 info->password, NULL,info->realm);
930 * Just for symmetry ;-)
932 static void pop_auth_from_exosip() {
933 eXosip_clear_authentication_info();
936 int sal_call_terminate(SalOp *h){
938 if (h == NULL) return -1;
939 if (h->auth_info) push_auth_to_exosip(h->auth_info);
941 err=eXosip_call_terminate(h->cid,h->did);
943 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
945 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
951 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
952 bool_t terminating=FALSE;
953 if (h->pending_auth && strcmp(h->pending_auth->request->sip_method,"BYE")==0) {
956 if (h->terminated && !terminating) return;
958 if (h->pending_auth){
959 push_auth_to_exosip(info);
961 /*FIXME exosip does not take into account this update register message*/
963 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
967 update_contact_from_response(h,h->pending_auth->response);
969 eXosip_default_action(h->pending_auth);
971 ms_message("eXosip_default_action() done");
972 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
974 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
975 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
978 void sal_op_cancel_authentication(SalOp *h) {
980 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
981 } else if (h->cid >0) {
982 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
984 ms_warning("Auth failure not handled");
988 static void set_network_origin(SalOp *op, osip_message_t *req){
989 const char *received=NULL;
992 SalTransport transport;
993 if (extract_received_rport(req,&received,&rport,&transport)!=0){
994 osip_via_t *via=NULL;
996 osip_message_get_via(req,0,&via);
997 received=osip_via_get_host(via);
998 tmp=osip_via_get_port(via);
999 if (tmp) rport=atoi(tmp);
1001 if (transport != SalTransportUDP) {
1002 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
1004 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
1006 __sal_op_set_network_origin(op,origin);
1009 static void set_remote_ua(SalOp* op, osip_message_t *req){
1010 if (op->base.remote_ua==NULL){
1011 osip_header_t *h=NULL;
1012 osip_message_get_user_agent(req,0,&h);
1014 op->base.remote_ua=ms_strdup(h->hvalue);
1019 static void set_replaces(SalOp *op, osip_message_t *req){
1020 osip_header_t *h=NULL;
1023 ms_free(op->replaces);
1026 osip_message_header_get_byname(req,"replaces",0,&h);
1028 if (h->hvalue && h->hvalue[0]!='\0'){
1029 op->replaces=ms_strdup(h->hvalue);
1034 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1036 return sal_find_call(sal,ev->cid);
1039 return sal_find_register(sal,ev->rid);
1042 return sal_find_out_subscribe(sal,ev->sid);
1045 return sal_find_in_subscribe(sal,ev->nid);
1047 if (ev->response) return sal_find_other(sal,ev->response);
1048 else if (ev->request) return sal_find_other(sal,ev->request);
1052 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1053 SalOp *op=sal_op_new(sal);
1054 osip_from_t *from,*to;
1055 osip_call_info_t *call_info;
1057 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1058 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1059 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1061 set_network_origin(op,ev->request);
1062 set_remote_ua(op,ev->request);
1063 set_replaces(op,ev->request);
1066 op->sdp_offering=FALSE;
1067 op->base.remote_media=sal_media_description_new();
1068 sdp_to_media_description(sdp,op->base.remote_media);
1069 sdp_message_free(sdp);
1070 }else op->sdp_offering=TRUE;
1072 from=osip_message_get_from(ev->request);
1073 to=osip_message_get_to(ev->request);
1074 osip_from_to_str(from,&tmp);
1075 sal_op_set_from(op,tmp);
1077 osip_from_to_str(to,&tmp);
1078 sal_op_set_to(op,tmp);
1081 osip_message_get_call_info(ev->request,0,&call_info);
1084 osip_call_info_to_str(call_info,&tmp);
1085 if( strstr(tmp,"answer-after=") != NULL)
1087 op->auto_answer_asked=TRUE;
1088 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1096 sal_add_call(op->base.root,op);
1097 sal->callbacks.call_received(op);
1100 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1101 SalOp *op=find_op(sal,ev);
1105 ms_warning("Reinvite for non-existing operation !");
1110 sdp=eXosip_get_sdp_info(ev->request);
1111 if (op->base.remote_media){
1112 sal_media_description_unref(op->base.remote_media);
1113 op->base.remote_media=NULL;
1116 sal_media_description_unref(op->result);
1120 op->sdp_offering=FALSE;
1121 op->base.remote_media=sal_media_description_new();
1122 sdp_to_media_description(sdp,op->base.remote_media);
1123 sdp_message_free(sdp);
1126 op->sdp_offering=TRUE;
1128 sal->callbacks.call_updating(op);
1131 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1132 SalOp *op=find_op(sal,ev);
1136 ms_warning("ack for non-existing call !");
1139 if (op->terminated) {
1140 ms_warning("ack for terminated call, ignoring");
1144 if (op->sdp_offering){
1145 sdp=eXosip_get_sdp_info(ev->ack);
1147 if (op->base.remote_media)
1148 sal_media_description_unref(op->base.remote_media);
1149 op->base.remote_media=sal_media_description_new();
1150 sdp_to_media_description(sdp,op->base.remote_media);
1152 sdp_message_free(sdp);
1158 sal->callbacks.call_ack(op);
1161 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1162 const char *received;
1164 SalTransport transport;
1165 if (extract_received_rport(response,&received,&rport,&transport)==0){
1166 const char *contact=sal_op_get_contact(op);
1168 /*no contact given yet, use from instead*/
1169 contact=sal_op_get_from(op);
1172 SalAddress *addr=sal_address_new(contact);
1174 sal_address_set_domain(addr,received);
1175 sal_address_set_port_int(addr,rport);
1176 if (transport!=SalTransportUDP)
1177 sal_address_set_transport(addr,transport);
1178 tmp=sal_address_as_string(addr);
1179 ms_message("Contact address updated to %s",tmp);
1180 sal_op_set_contact(op,tmp);
1181 sal_address_destroy(addr);
1187 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1188 SalOp *op=find_op(sal,ev);
1190 if (op==NULL || op->terminated==TRUE) {
1191 ms_warning("This call has been canceled.");
1193 eXosip_call_terminate(ev->cid,ev->did);
1201 /* update contact if received and rport are set by the server
1202 note: will only be used by remote for next INVITE, if any...*/
1203 update_contact_from_response(op,ev->response);
1207 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1209 SalOp *op=find_op(sal,ev);
1210 if (call_proceeding(sal, ev)==-1) return;
1212 set_remote_ua(op,ev->response);
1213 sdp=eXosip_get_sdp_info(ev->response);
1215 op->base.remote_media=sal_media_description_new();
1216 sdp_to_media_description(sdp,op->base.remote_media);
1217 sdp_message_free(sdp);
1218 if (op->base.local_media) sdp_process(op);
1220 sal->callbacks.call_ringing(op);
1223 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1225 osip_message_t *msg=NULL;
1226 SalOp *op=find_op(sal,ev);
1227 const char *contact;
1229 if (op==NULL || op->terminated==TRUE) {
1230 ms_warning("This call has been already terminated.");
1232 eXosip_call_terminate(ev->cid,ev->did);
1238 set_remote_ua(op,ev->response);
1240 sdp=eXosip_get_sdp_info(ev->response);
1242 op->base.remote_media=sal_media_description_new();
1243 sdp_to_media_description(sdp,op->base.remote_media);
1244 sdp_message_free(sdp);
1245 if (op->base.local_media) sdp_process(op);
1247 eXosip_call_build_ack(ev->did,&msg);
1249 ms_warning("This call has been already terminated.");
1251 eXosip_call_terminate(ev->cid,ev->did);
1255 contact=sal_op_get_contact(op);
1257 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1258 osip_message_set_contact(msg,contact);
1260 if (op->sdp_answer){
1261 set_sdp(msg,op->sdp_answer);
1262 sdp_message_free(op->sdp_answer);
1263 op->sdp_answer=NULL;
1265 eXosip_call_send_ack(ev->did,msg);
1266 sal->callbacks.call_accepted(op);
1269 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1271 SalOp *op=find_op(sal,ev);
1273 ms_warning("Call terminated for already closed call ?");
1277 osip_from_to_str(ev->request->from,&from);
1279 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1280 if (from) osip_free(from);
1281 op->terminated=TRUE;
1284 static void call_released(Sal *sal, eXosip_event_t *ev){
1285 SalOp *op=find_op(sal,ev);
1287 ms_warning("No op associated to this call_released()");
1290 if (!op->terminated){
1291 /* no response received so far */
1292 call_failure(sal,ev);
1294 sal->callbacks.call_released(op);
1297 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1298 const char *prx_realm=NULL,*www_realm=NULL;
1299 osip_proxy_authenticate_t *prx_auth;
1300 osip_www_authenticate_t *www_auth;
1302 *username=osip_uri_get_username(resp->from->url);
1303 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1304 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1306 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1308 www_realm=osip_www_authenticate_get_realm(www_auth);
1312 }else if (www_realm){
1320 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1321 osip_authorization_t *auth=NULL;
1322 osip_proxy_authorization_t *prx_auth=NULL;
1324 *username=osip_uri_get_username(msg->from->url);
1325 osip_message_get_authorization(msg, 0, &auth);
1327 *realm=osip_authorization_get_realm(auth);
1330 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1332 *realm=osip_proxy_authorization_get_realm(prx_auth);
1338 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1339 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1340 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1344 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1345 if (op->pending_auth){
1346 return get_auth_data(op->pending_auth,realm,username);
1351 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1353 const char *username,*realm;
1356 ms_warning("No operation associated with this authentication !");
1359 if (get_auth_data(ev,&realm,&username)==0){
1360 if (op->pending_auth!=NULL){
1361 eXosip_event_free(op->pending_auth);
1362 op->pending_auth=ev;
1364 op->pending_auth=ev;
1365 sal_add_pending_auth(sal,op);
1368 sal->callbacks.auth_requested(op,realm,username);
1374 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1376 const char *username,*realm;
1379 ms_warning("No operation associated with this authentication_ok!");
1382 if (op->pending_auth){
1383 eXosip_event_free(op->pending_auth);
1384 sal_remove_pending_auth(sal,op);
1385 op->pending_auth=NULL;
1387 if (get_auth_data(ev,&realm,&username)==0){
1388 sal->callbacks.auth_success(op,realm,username);
1392 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1395 char* computedReason=NULL;
1396 const char *reason=NULL;
1397 SalError error=SalErrorUnknown;
1398 SalReason sr=SalReasonUnknown;
1401 op=(SalOp*)find_op(sal,ev);
1404 ms_warning("Call failure reported for a closed call, ignored.");
1409 code=osip_message_get_status_code(ev->response);
1410 reason=osip_message_get_reason_phrase(ev->response);
1411 osip_header_t *h=NULL;
1412 if (!osip_message_header_get_byname( ev->response
1416 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1417 reason = computedReason;
1425 return process_authentication(sal,ev);
1428 error=SalErrorUnknown;
1431 error=SalErrorFailure;
1432 sr=SalReasonNotFound;
1435 error=SalErrorFailure;
1439 eXosip_default_action(ev);
1443 error=SalErrorFailure;
1444 sr=SalReasonTemporarilyUnavailable;
1446 error=SalErrorFailure;
1452 error=SalErrorFailure;
1453 sr=SalReasonDoNotDisturb;
1456 error=SalErrorFailure;
1457 sr=SalReasonDeclined;
1461 error=SalErrorFailure;
1462 sr=SalReasonUnknown;
1463 }else error=SalErrorNoResponse;
1465 op->terminated=TRUE;
1466 sal->callbacks.call_failure(op,error,sr,reason,code);
1467 if (computedReason != NULL){
1468 ms_free(computedReason);
1473 /* Request remote side to send us VFU */
1474 void sal_call_send_vfu_request(SalOp *h){
1475 osip_message_t *msg=NULL;
1477 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1481 " <picture_fast_update></picture_fast_update>"
1489 eXosip_call_build_info(h->did,&msg);
1491 osip_message_set_body(msg,info_body,strlen(info_body));
1492 osip_message_set_content_type(msg,"application/media_control+xml");
1493 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1494 osip_message_set_content_length(msg,clen);
1495 eXosip_call_send_request(h->did,msg);
1496 ms_message("Sending VFU request !");
1501 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1502 SalOp *op=find_op(sal,ev);
1503 osip_body_t *body=NULL;
1506 ms_warning("media control xml received without operation context!");
1510 osip_message_get_body(ev->request,0,&body);
1511 if (body && body->body!=NULL &&
1512 strstr(body->body,"picture_fast_update")){
1513 osip_message_t *ans=NULL;
1514 ms_message("Receiving VFU request !");
1515 if (sal->callbacks.vfu_request){
1516 sal->callbacks.vfu_request(op);
1517 eXosip_call_build_answer(ev->tid,200,&ans);
1519 eXosip_call_send_answer(ev->tid,200,ans);
1523 /*in all other cases we must say it is not implemented.*/
1525 osip_message_t *ans=NULL;
1527 eXosip_call_build_answer(ev->tid,501,&ans);
1529 eXosip_call_send_answer(ev->tid,501,ans);
1534 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1535 SalOp *op=find_op(sal,ev);
1536 osip_body_t *body=NULL;
1539 ms_warning("media dtmf relay received without operation context!");
1543 osip_message_get_body(ev->request,0,&body);
1544 if (body && body->body!=NULL){
1545 osip_message_t *ans=NULL;
1546 const char *name=strstr(body->body,"Signal");
1547 if (name==NULL) name=strstr(body->body,"signal");
1549 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1552 name+=strlen("signal");
1553 if (sscanf(name," = %1s",tmp)==1){
1554 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1555 if (sal->callbacks.dtmf_received != NULL)
1556 sal->callbacks.dtmf_received(op, tmp[0]);
1560 eXosip_call_build_answer(ev->tid,200,&ans);
1562 eXosip_call_send_answer(ev->tid,200,ans);
1567 static void fill_options_answer(osip_message_t *options){
1568 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1569 osip_message_set_accept(options,"application/sdp");
1572 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1573 osip_header_t *h=NULL;
1574 osip_message_t *ans=NULL;
1575 ms_message("Receiving REFER request !");
1576 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1579 osip_from_t *from=NULL;
1581 osip_from_init(&from);
1583 if (osip_from_parse(from,h->hvalue)==0){
1585 osip_uri_header_t *uh=NULL;
1586 osip_header_t *referred_by=NULL;
1587 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1588 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1589 ms_message("Found replaces in Refer-To");
1591 ms_free(op->replaces);
1593 op->replaces=ms_strdup(uh->gvalue);
1595 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1596 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1597 if (op->referred_by)
1598 ms_free(op->referred_by);
1599 op->referred_by=ms_strdup(referred_by->hvalue);
1602 osip_uri_header_freelist(&from->url->url_headers);
1603 osip_from_to_str(from,&tmp);
1604 sal->callbacks.refer_received(sal,op,tmp);
1606 osip_from_free(from);
1609 eXosip_call_build_answer(ev->tid,202,&ans);
1611 eXosip_call_send_answer(ev->tid,202,ans);
1616 ms_warning("cannot do anything with the refer without destination\n");
1620 static void process_notify(Sal *sal, eXosip_event_t *ev){
1621 osip_header_t *h=NULL;
1623 SalOp *op=find_op(sal,ev);
1624 osip_message_t *ans=NULL;
1626 ms_message("Receiving NOTIFY request !");
1627 osip_from_to_str(ev->request->from,&from);
1628 osip_message_header_get_byname(ev->request,"Event",0,&h);
1630 osip_body_t *body=NULL;
1631 //osip_content_type_t *ct=NULL;
1632 osip_message_get_body(ev->request,0,&body);
1633 //ct=osip_message_get_content_type(ev->request);
1634 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1635 /*special handling of refer events*/
1636 if (body && body->body){
1637 osip_message_t *msg;
1638 osip_message_init(&msg);
1639 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1640 int code=osip_message_get_status_code(msg);
1642 sal->callbacks.notify_refer(op,SalReferTrying);
1643 }else if (code==200){
1644 sal->callbacks.notify_refer(op,SalReferSuccess);
1645 }else if (code>=400){
1646 sal->callbacks.notify_refer(op,SalReferFailed);
1649 osip_message_free(msg);
1652 /*generic handling*/
1653 sal->callbacks.notify(op,from,h->hvalue);
1656 /*answer that we received the notify*/
1658 eXosip_call_build_answer(ev->tid,200,&ans);
1660 eXosip_call_send_answer(ev->tid,200,ans);
1665 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1666 osip_message_t *ans=NULL;
1668 if (MSG_IS_INFO(ev->request)){
1669 osip_content_type_t *ct;
1670 ct=osip_message_get_content_type(ev->request);
1671 if (ct && ct->subtype){
1672 if (strcmp(ct->subtype,"media_control+xml")==0)
1673 process_media_control_xml(sal,ev);
1674 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1675 process_dtmf_relay(sal,ev);
1677 ms_message("Unhandled SIP INFO.");
1678 /*send an "Not implemented" answer*/
1680 eXosip_call_build_answer(ev->tid,501,&ans);
1682 eXosip_call_send_answer(ev->tid,501,ans);
1686 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1688 eXosip_call_build_answer(ev->tid,200,&ans);
1690 eXosip_call_send_answer(ev->tid,200,ans);
1693 }else if(MSG_IS_MESSAGE(ev->request)){
1694 /* SIP messages could be received into call */
1695 text_received(sal, ev);
1697 eXosip_call_build_answer(ev->tid,200,&ans);
1699 eXosip_call_send_answer(ev->tid,200,ans);
1701 }else if(MSG_IS_REFER(ev->request)){
1702 SalOp *op=find_op(sal,ev);
1704 ms_message("Receiving REFER request !");
1705 process_refer(sal,op,ev);
1706 }else if(MSG_IS_NOTIFY(ev->request)){
1707 process_notify(sal,ev);
1708 }else if (MSG_IS_OPTIONS(ev->request)){
1710 eXosip_call_build_answer(ev->tid,200,&ans);
1712 fill_options_answer(ans);
1713 eXosip_call_send_answer(ev->tid,200,ans);
1717 }else ms_warning("call_message_new: No request ?");
1720 static void inc_update(Sal *sal, eXosip_event_t *ev){
1721 osip_message_t *msg=NULL;
1722 ms_message("Processing incoming UPDATE");
1724 eXosip_message_build_answer(ev->tid,200,&msg);
1726 eXosip_message_send_answer(ev->tid,200,msg);
1730 static bool_t comes_from_local_if(osip_message_t *msg){
1731 osip_via_t *via=NULL;
1732 osip_message_get_via(msg,0,&via);
1735 host=osip_via_get_host(via);
1736 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1737 osip_generic_param_t *param=NULL;
1738 osip_via_param_get_byname(via,"received",¶m);
1739 if (param==NULL) return TRUE;
1740 if (param->gvalue &&
1741 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1749 static void text_received(Sal *sal, eXosip_event_t *ev){
1750 osip_body_t *body=NULL;
1751 char *from=NULL,*msg=NULL;
1752 osip_content_type_t* content_type;
1753 osip_uri_param_t* external_body_url;
1754 char unquoted_external_body_url [256];
1755 int external_body_size=0;
1757 char message_id[256]={0};
1759 content_type= osip_message_get_content_type(ev->request);
1760 if (!content_type) {
1761 ms_error("Could not get message because no content type");
1764 osip_from_to_str(ev->request->from,&from);
1765 if (content_type->type
1766 && strcmp(content_type->type, "text")==0
1767 && content_type->subtype
1768 && strcmp(content_type->subtype, "plain")==0 ) {
1769 osip_message_get_body(ev->request,0,&body);
1771 ms_error("Could not get text message from SIP body");
1776 }else if (content_type->type
1777 && strcmp(content_type->type, "message")==0
1778 && content_type->subtype
1779 && strcmp(content_type->subtype, "external-body")==0 ) {
1781 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1782 /*remove both first and last character*/
1783 strncpy(unquoted_external_body_url
1784 ,&external_body_url->gvalue[1]
1785 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1786 unquoted_external_body_url[external_body_size-1]='\0';
1788 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1792 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1796 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1797 salmsg.message_id=message_id;
1798 sal->callbacks.text_received(sal,&salmsg);
1804 static void other_request(Sal *sal, eXosip_event_t *ev){
1805 ms_message("in other_request");
1806 if (ev->request==NULL) return;
1807 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1808 text_received(sal,ev);
1809 eXosip_message_send_answer(ev->tid,200,NULL);
1810 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1811 osip_message_t *options=NULL;
1812 eXosip_options_build_answer(ev->tid,200,&options);
1813 fill_options_answer(options);
1814 eXosip_options_send_answer(ev->tid,200,options);
1815 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1816 ms_message("Receiving REFER request !");
1817 if (comes_from_local_if(ev->request)) {
1818 process_refer(sal,NULL,ev);
1819 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1820 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1825 osip_message_to_str(ev->request,&tmp,&msglen);
1827 ms_message("Unsupported request received:\n%s",tmp);
1830 /*answer with a 501 Not implemented*/
1831 eXosip_message_send_answer(ev->tid,501,NULL);
1835 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1836 osip_via_t *via=NULL;
1837 osip_message_get_via(msg,0,&via);
1839 osip_free(via->port);
1840 via->port=osip_strdup(port);
1841 osip_free(via->host);
1842 via->host=osip_strdup(ip);
1847 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1848 osip_contact_t *ctt=NULL;
1849 const char *received;
1851 SalTransport transport;
1854 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1855 osip_message_get_contact(request,0,&ctt);
1857 ms_warning("fix_message_contact(): no contact to update");
1860 if (expire_last_contact){
1861 osip_contact_t *oldct=NULL,*prevct;
1862 osip_generic_param_t *param=NULL;
1863 osip_contact_clone(ctt,&oldct);
1864 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1865 osip_contact_free(prevct);
1866 osip_list_remove(&request->contacts,1);
1868 osip_list_add(&request->contacts,oldct,1);
1869 osip_contact_param_get_byname(oldct,"expires",¶m);
1871 if (param->gvalue) osip_free(param->gvalue);
1872 param->gvalue=osip_strdup("0");
1874 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1877 if (ctt->url->host!=NULL){
1878 osip_free(ctt->url->host);
1880 ctt->url->host=osip_strdup(received);
1881 if (ctt->url->port!=NULL){
1882 osip_free(ctt->url->port);
1884 snprintf(port,sizeof(port),"%i",rport);
1885 ctt->url->port=osip_strdup(port);
1886 if (op->masquerade_via) masquerade_via(request,received,port);
1888 if (transport != SalTransportUDP) {
1889 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1894 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1895 osip_contact_t *ctt=NULL;
1896 SalAddress* ori_contact_address=NULL;
1897 const char *received;
1899 SalTransport transport;
1901 osip_message_t *msg=NULL;
1902 Sal* sal=op->base.root;
1904 bool_t found_valid_contact=FALSE;
1905 bool_t from_request=FALSE;
1907 if (sal->double_reg==FALSE ) return FALSE;
1909 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1912 osip_message_get_contact(last_answer,i,&ctt);
1913 if (!from_request && ctt==NULL) {
1914 osip_message_get_contact(orig_request,0,&ctt);
1918 osip_contact_to_str(ctt,&tmp);
1919 ori_contact_address = sal_address_new(tmp);
1921 /*check if contact is up to date*/
1922 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1923 && sal_address_get_port_int(ori_contact_address) == rport
1924 && sal_address_get_transport(ori_contact_address) == transport) {
1926 ms_message("Register response has up to date contact, doing nothing.");
1928 ms_warning("Register response does not have up to date contact, but last request had."
1929 "Stupid registrar detected, giving up.");
1931 found_valid_contact=TRUE;
1934 sal_address_destroy(ori_contact_address);
1937 }while(!found_valid_contact);
1938 if (!found_valid_contact)
1939 ms_message("Contact do not match, resending register.");
1943 eXosip_register_build_register(op->rid,op->expires,&msg);
1946 ms_warning("Fail to create a contact updated register.");
1949 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1950 eXosip_register_send_register(op->rid,msg);
1952 ms_message("Resending new register with updated contact");
1953 update_contact_from_response(op,last_answer);
1956 ms_warning("Fail to send updated register.");
1964 static void registration_success(Sal *sal, eXosip_event_t *ev){
1965 SalOp *op=sal_find_register(sal,ev->rid);
1966 osip_header_t *h=NULL;
1969 ms_error("Receiving register response for unknown operation");
1972 osip_message_get_expires(ev->request,0,&h);
1973 if (h!=NULL && atoi(h->hvalue)!=0){
1975 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1976 sal->callbacks.register_success(op,registered);
1979 sal->callbacks.register_success(op,FALSE);
1983 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1985 const char *reason=NULL;
1986 SalOp *op=sal_find_register(sal,ev->rid);
1987 SalReason sr=SalReasonUnknown;
1988 SalError se=SalErrorUnknown;
1991 ms_error("Receiving register failure for unknown operation");
1995 status_code=osip_message_get_status_code(ev->response);
1996 reason=osip_message_get_reason_phrase(ev->response);
1998 switch(status_code){
2001 return process_authentication(sal,ev);
2003 case 423: /*interval too brief*/
2004 {/*retry with greater interval */
2005 osip_header_t *h=NULL;
2006 osip_message_t *msg=NULL;
2007 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
2008 if (h && h->hvalue && h->hvalue[0]!='\0'){
2009 int val=atoi(h->hvalue);
2010 if (val>op->expires)
2012 }else op->expires*=2;
2014 eXosip_register_build_register(op->rid,op->expires,&msg);
2015 eXosip_register_send_register(op->rid,msg);
2019 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2020 in vias, such as ekiga.net
2021 On the opposite, freephonie.net bugs when via are masqueraded.
2023 op->masquerade_via=TRUE;
2025 /* if contact is up to date, process the failure, otherwise resend a new register with
2026 updated contact first, just in case the faillure is due to incorrect contact */
2027 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2028 return TRUE; /*we are retrying with an updated contact*/
2029 if (status_code==403){
2031 sr=SalReasonForbidden;
2032 }else if (status_code==0){
2033 se=SalErrorNoResponse;
2035 sal->callbacks.register_failure(op,se,sr,reason);
2040 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2041 SalOp *op=find_op(sal,ev);
2043 ms_warning("other_request_reply(): Receiving response to unknown request.");
2047 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2048 update_contact_from_response(op,ev->response);
2049 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2050 sal->callbacks.ping_reply(op);
2052 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2053 /*out of call message acknolegment*/
2054 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2056 if (ev->response->status_code<200){
2057 status=SalTextDeliveryInProgress;
2058 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2059 status=SalTextDeliveryDone;
2062 sal->callbacks.text_delivery_update(op,status);
2066 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2067 SalOp *op=find_op(sal,ev);
2069 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2070 if (op->sipfrag_pending){
2071 send_notify_for_refer(op->did,op->sipfrag_pending);
2072 op->sipfrag_pending=NULL;
2078 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2079 ms_message("linphone process event get a message %d\n",ev->type);
2081 case EXOSIP_CALL_ANSWERED:
2082 ms_message("CALL_ANSWERED\n");
2083 call_accepted(sal,ev);
2084 authentication_ok(sal,ev);
2086 case EXOSIP_CALL_CLOSED:
2087 case EXOSIP_CALL_CANCELLED:
2088 ms_message("CALL_CLOSED or CANCELLED\n");
2089 call_terminated(sal,ev);
2091 case EXOSIP_CALL_TIMEOUT:
2092 case EXOSIP_CALL_NOANSWER:
2093 ms_message("CALL_TIMEOUT or NOANSWER\n");
2094 return call_failure(sal,ev);
2096 case EXOSIP_CALL_REQUESTFAILURE:
2097 case EXOSIP_CALL_GLOBALFAILURE:
2098 case EXOSIP_CALL_SERVERFAILURE:
2099 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2100 return call_failure(sal,ev);
2102 case EXOSIP_CALL_RELEASED:
2103 ms_message("CALL_RELEASED\n");
2104 call_released(sal, ev);
2106 case EXOSIP_CALL_INVITE:
2107 ms_message("CALL_NEW\n");
2108 inc_new_call(sal,ev);
2110 case EXOSIP_CALL_REINVITE:
2111 handle_reinvite(sal,ev);
2113 case EXOSIP_CALL_ACK:
2114 ms_message("CALL_ACK");
2117 case EXOSIP_CALL_REDIRECTED:
2118 ms_message("CALL_REDIRECTED");
2119 eXosip_default_action(ev);
2121 case EXOSIP_CALL_PROCEEDING:
2122 ms_message("CALL_PROCEEDING");
2123 call_proceeding(sal,ev);
2125 case EXOSIP_CALL_RINGING:
2126 ms_message("CALL_RINGING");
2127 call_ringing(sal,ev);
2128 authentication_ok(sal,ev);
2130 case EXOSIP_CALL_MESSAGE_NEW:
2131 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2132 call_message_new(sal,ev);
2134 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2136 (ev->response->status_code==407 || ev->response->status_code==401)){
2137 return process_authentication(sal,ev);
2140 case EXOSIP_CALL_MESSAGE_ANSWERED:
2141 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2142 process_in_call_reply(sal,ev);
2144 case EXOSIP_IN_SUBSCRIPTION_NEW:
2145 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2146 sal_exosip_subscription_recv(sal,ev);
2148 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2149 ms_message("CALL_SUBSCRIPTION_NEW ");
2150 sal_exosip_in_subscription_closed(sal,ev);
2152 case EXOSIP_SUBSCRIPTION_UPDATE:
2153 ms_message("CALL_SUBSCRIPTION_UPDATE");
2155 case EXOSIP_SUBSCRIPTION_NOTIFY:
2156 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2157 sal_exosip_notify_recv(sal,ev);
2159 case EXOSIP_SUBSCRIPTION_ANSWERED:
2160 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2161 sal_exosip_subscription_answered(sal,ev);
2163 case EXOSIP_SUBSCRIPTION_CLOSED:
2164 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2165 sal_exosip_subscription_closed(sal,ev);
2167 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2168 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2169 return process_authentication(sal,ev);
2171 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2172 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2173 sal_exosip_subscription_closed(sal,ev);
2175 case EXOSIP_REGISTRATION_FAILURE:
2176 ms_message("REGISTRATION_FAILURE\n");
2177 return registration_failure(sal,ev);
2179 case EXOSIP_REGISTRATION_SUCCESS:
2180 authentication_ok(sal,ev);
2181 registration_success(sal,ev);
2183 case EXOSIP_MESSAGE_NEW:
2184 other_request(sal,ev);
2186 case EXOSIP_MESSAGE_PROCEEDING:
2187 case EXOSIP_MESSAGE_ANSWERED:
2188 case EXOSIP_MESSAGE_REDIRECTED:
2189 case EXOSIP_MESSAGE_SERVERFAILURE:
2190 case EXOSIP_MESSAGE_GLOBALFAILURE:
2191 other_request_reply(sal,ev);
2193 case EXOSIP_MESSAGE_REQUESTFAILURE:
2194 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2196 switch (ev->response->status_code) {
2199 return process_authentication(sal,ev);
2201 eXosip_automatic_action ();
2206 other_request_reply(sal,ev);
2209 ms_message("Unhandled exosip event ! %i",ev->type);
2215 int sal_iterate(Sal *sal){
2217 while((ev=eXosip_event_wait(0,0))!=NULL){
2218 if (process_event(sal,ev))
2219 eXosip_event_free(ev);
2221 #ifdef HAVE_EXOSIP_TRYLOCK
2222 if (eXosip_trylock()==0){
2223 eXosip_automatic_refresh();
2226 ms_warning("eXosip_trylock busy.");
2230 eXosip_automatic_refresh();
2236 static void register_set_contact(osip_message_t *msg, const char *contact){
2237 osip_uri_param_t *param = NULL;
2238 osip_contact_t *ct=NULL;
2240 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2241 osip_message_get_contact(msg,0,&ct);
2243 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2244 if (param && param->gvalue)
2245 line=osip_strdup(param->gvalue);
2247 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2248 osip_message_set_contact(msg,contact);
2249 osip_message_get_contact(msg,0,&ct);
2250 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2253 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2254 osip_route_t *route;
2256 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2258 osip_route_init(&route);
2259 if (osip_route_parse(route,proxy)==0){
2260 osip_uri_param_t *lr_param = NULL;
2261 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2262 if (lr_param == NULL){
2263 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2265 osip_list_add(&msg->routes,route,0);
2268 osip_route_free(route);
2272 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2273 osip_message_t *msg;
2274 const char *contact=sal_op_get_contact(h);
2276 sal_op_set_route(h,proxy);
2278 SalAddress *from_parsed=sal_address_new(from);
2280 char *uri, *domain_ptr = NULL;
2281 if (from_parsed==NULL) {
2282 ms_warning("sal_register() bad from %s",from);
2285 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2286 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2287 uri = sal_address_as_string_uri_only(from_parsed);
2288 if (uri) domain_ptr = strchr(uri, '@');
2290 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2292 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2294 if (uri) ms_free(uri);
2295 sal_address_destroy(from_parsed);
2297 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2299 if (contact) register_set_contact(msg,contact);
2300 sal_register_add_route(msg,proxy);
2301 sal_add_register(h->base.root,h);
2303 ms_error("Could not build initial register.");
2309 eXosip_register_build_register(h->rid,expires,&msg);
2310 sal_register_add_route(msg,proxy);
2313 eXosip_register_send_register(h->rid,msg);
2317 return (msg != NULL) ? 0 : -1;
2320 int sal_register_refresh(SalOp *op, int expires){
2321 osip_message_t *msg=NULL;
2322 const char *contact=sal_op_get_contact(op);
2325 ms_error("Unexistant registration context, not possible to refresh.");
2328 #ifdef HAVE_EXOSIP_TRYLOCK
2331 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2332 * 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
2333 * the exosip lock in a non blocking way, and give up if it takes too long*/
2334 while (eXosip_trylock()!=0){
2336 if (tries>30) {/*after 3 seconds, give up*/
2337 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2345 eXosip_register_build_register(op->rid,expires,&msg);
2347 if (contact) register_set_contact(msg,contact);
2348 sal_register_add_route(msg,sal_op_get_route(op));
2349 eXosip_register_send_register(op->rid,msg);
2350 }else ms_error("Could not build REGISTER refresh message.");
2352 return (msg != NULL) ? 0 : -1;
2356 int sal_unregister(SalOp *h){
2357 osip_message_t *msg=NULL;
2359 eXosip_register_build_register(h->rid,0,&msg);
2360 if (msg) eXosip_register_send_register(h->rid,msg);
2361 else ms_warning("Could not build unREGISTER !");
2366 SalAddress * sal_address_new(const char *uri){
2368 osip_from_init(&from);
2370 // Remove front spaces
2371 while (uri[0]==' ') {
2375 if (osip_from_parse(from,uri)!=0){
2376 osip_from_free(from);
2379 if (from->displayname!=NULL && from->displayname[0]=='"'){
2380 char *unquoted=osip_strdup_without_quote(from->displayname);
2381 osip_free(from->displayname);
2382 from->displayname=unquoted;
2384 return (SalAddress*)from;
2387 SalAddress * sal_address_clone(const SalAddress *addr){
2388 osip_from_t *ret=NULL;
2389 osip_from_clone((osip_from_t*)addr,&ret);
2390 return (SalAddress*)ret;
2393 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2395 const char *sal_address_get_scheme(const SalAddress *addr){
2396 const osip_from_t *u=(const osip_from_t*)addr;
2397 return null_if_empty(u->url->scheme);
2400 const char *sal_address_get_display_name(const SalAddress* addr){
2401 const osip_from_t *u=(const osip_from_t*)addr;
2402 return null_if_empty(u->displayname);
2405 const char *sal_address_get_username(const SalAddress *addr){
2406 const osip_from_t *u=(const osip_from_t*)addr;
2407 return null_if_empty(u->url->username);
2410 const char *sal_address_get_domain(const SalAddress *addr){
2411 const osip_from_t *u=(const osip_from_t*)addr;
2412 return null_if_empty(u->url->host);
2415 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2416 osip_from_t *u=(osip_from_t*)addr;
2417 if (u->displayname!=NULL){
2418 osip_free(u->displayname);
2419 u->displayname=NULL;
2421 if (display_name!=NULL && display_name[0]!='\0'){
2422 u->displayname=osip_strdup(display_name);
2426 void sal_address_set_username(SalAddress *addr, const char *username){
2427 osip_from_t *uri=(osip_from_t*)addr;
2428 if (uri->url->username!=NULL){
2429 osip_free(uri->url->username);
2430 uri->url->username=NULL;
2433 uri->url->username=osip_strdup(username);
2436 void sal_address_set_domain(SalAddress *addr, const char *host){
2437 osip_from_t *uri=(osip_from_t*)addr;
2438 if (uri->url->host!=NULL){
2439 osip_free(uri->url->host);
2440 uri->url->host=NULL;
2443 uri->url->host=osip_strdup(host);
2446 void sal_address_set_port(SalAddress *addr, const char *port){
2447 osip_from_t *uri=(osip_from_t*)addr;
2448 if (uri->url->port!=NULL){
2449 osip_free(uri->url->port);
2450 uri->url->port=NULL;
2453 uri->url->port=osip_strdup(port);
2456 void sal_address_set_port_int(SalAddress *uri, int port){
2459 /*this is the default, special case to leave the port field blank*/
2460 sal_address_set_port(uri,NULL);
2463 snprintf(tmp,sizeof(tmp),"%i",port);
2464 sal_address_set_port(uri,tmp);
2467 void sal_address_clean(SalAddress *addr){
2468 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2469 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2472 char *sal_address_as_string(const SalAddress *u){
2474 osip_from_t *from=(osip_from_t *)u;
2475 char *old_displayname=NULL;
2476 /* hack to force use of quotes around the displayname*/
2477 if (from->displayname!=NULL
2478 && from->displayname[0]!='"'){
2479 old_displayname=from->displayname;
2480 from->displayname=osip_enquote(from->displayname);
2482 osip_from_to_str(from,&tmp);
2483 if (old_displayname!=NULL){
2484 ms_free(from->displayname);
2485 from->displayname=old_displayname;
2492 char *sal_address_as_string_uri_only(const SalAddress *u){
2493 char *tmp=NULL,*ret;
2494 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2499 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2500 osip_uri_param_t *param=NULL;
2501 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2503 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2505 osip_free(param->gvalue);
2506 param->gvalue=value ? osip_strdup(value) : NULL;
2511 void sal_address_destroy(SalAddress *u){
2512 osip_from_free((osip_from_t*)u);
2515 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2516 ctx->keepalive_period=value;
2517 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2519 unsigned int sal_get_keepalive_period(Sal *ctx) {
2520 return ctx->keepalive_period;
2523 const char * sal_address_get_port(const SalAddress *addr) {
2524 const osip_from_t *u=(const osip_from_t*)addr;
2525 return null_if_empty(u->url->port);
2528 int sal_address_get_port_int(const SalAddress *uri) {
2529 const char* port = sal_address_get_port(uri);
2536 SalTransport sal_address_get_transport(const SalAddress* addr) {
2537 const osip_from_t *u=(const osip_from_t*)addr;
2538 osip_uri_param_t *transport_param=NULL;
2539 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2540 if (transport_param == NULL){
2541 return SalTransportUDP;
2543 return sal_transport_parse(transport_param->gvalue);
2546 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2547 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2550 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2551 int sal_call_update(SalOp *h, const char *subject){
2553 osip_message_t *reinvite=NULL;
2556 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2561 osip_message_set_subject(reinvite,subject);
2562 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2563 if (h->base.contact){
2564 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2565 osip_message_set_contact(reinvite,h->base.contact);
2567 if (h->base.root->session_expires!=0){
2568 osip_message_set_header(reinvite, "Session-expires", "200");
2569 osip_message_set_supported(reinvite, "timer");
2571 if (h->base.local_media){
2572 h->sdp_offering=TRUE;
2573 set_sdp_from_desc(reinvite,h->base.local_media);
2574 }else h->sdp_offering=FALSE;
2576 err = eXosip_call_send_request(h->did, reinvite);
2580 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2581 ctx->reuse_authorization=value;