3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "sal_eXosip2.h"
24 #include "offeranswer.h"
27 // Necessary to make it linked
28 static void for_linker() { eXosip_transport_hook_register(NULL); }
30 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
32 static void text_received(Sal *sal, eXosip_event_t *ev);
34 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
35 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact);
36 static void update_contact_from_response(SalOp *op, osip_message_t *response);
38 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
40 while(!osip_list_eol(l,0)) {
41 data=osip_list_get(l,0);
42 osip_list_remove(l,0);
43 if (data) freefunc(data);
47 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
48 if (eXosip_guess_localip(address_family,ip,iplen)<0){
49 /*default to something */
50 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
51 ms_error("Could not find default routable ip address !");
56 static SalOp * sal_find_call(Sal *sal, int cid){
59 for(elem=sal->calls;elem!=NULL;elem=elem->next){
60 op=(SalOp*)elem->data;
61 if (op->cid==cid) return op;
66 static void sal_add_call(Sal *sal, SalOp *op){
67 sal->calls=ms_list_append(sal->calls,op);
70 static void sal_remove_call(Sal *sal, SalOp *op){
71 sal->calls=ms_list_remove(sal->calls, op);
74 static SalOp * sal_find_register(Sal *sal, int rid){
77 for(elem=sal->registers;elem!=NULL;elem=elem->next){
78 op=(SalOp*)elem->data;
79 if (op->rid==rid) return op;
84 static void sal_add_register(Sal *sal, SalOp *op){
85 sal->registers=ms_list_append(sal->registers,op);
88 static void sal_remove_register(Sal *sal, int rid){
91 for(elem=sal->registers;elem!=NULL;elem=elem->next){
92 op=(SalOp*)elem->data;
94 sal->registers=ms_list_remove_link(sal->registers,elem);
100 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
103 osip_call_id_t *callid=osip_message_get_call_id(message);
105 ms_error("There is no call-id in this message !");
108 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
109 op=(SalOp*)elem->data;
110 if (osip_call_id_match(callid,op->call_id)==0) return op;
115 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
116 osip_call_id_t *callid=osip_message_get_call_id(request);
118 ms_error("There is no call id in the request !");
121 osip_call_id_clone(callid,&op->call_id);
122 sal->other_transactions=ms_list_append(sal->other_transactions,op);
125 static void sal_remove_other(Sal *sal, SalOp *op){
126 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
130 static void sal_add_pending_auth(Sal *sal, SalOp *op){
131 sal->pending_auths=ms_list_append(sal->pending_auths,op);
135 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
136 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
139 void sal_exosip_fix_route(SalOp *op){
140 if (sal_op_get_route(op)!=NULL){
141 osip_route_t *rt=NULL;
142 osip_uri_param_t *lr_param=NULL;
144 osip_route_init(&rt);
145 if (osip_route_parse(rt,sal_op_get_route(op))<0){
146 ms_warning("Bad route %s!",sal_op_get_route(op));
147 sal_op_set_route(op,NULL);
149 /* check if the lr parameter is set , if not add it */
150 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
153 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
154 osip_route_to_str(rt,&tmproute);
155 sal_op_set_route(op,tmproute);
163 SalOp * sal_op_new(Sal *sal){
164 SalOp *op=ms_new0(SalOp,1);
165 __sal_op_init(op,sal);
166 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
168 op->supports_session_timers=FALSE;
169 op->sdp_offering=TRUE;
170 op->pending_auth=NULL;
175 op->referred_by=NULL;
176 op->masquerade_via=FALSE;
177 op->auto_answer_asked=FALSE;
179 op->terminated=FALSE;
183 bool_t sal_call_autoanswer_asked(SalOp *op)
185 return op->auto_answer_asked;
188 void sal_op_release(SalOp *op){
190 sdp_message_free(op->sdp_answer);
191 if (op->pending_auth)
192 eXosip_event_free(op->pending_auth);
194 sal_remove_register(op->base.root,op->rid);
195 eXosip_register_remove(op->rid);
198 ms_message("Cleaning cid %i",op->cid);
199 sal_remove_call(op->base.root,op);
202 sal_remove_out_subscribe(op->base.root,op);
205 sal_remove_in_subscribe(op->base.root,op);
207 osip_call_id_free(op->call_id);
210 if (op->pending_auth){
211 sal_remove_pending_auth(op->base.root,op);
214 sal_media_description_unref(op->result);
216 sal_remove_other(op->base.root,op);
217 osip_call_id_free(op->call_id);
220 ms_free(op->replaces);
222 if (op->referred_by){
223 ms_free(op->referred_by);
226 sal_auth_info_delete(op->auth_info);
231 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
232 int ortp_level=ORTP_DEBUG;
238 ortp_level=ORTP_MESSAGE;
241 ortp_level=ORTP_WARNING;
245 ortp_level=ORTP_ERROR;
248 ortp_level=ORTP_FATAL;
250 case END_TRACE_LEVEL:
253 if (ortp_log_level_enabled(level)){
254 int len=strlen(chfr);
255 char *chfrdup=ortp_strdup(chfr);
256 /*need to remove endline*/
258 if (chfrdup[len-1]=='\n')
260 if (chfrdup[len-2]=='\r')
263 ortp_logv(ortp_level,chfrdup,ap);
270 static bool_t firsttime=TRUE;
273 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
278 sal->keepalive_period=30;
279 sal->double_reg=TRUE;
280 sal->use_rports=TRUE;
282 sal->reuse_authorization=FALSE;
284 sal->verify_server_certs=TRUE;
285 sal->expire_old_contact=FALSE;
286 sal->add_dates=FALSE;
291 void sal_uninit(Sal* sal){
294 ms_free(sal->rootCa);
298 void sal_set_user_pointer(Sal *sal, void *user_data){
302 void *sal_get_user_pointer(const Sal *sal){
306 static void unimplemented_stub(){
307 ms_warning("Unimplemented SAL callback");
310 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
311 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
312 if (ctx->callbacks.call_received==NULL)
313 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
314 if (ctx->callbacks.call_ringing==NULL)
315 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
316 if (ctx->callbacks.call_accepted==NULL)
317 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
318 if (ctx->callbacks.call_failure==NULL)
319 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
320 if (ctx->callbacks.call_terminated==NULL)
321 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
322 if (ctx->callbacks.call_released==NULL)
323 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
324 if (ctx->callbacks.call_updating==NULL)
325 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
326 if (ctx->callbacks.auth_requested==NULL)
327 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
328 if (ctx->callbacks.auth_success==NULL)
329 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
330 if (ctx->callbacks.register_success==NULL)
331 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
332 if (ctx->callbacks.register_failure==NULL)
333 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
334 if (ctx->callbacks.dtmf_received==NULL)
335 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
336 if (ctx->callbacks.notify==NULL)
337 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
338 if (ctx->callbacks.notify_presence==NULL)
339 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
340 if (ctx->callbacks.subscribe_received==NULL)
341 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
342 if (ctx->callbacks.text_received==NULL)
343 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
344 if (ctx->callbacks.ping_reply==NULL)
345 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
346 if (ctx->callbacks.message_external_body==NULL)
347 ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)unimplemented_stub;
350 int sal_unlisten_ports(Sal *ctx){
359 int sal_reset_transports(Sal *ctx){
360 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
362 ms_message("Exosip transports reset.");
363 eXosip_reset_transports();
367 ms_warning("sal_reset_transports() not implemented in this version.");
373 static void set_tls_options(Sal *ctx){
375 eXosip_tls_ctx_t tlsCtx;
376 memset(&tlsCtx, 0, sizeof(tlsCtx));
377 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
378 eXosip_set_tls_ctx(&tlsCtx);
380 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
381 eXosip_tls_verify_certificate(ctx->verify_server_certs);
385 void sal_set_dscp(Sal *ctx, int dscp){
388 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
391 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
394 int proto=IPPROTO_UDP;
395 int keepalive = ctx->keepalive_period;
398 case SalTransportUDP:
400 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
402 case SalTransportTCP:
403 case SalTransportTLS:
406 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
407 set_tls_options(ctx);
410 ms_warning("unexpected proto, using datagram");
412 /*see if it looks like an IPv6 address*/
413 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
414 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
415 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
416 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
417 sal_set_dscp(ctx,ctx->dscp);
418 sal_use_dates(ctx,ctx->add_dates);
420 ipv6=strchr(addr,':')!=NULL;
421 eXosip_enable_ipv6(ipv6);
423 if (is_secure && tr == SalTransportUDP){
424 ms_fatal("SIP over DTLS is not supported yet.");
427 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
432 ortp_socket_t sal_get_socket(Sal *ctx){
433 #ifdef HAVE_EXOSIP_GET_SOCKET
434 return eXosip_get_socket(IPPROTO_UDP);
436 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
441 void sal_set_user_agent(Sal *ctx, const char *user_agent){
442 eXosip_set_user_agent(user_agent);
445 void sal_use_session_timers(Sal *ctx, int expires){
446 ctx->session_expires=expires;
449 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
450 ctx->one_matching_codec=one_matching_codec;
453 MSList *sal_get_pending_auths(Sal *sal){
454 return ms_list_copy(sal->pending_auths);
457 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
458 ctx->double_reg=enabled;
461 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
462 ctx->expire_old_contact=enabled;
465 void sal_use_dates(Sal *ctx, bool_t enabled){
466 ctx->add_dates=enabled;
467 #ifdef EXOSIP_OPT_REGISTER_WITH_DATE
470 eXosip_set_option(EXOSIP_OPT_REGISTER_WITH_DATE,&tmp);
473 if (enabled) ms_warning("Exosip does not support EXOSIP_OPT_REGISTER_WITH_DATE option.");
477 void sal_use_rport(Sal *ctx, bool_t use_rports){
478 ctx->use_rports=use_rports;
480 void sal_use_101(Sal *ctx, bool_t use_101){
481 ctx->use_101=use_101;
484 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
486 ms_free(ctx->rootCa);
487 ctx->rootCa = ms_strdup(rootCa);
488 set_tls_options(ctx);
491 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
492 ctx->verify_server_certs=verify;
493 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
494 eXosip_tls_verify_certificate(verify);
498 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
499 osip_via_t *via=NULL;
500 osip_generic_param_t *param=NULL;
501 const char *rport=NULL;
505 osip_message_get_via(msg,0,&via);
507 ms_warning("extract_received_rport(): no via.");
511 *transport = sal_transport_parse(via->protocol);
513 if (via->port && via->port[0]!='\0')
514 *rportval=atoi(via->port);
516 osip_via_param_get_byname(via,"rport",¶m);
519 if (rport && rport[0]!='\0') *rportval=atoi(rport);
523 osip_via_param_get_byname(via,"received",¶m);
524 if (param) *received=param->gvalue;
526 if (rport==NULL && *received==NULL){
527 ms_warning("extract_received_rport(): no rport and no received parameters.");
533 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
537 sdp_message_to_str(msg,&sdp);
539 snprintf(clen,sizeof(clen),"%i",sdplen);
540 osip_message_set_body(sip,sdp,sdplen);
541 osip_message_set_content_type(sip,"application/sdp");
542 osip_message_set_content_length(sip,clen);
546 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
547 sdp_message_t *msg=media_description_to_sdp(desc);
549 ms_error("Fail to print sdp message !");
553 sdp_message_free(msg);
556 static void sdp_process(SalOp *h){
557 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
559 sal_media_description_unref(h->result);
561 h->result=sal_media_description_new();
562 if (h->sdp_offering){
563 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
567 sdp_message_free(h->sdp_answer);
569 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
570 h->sdp_answer=media_description_to_sdp(h->result);
571 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
572 It should contains media parameters constraint from the remote offer, not our response*/
573 strcpy(h->result->addr,h->base.remote_media->addr);
574 h->result->bandwidth=h->base.remote_media->bandwidth;
576 for(i=0;i<h->result->nstreams;++i){
577 if (h->result->streams[i].rtp_port>0){
578 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
579 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
580 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
581 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
582 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
583 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
585 if (h->result->streams[i].proto == SalProtoRtpSavp) {
586 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
594 int sal_call_is_offerer(const SalOp *h){
595 return h->sdp_offering;
598 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
600 sal_media_description_ref(desc);
601 if (h->base.local_media)
602 sal_media_description_unref(h->base.local_media);
603 h->base.local_media=desc;
604 if (h->base.remote_media){
605 /*case of an incoming call where we modify the local capabilities between the time
606 * the call is ringing and it is accepted (for example if you want to accept without video*/
607 /*reset the sdp answer so that it is computed again*/
609 sdp_message_free(h->sdp_answer);
616 int sal_call(SalOp *h, const char *from, const char *to){
619 osip_message_t *invite=NULL;
620 osip_call_id_t *callid;
621 sal_op_set_from(h,from);
623 sal_exosip_fix_route(h);
625 h->terminated = FALSE;
627 route = sal_op_get_route(h);
628 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
630 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
631 err, from, to, route);
634 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
635 if (h->base.contact){
636 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
637 osip_message_set_contact(invite,h->base.contact);
639 if (h->base.root->session_expires!=0){
640 osip_message_set_header(invite, "Session-expires", "200");
641 osip_message_set_supported(invite, "timer");
643 if (h->base.local_media){
644 h->sdp_offering=TRUE;
645 set_sdp_from_desc(invite,h->base.local_media);
646 }else h->sdp_offering=FALSE;
648 osip_message_set_header(invite,"Replaces",h->replaces);
650 osip_message_set_header(invite,"Referred-By",h->referred_by);
654 err=eXosip_call_send_initial_invite(invite);
658 ms_error("Fail to send invite ! Error code %d", err);
661 callid=osip_message_get_call_id(invite);
662 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
663 sal_add_call(h->base.root,h);
668 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
671 /*if early media send also 180 and 183 */
675 eXosip_call_build_answer(h->tid,183,&msg);
679 set_sdp(msg,h->sdp_answer);
680 sdp_message_free(h->sdp_answer);
683 eXosip_call_send_answer(h->tid,183,msg);
688 eXosip_call_send_answer(h->tid,180,NULL);
694 int sal_call_accept(SalOp * h){
696 const char *contact=sal_op_get_contact(h);
698 int err=eXosip_call_build_answer(h->tid,200,&msg);
699 if (err<0 || msg==NULL){
700 ms_error("Fail to build answer for call: err=%i",err);
703 if (h->base.root->session_expires!=0){
704 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
708 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
709 osip_message_set_contact(msg,contact);
712 if (h->base.local_media){
713 /*this is the case where we received an invite without SDP*/
714 if (h->sdp_offering) {
715 set_sdp_from_desc(msg,h->base.local_media);
717 if (h->sdp_answer==NULL) sdp_process(h);
719 set_sdp(msg,h->sdp_answer);
720 sdp_message_free(h->sdp_answer);
725 ms_error("You are accepting a call but not defined any media capabilities !");
727 eXosip_call_send_answer(h->tid,200,msg);
731 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
732 if (reason==SalReasonBusy){
734 eXosip_call_send_answer(h->tid,486,NULL);
737 else if (reason==SalReasonTemporarilyUnavailable){
739 eXosip_call_send_answer(h->tid,480,NULL);
741 }else if (reason==SalReasonDoNotDisturb){
743 eXosip_call_send_answer(h->tid,600,NULL);
745 }else if (reason==SalReasonMedia){
747 eXosip_call_send_answer(h->tid,415,NULL);
749 }else if (redirect!=NULL && reason==SalReasonRedirect){
752 if (strstr(redirect,"sip:")!=0) code=302;
755 eXosip_call_build_answer(h->tid,code,&msg);
756 osip_message_set_contact(msg,redirect);
757 eXosip_call_send_answer(h->tid,code,msg);
759 }else sal_call_terminate(h);
763 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
764 return h->base.remote_media;
767 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
768 if (h->base.local_media && h->base.remote_media && !h->result){
774 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
775 if (refered_call->replaces)
776 h->replaces=ms_strdup(refered_call->replaces);
777 if (refered_call->referred_by)
778 h->referred_by=ms_strdup(refered_call->referred_by);
782 static int send_notify_for_refer(int did, const char *sipfrag){
785 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
788 ms_warning("Could not build NOTIFY for refer.");
791 osip_message_set_content_type(msg,"message/sipfrag");
792 osip_message_set_header(msg,"Event","refer");
793 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
794 eXosip_call_send_request(did,msg);
799 /* currently only support to notify trying and 200Ok*/
800 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
803 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
805 else if (newcall->cid!=-1){
806 if (newcall->did==-1){
807 /* not yet established*/
808 if (!newcall->terminated){
810 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
813 if (!newcall->terminated){
814 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
815 /* we need previous notify transaction to complete, so buffer the request for later*/
816 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
824 int sal_ping(SalOp *op, const char *from, const char *to){
825 osip_message_t *options=NULL;
827 sal_op_set_from(op,from);
828 sal_op_set_to(op,to);
829 sal_exosip_fix_route(op);
831 eXosip_options_build_request (&options, sal_op_get_to(op),
832 sal_op_get_from(op),sal_op_get_route(op));
834 if (op->base.root->session_expires!=0){
835 osip_message_set_header(options, "Session-expires", "200");
836 osip_message_set_supported(options, "timer");
838 sal_add_other(sal_op_get_sal(op),op,options);
839 return eXosip_options_send_request(options);
844 int sal_call_refer(SalOp *h, const char *refer_to){
845 osip_message_t *msg=NULL;
848 eXosip_call_build_refer(h->did,refer_to, &msg);
849 if (msg) err=eXosip_call_send_request(h->did, msg);
855 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
856 osip_message_t *msg=NULL;
857 char referto[256]={0};
860 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
861 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
865 eXosip_call_build_refer(h->did,referto, &msg);
866 osip_message_set_header(msg,"Referred-By",h->base.from);
867 if (msg) err=eXosip_call_send_request(h->did, msg);
873 SalOp *sal_call_get_replaces(SalOp *h){
874 if (h!=NULL && h->replaces!=NULL){
877 cid=eXosip_call_find_by_replaces(h->replaces);
880 SalOp *ret=sal_find_call(h->base.root,cid);
887 int sal_call_send_dtmf(SalOp *h, char dtmf){
888 osip_message_t *msg=NULL;
893 eXosip_call_build_info(h->did,&msg);
895 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
896 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
897 osip_message_set_content_type(msg,"application/dtmf-relay");
898 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
899 osip_message_set_content_length(msg,clen);
900 eXosip_call_send_request(h->did,msg);
906 static void push_auth_to_exosip(const SalAuthInfo *info){
908 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
909 else userid=info->userid;
910 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
911 eXosip_add_authentication_info (info->username,userid,
912 info->password, NULL,info->realm);
915 * Just for symmetry ;-)
917 static void pop_auth_from_exosip() {
918 eXosip_clear_authentication_info();
921 int sal_call_terminate(SalOp *h){
923 if (h == NULL) return -1;
924 if (h->auth_info) push_auth_to_exosip(h->auth_info);
926 err=eXosip_call_terminate(h->cid,h->did);
928 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
930 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
936 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
937 if (h->terminated) return;
938 if (h->pending_auth){
939 push_auth_to_exosip(info);
941 /*FIXME exosip does not take into account this update register message*/
943 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
947 update_contact_from_response(h,h->pending_auth->response);
949 eXosip_default_action(h->pending_auth);
951 ms_message("eXosip_default_action() done");
952 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
954 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
955 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
958 void sal_op_cancel_authentication(SalOp *h) {
960 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
961 } else if (h->cid >0) {
962 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
964 ms_warning("Auth failure not handled");
968 static void set_network_origin(SalOp *op, osip_message_t *req){
969 const char *received=NULL;
972 SalTransport transport;
973 if (extract_received_rport(req,&received,&rport,&transport)!=0){
974 osip_via_t *via=NULL;
976 osip_message_get_via(req,0,&via);
977 received=osip_via_get_host(via);
978 tmp=osip_via_get_port(via);
979 if (tmp) rport=atoi(tmp);
981 if (transport != SalTransportUDP) {
982 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
984 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
986 __sal_op_set_network_origin(op,origin);
989 static void set_remote_ua(SalOp* op, osip_message_t *req){
990 if (op->base.remote_ua==NULL){
991 osip_header_t *h=NULL;
992 osip_message_get_user_agent(req,0,&h);
994 op->base.remote_ua=ms_strdup(h->hvalue);
999 static void set_replaces(SalOp *op, osip_message_t *req){
1000 osip_header_t *h=NULL;
1003 ms_free(op->replaces);
1006 osip_message_header_get_byname(req,"replaces",0,&h);
1008 if (h->hvalue && h->hvalue[0]!='\0'){
1009 op->replaces=ms_strdup(h->hvalue);
1014 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1016 return sal_find_call(sal,ev->cid);
1019 return sal_find_register(sal,ev->rid);
1022 return sal_find_out_subscribe(sal,ev->sid);
1025 return sal_find_in_subscribe(sal,ev->nid);
1027 if (ev->response) return sal_find_other(sal,ev->response);
1028 else if (ev->request) return sal_find_other(sal,ev->request);
1032 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1033 SalOp *op=sal_op_new(sal);
1034 osip_from_t *from,*to;
1035 osip_call_info_t *call_info;
1037 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1038 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1039 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1041 set_network_origin(op,ev->request);
1042 set_remote_ua(op,ev->request);
1043 set_replaces(op,ev->request);
1046 op->sdp_offering=FALSE;
1047 op->base.remote_media=sal_media_description_new();
1048 sdp_to_media_description(sdp,op->base.remote_media);
1049 sdp_message_free(sdp);
1050 }else op->sdp_offering=TRUE;
1052 from=osip_message_get_from(ev->request);
1053 to=osip_message_get_to(ev->request);
1054 osip_from_to_str(from,&tmp);
1055 sal_op_set_from(op,tmp);
1057 osip_from_to_str(to,&tmp);
1058 sal_op_set_to(op,tmp);
1061 osip_message_get_call_info(ev->request,0,&call_info);
1064 osip_call_info_to_str(call_info,&tmp);
1065 if( strstr(tmp,"answer-after=") != NULL)
1067 op->auto_answer_asked=TRUE;
1068 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1076 sal_add_call(op->base.root,op);
1077 sal->callbacks.call_received(op);
1080 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1081 SalOp *op=find_op(sal,ev);
1085 ms_warning("Reinvite for non-existing operation !");
1090 sdp=eXosip_get_sdp_info(ev->request);
1091 if (op->base.remote_media){
1092 sal_media_description_unref(op->base.remote_media);
1093 op->base.remote_media=NULL;
1096 sal_media_description_unref(op->result);
1100 op->sdp_offering=FALSE;
1101 op->base.remote_media=sal_media_description_new();
1102 sdp_to_media_description(sdp,op->base.remote_media);
1103 sdp_message_free(sdp);
1106 op->sdp_offering=TRUE;
1108 sal->callbacks.call_updating(op);
1111 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1112 SalOp *op=find_op(sal,ev);
1116 ms_warning("ack for non-existing call !");
1119 if (op->terminated) {
1120 ms_warning("ack for terminated call, ignoring");
1124 if (op->sdp_offering){
1125 sdp=eXosip_get_sdp_info(ev->ack);
1127 if (op->base.remote_media)
1128 sal_media_description_unref(op->base.remote_media);
1129 op->base.remote_media=sal_media_description_new();
1130 sdp_to_media_description(sdp,op->base.remote_media);
1132 sdp_message_free(sdp);
1138 sal->callbacks.call_ack(op);
1141 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1142 const char *received;
1144 SalTransport transport;
1145 if (extract_received_rport(response,&received,&rport,&transport)==0){
1146 const char *contact=sal_op_get_contact(op);
1148 /*no contact given yet, use from instead*/
1149 contact=sal_op_get_from(op);
1152 SalAddress *addr=sal_address_new(contact);
1154 sal_address_set_domain(addr,received);
1155 sal_address_set_port_int(addr,rport);
1156 if (transport!=SalTransportUDP)
1157 sal_address_set_transport(addr,transport);
1158 tmp=sal_address_as_string(addr);
1159 ms_message("Contact address updated to %s",tmp);
1160 sal_op_set_contact(op,tmp);
1161 sal_address_destroy(addr);
1167 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1168 SalOp *op=find_op(sal,ev);
1170 if (op==NULL || op->terminated==TRUE) {
1171 ms_warning("This call has been canceled.");
1173 eXosip_call_terminate(ev->cid,ev->did);
1181 /* update contact if received and rport are set by the server
1182 note: will only be used by remote for next INVITE, if any...*/
1183 update_contact_from_response(op,ev->response);
1187 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1189 SalOp *op=find_op(sal,ev);
1190 if (call_proceeding(sal, ev)==-1) return;
1192 set_remote_ua(op,ev->response);
1193 sdp=eXosip_get_sdp_info(ev->response);
1195 op->base.remote_media=sal_media_description_new();
1196 sdp_to_media_description(sdp,op->base.remote_media);
1197 sdp_message_free(sdp);
1198 if (op->base.local_media) sdp_process(op);
1200 sal->callbacks.call_ringing(op);
1203 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1205 osip_message_t *msg=NULL;
1206 SalOp *op=find_op(sal,ev);
1207 const char *contact;
1209 if (op==NULL || op->terminated==TRUE) {
1210 ms_warning("This call has been already terminated.");
1212 eXosip_call_terminate(ev->cid,ev->did);
1218 set_remote_ua(op,ev->response);
1220 sdp=eXosip_get_sdp_info(ev->response);
1222 op->base.remote_media=sal_media_description_new();
1223 sdp_to_media_description(sdp,op->base.remote_media);
1224 sdp_message_free(sdp);
1225 if (op->base.local_media) sdp_process(op);
1227 eXosip_call_build_ack(ev->did,&msg);
1229 ms_warning("This call has been already terminated.");
1231 eXosip_call_terminate(ev->cid,ev->did);
1235 contact=sal_op_get_contact(op);
1237 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1238 osip_message_set_contact(msg,contact);
1240 if (op->sdp_answer){
1241 set_sdp(msg,op->sdp_answer);
1242 sdp_message_free(op->sdp_answer);
1243 op->sdp_answer=NULL;
1245 eXosip_call_send_ack(ev->did,msg);
1246 sal->callbacks.call_accepted(op);
1249 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1251 SalOp *op=find_op(sal,ev);
1253 ms_warning("Call terminated for already closed call ?");
1257 osip_from_to_str(ev->request->from,&from);
1259 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1260 if (from) osip_free(from);
1261 op->terminated=TRUE;
1264 static void call_released(Sal *sal, eXosip_event_t *ev){
1265 SalOp *op=find_op(sal,ev);
1267 ms_warning("No op associated to this call_released()");
1270 if (!op->terminated){
1271 /* no response received so far */
1272 call_failure(sal,ev);
1274 sal->callbacks.call_released(op);
1277 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1278 const char *prx_realm=NULL,*www_realm=NULL;
1279 osip_proxy_authenticate_t *prx_auth;
1280 osip_www_authenticate_t *www_auth;
1282 *username=osip_uri_get_username(resp->from->url);
1283 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1284 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1286 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1288 www_realm=osip_www_authenticate_get_realm(www_auth);
1292 }else if (www_realm){
1300 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1301 osip_authorization_t *auth=NULL;
1302 osip_proxy_authorization_t *prx_auth=NULL;
1304 *username=osip_uri_get_username(msg->from->url);
1305 osip_message_get_authorization(msg, 0, &auth);
1307 *realm=osip_authorization_get_realm(auth);
1310 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1312 *realm=osip_proxy_authorization_get_realm(prx_auth);
1318 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1319 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1320 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1324 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1325 if (op->pending_auth){
1326 return get_auth_data(op->pending_auth,realm,username);
1331 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1333 const char *username,*realm;
1336 ms_warning("No operation associated with this authentication !");
1339 if (get_auth_data(ev,&realm,&username)==0){
1340 if (op->pending_auth!=NULL){
1341 eXosip_event_free(op->pending_auth);
1342 op->pending_auth=ev;
1344 op->pending_auth=ev;
1345 sal_add_pending_auth(sal,op);
1348 sal->callbacks.auth_requested(op,realm,username);
1354 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1356 const char *username,*realm;
1359 ms_warning("No operation associated with this authentication_ok!");
1362 if (op->pending_auth){
1363 eXosip_event_free(op->pending_auth);
1364 sal_remove_pending_auth(sal,op);
1365 op->pending_auth=NULL;
1367 if (get_auth_data(ev,&realm,&username)==0){
1368 sal->callbacks.auth_success(op,realm,username);
1372 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1375 char* computedReason=NULL;
1376 const char *reason=NULL;
1377 SalError error=SalErrorUnknown;
1378 SalReason sr=SalReasonUnknown;
1381 op=(SalOp*)find_op(sal,ev);
1384 ms_warning("Call failure reported for a closed call, ignored.");
1389 code=osip_message_get_status_code(ev->response);
1390 reason=osip_message_get_reason_phrase(ev->response);
1391 osip_header_t *h=NULL;
1392 if (!osip_message_header_get_byname( ev->response
1396 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1397 reason = computedReason;
1405 return process_authentication(sal,ev);
1408 error=SalErrorUnknown;
1411 error=SalErrorFailure;
1412 sr=SalReasonNotFound;
1415 error=SalErrorFailure;
1419 eXosip_default_action(ev);
1423 error=SalErrorFailure;
1424 sr=SalReasonTemporarilyUnavailable;
1426 error=SalErrorFailure;
1432 error=SalErrorFailure;
1433 sr=SalReasonDoNotDisturb;
1436 error=SalErrorFailure;
1437 sr=SalReasonDeclined;
1441 error=SalErrorFailure;
1442 sr=SalReasonUnknown;
1443 }else error=SalErrorNoResponse;
1445 op->terminated=TRUE;
1446 sal->callbacks.call_failure(op,error,sr,reason,code);
1447 if (computedReason != NULL){
1448 ms_free(computedReason);
1453 /* Request remote side to send us VFU */
1454 void sal_call_send_vfu_request(SalOp *h){
1455 osip_message_t *msg=NULL;
1457 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1461 " <picture_fast_update></picture_fast_update>"
1469 eXosip_call_build_info(h->did,&msg);
1471 osip_message_set_body(msg,info_body,strlen(info_body));
1472 osip_message_set_content_type(msg,"application/media_control+xml");
1473 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1474 osip_message_set_content_length(msg,clen);
1475 eXosip_call_send_request(h->did,msg);
1476 ms_message("Sending VFU request !");
1481 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1482 SalOp *op=find_op(sal,ev);
1483 osip_body_t *body=NULL;
1486 ms_warning("media control xml received without operation context!");
1490 osip_message_get_body(ev->request,0,&body);
1491 if (body && body->body!=NULL &&
1492 strstr(body->body,"picture_fast_update")){
1493 osip_message_t *ans=NULL;
1494 ms_message("Receiving VFU request !");
1495 if (sal->callbacks.vfu_request){
1496 sal->callbacks.vfu_request(op);
1497 eXosip_call_build_answer(ev->tid,200,&ans);
1499 eXosip_call_send_answer(ev->tid,200,ans);
1503 /*in all other cases we must say it is not implemented.*/
1505 osip_message_t *ans=NULL;
1507 eXosip_call_build_answer(ev->tid,501,&ans);
1509 eXosip_call_send_answer(ev->tid,501,ans);
1514 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1515 SalOp *op=find_op(sal,ev);
1516 osip_body_t *body=NULL;
1519 ms_warning("media dtmf relay received without operation context!");
1523 osip_message_get_body(ev->request,0,&body);
1524 if (body && body->body!=NULL){
1525 osip_message_t *ans=NULL;
1526 const char *name=strstr(body->body,"Signal");
1527 if (name==NULL) name=strstr(body->body,"signal");
1529 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1532 name+=strlen("signal");
1533 if (sscanf(name," = %1s",tmp)==1){
1534 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1535 if (sal->callbacks.dtmf_received != NULL)
1536 sal->callbacks.dtmf_received(op, tmp[0]);
1540 eXosip_call_build_answer(ev->tid,200,&ans);
1542 eXosip_call_send_answer(ev->tid,200,ans);
1547 static void fill_options_answer(osip_message_t *options){
1548 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1549 osip_message_set_accept(options,"application/sdp");
1552 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1553 osip_header_t *h=NULL;
1554 osip_message_t *ans=NULL;
1555 ms_message("Receiving REFER request !");
1556 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1559 osip_from_t *from=NULL;
1561 osip_from_init(&from);
1563 if (osip_from_parse(from,h->hvalue)==0){
1565 osip_uri_header_t *uh=NULL;
1566 osip_header_t *referred_by=NULL;
1567 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1568 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1569 ms_message("Found replaces in Refer-To");
1571 ms_free(op->replaces);
1573 op->replaces=ms_strdup(uh->gvalue);
1575 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1576 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1577 if (op->referred_by)
1578 ms_free(op->referred_by);
1579 op->referred_by=ms_strdup(referred_by->hvalue);
1582 osip_uri_header_freelist(&from->url->url_headers);
1583 osip_from_to_str(from,&tmp);
1584 sal->callbacks.refer_received(sal,op,tmp);
1586 osip_from_free(from);
1589 eXosip_call_build_answer(ev->tid,202,&ans);
1591 eXosip_call_send_answer(ev->tid,202,ans);
1596 ms_warning("cannot do anything with the refer without destination\n");
1600 static void process_notify(Sal *sal, eXosip_event_t *ev){
1601 osip_header_t *h=NULL;
1603 SalOp *op=find_op(sal,ev);
1604 osip_message_t *ans=NULL;
1606 ms_message("Receiving NOTIFY request !");
1607 osip_from_to_str(ev->request->from,&from);
1608 osip_message_header_get_byname(ev->request,"Event",0,&h);
1610 osip_body_t *body=NULL;
1611 //osip_content_type_t *ct=NULL;
1612 osip_message_get_body(ev->request,0,&body);
1613 //ct=osip_message_get_content_type(ev->request);
1614 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1615 /*special handling of refer events*/
1616 if (body && body->body){
1617 osip_message_t *msg;
1618 osip_message_init(&msg);
1619 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1620 int code=osip_message_get_status_code(msg);
1622 sal->callbacks.notify_refer(op,SalReferTrying);
1623 }else if (code==200){
1624 sal->callbacks.notify_refer(op,SalReferSuccess);
1625 }else if (code>=400){
1626 sal->callbacks.notify_refer(op,SalReferFailed);
1629 osip_message_free(msg);
1632 /*generic handling*/
1633 sal->callbacks.notify(op,from,h->hvalue);
1636 /*answer that we received the notify*/
1638 eXosip_call_build_answer(ev->tid,200,&ans);
1640 eXosip_call_send_answer(ev->tid,200,ans);
1645 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1646 osip_message_t *ans=NULL;
1648 if (MSG_IS_INFO(ev->request)){
1649 osip_content_type_t *ct;
1650 ct=osip_message_get_content_type(ev->request);
1651 if (ct && ct->subtype){
1652 if (strcmp(ct->subtype,"media_control+xml")==0)
1653 process_media_control_xml(sal,ev);
1654 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1655 process_dtmf_relay(sal,ev);
1657 ms_message("Unhandled SIP INFO.");
1658 /*send an "Not implemented" answer*/
1660 eXosip_call_build_answer(ev->tid,501,&ans);
1662 eXosip_call_send_answer(ev->tid,501,ans);
1666 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1668 eXosip_call_build_answer(ev->tid,200,&ans);
1670 eXosip_call_send_answer(ev->tid,200,ans);
1673 }else if(MSG_IS_MESSAGE(ev->request)){
1674 /* SIP messages could be received into call */
1675 text_received(sal, ev);
1677 eXosip_call_build_answer(ev->tid,200,&ans);
1679 eXosip_call_send_answer(ev->tid,200,ans);
1681 }else if(MSG_IS_REFER(ev->request)){
1682 SalOp *op=find_op(sal,ev);
1684 ms_message("Receiving REFER request !");
1685 process_refer(sal,op,ev);
1686 }else if(MSG_IS_NOTIFY(ev->request)){
1687 process_notify(sal,ev);
1688 }else if (MSG_IS_OPTIONS(ev->request)){
1690 eXosip_call_build_answer(ev->tid,200,&ans);
1692 fill_options_answer(ans);
1693 eXosip_call_send_answer(ev->tid,200,ans);
1697 }else ms_warning("call_message_new: No request ?");
1700 static void inc_update(Sal *sal, eXosip_event_t *ev){
1701 osip_message_t *msg=NULL;
1702 ms_message("Processing incoming UPDATE");
1704 eXosip_message_build_answer(ev->tid,200,&msg);
1706 eXosip_message_send_answer(ev->tid,200,msg);
1710 static bool_t comes_from_local_if(osip_message_t *msg){
1711 osip_via_t *via=NULL;
1712 osip_message_get_via(msg,0,&via);
1715 host=osip_via_get_host(via);
1716 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1717 osip_generic_param_t *param=NULL;
1718 osip_via_param_get_byname(via,"received",¶m);
1719 if (param==NULL) return TRUE;
1720 if (param->gvalue &&
1721 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1729 static void text_received(Sal *sal, eXosip_event_t *ev){
1730 osip_body_t *body=NULL;
1731 char *from=NULL,*msg;
1732 osip_content_type_t* content_type;
1733 osip_uri_param_t* external_body_url;
1734 char unquoted_external_body_url [256];
1735 int external_body_size=0;
1737 content_type= osip_message_get_content_type(ev->request);
1738 if (!content_type) {
1739 ms_error("Could not get message because no content type");
1742 osip_from_to_str(ev->request->from,&from);
1743 if (content_type->type
1744 && strcmp(content_type->type, "text")==0
1745 && content_type->subtype
1746 && strcmp(content_type->subtype, "plain")==0 ) {
1747 osip_message_get_body(ev->request,0,&body);
1749 ms_error("Could not get text message from SIP body");
1753 sal->callbacks.text_received(sal,from,msg);
1754 } if (content_type->type
1755 && strcmp(content_type->type, "message")==0
1756 && content_type->subtype
1757 && strcmp(content_type->subtype, "external-body")==0 ) {
1759 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1760 /*remove both first and last character*/
1761 strncpy(unquoted_external_body_url
1762 ,&external_body_url->gvalue[1]
1763 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1764 unquoted_external_body_url[external_body_size-1]='\0';
1765 sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
1768 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1775 static void other_request(Sal *sal, eXosip_event_t *ev){
1776 ms_message("in other_request");
1777 if (ev->request==NULL) return;
1778 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1779 text_received(sal,ev);
1780 eXosip_message_send_answer(ev->tid,200,NULL);
1781 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1782 osip_message_t *options=NULL;
1783 eXosip_options_build_answer(ev->tid,200,&options);
1784 fill_options_answer(options);
1785 eXosip_options_send_answer(ev->tid,200,options);
1786 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1787 ms_message("Receiving REFER request !");
1788 if (comes_from_local_if(ev->request)) {
1789 process_refer(sal,NULL,ev);
1790 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1791 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1796 osip_message_to_str(ev->request,&tmp,&msglen);
1798 ms_message("Unsupported request received:\n%s",tmp);
1801 /*answer with a 501 Not implemented*/
1802 eXosip_message_send_answer(ev->tid,501,NULL);
1806 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1807 osip_via_t *via=NULL;
1808 osip_message_get_via(msg,0,&via);
1810 osip_free(via->port);
1811 via->port=osip_strdup(port);
1812 osip_free(via->host);
1813 via->host=osip_strdup(ip);
1818 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1819 osip_contact_t *ctt=NULL;
1820 const char *received;
1822 SalTransport transport;
1825 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1826 osip_message_get_contact(request,0,&ctt);
1828 ms_warning("fix_message_contact(): no contact to update");
1831 if (expire_last_contact){
1832 osip_contact_t *oldct=NULL,*prevct;
1833 osip_generic_param_t *param=NULL;
1834 osip_contact_clone(ctt,&oldct);
1835 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1836 osip_contact_free(prevct);
1837 osip_list_remove(&request->contacts,1);
1839 osip_list_add(&request->contacts,oldct,1);
1840 osip_contact_param_get_byname(oldct,"expires",¶m);
1842 if (param->gvalue) osip_free(param->gvalue);
1843 param->gvalue=osip_strdup("0");
1845 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1848 if (ctt->url->host!=NULL){
1849 osip_free(ctt->url->host);
1851 ctt->url->host=osip_strdup(received);
1852 if (ctt->url->port!=NULL){
1853 osip_free(ctt->url->port);
1855 snprintf(port,sizeof(port),"%i",rport);
1856 ctt->url->port=osip_strdup(port);
1857 if (op->masquerade_via) masquerade_via(request,received,port);
1859 if (transport != SalTransportUDP) {
1860 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1865 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1866 osip_contact_t *ctt=NULL;
1867 SalAddress* ori_contact_address=NULL;
1868 const char *received;
1870 SalTransport transport;
1872 osip_message_t *msg=NULL;
1873 Sal* sal=op->base.root;
1875 bool_t found_valid_contact=FALSE;
1876 bool_t from_request=FALSE;
1878 if (sal->double_reg==FALSE ) return FALSE;
1880 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1883 osip_message_get_contact(last_answer,i,&ctt);
1884 if (!from_request && ctt==NULL) {
1885 osip_message_get_contact(orig_request,0,&ctt);
1889 osip_contact_to_str(ctt,&tmp);
1890 ori_contact_address = sal_address_new(tmp);
1892 /*check if contact is up to date*/
1893 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1894 && sal_address_get_port_int(ori_contact_address) == rport
1895 && sal_address_get_transport(ori_contact_address) == transport) {
1897 ms_message("Register response has up to date contact, doing nothing.");
1899 ms_warning("Register response does not have up to date contact, but last request had."
1900 "Stupid registrar detected, giving up.");
1902 found_valid_contact=TRUE;
1905 sal_address_destroy(ori_contact_address);
1908 }while(!found_valid_contact);
1909 if (!found_valid_contact)
1910 ms_message("Contact do not match, resending register.");
1914 eXosip_register_build_register(op->rid,op->expires,&msg);
1917 ms_warning("Fail to create a contact updated register.");
1920 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1921 eXosip_register_send_register(op->rid,msg);
1923 ms_message("Resending new register with updated contact");
1924 update_contact_from_response(op,last_answer);
1927 ms_warning("Fail to send updated register.");
1935 static void registration_success(Sal *sal, eXosip_event_t *ev){
1936 SalOp *op=sal_find_register(sal,ev->rid);
1937 osip_header_t *h=NULL;
1940 ms_error("Receiving register response for unknown operation");
1943 osip_message_get_expires(ev->request,0,&h);
1944 if (h!=NULL && atoi(h->hvalue)!=0){
1946 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1947 sal->callbacks.register_success(op,registered);
1950 sal->callbacks.register_success(op,FALSE);
1954 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1956 const char *reason=NULL;
1957 SalOp *op=sal_find_register(sal,ev->rid);
1958 SalReason sr=SalReasonUnknown;
1959 SalError se=SalErrorUnknown;
1962 ms_error("Receiving register failure for unknown operation");
1966 status_code=osip_message_get_status_code(ev->response);
1967 reason=osip_message_get_reason_phrase(ev->response);
1969 switch(status_code){
1972 return process_authentication(sal,ev);
1974 case 423: /*interval too brief*/
1975 {/*retry with greater interval */
1976 osip_header_t *h=NULL;
1977 osip_message_t *msg=NULL;
1978 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1979 if (h && h->hvalue && h->hvalue[0]!='\0'){
1980 int val=atoi(h->hvalue);
1981 if (val>op->expires)
1983 }else op->expires*=2;
1985 eXosip_register_build_register(op->rid,op->expires,&msg);
1986 eXosip_register_send_register(op->rid,msg);
1990 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1991 in vias, such as ekiga.net
1992 On the opposite, freephonie.net bugs when via are masqueraded.
1994 op->masquerade_via=TRUE;
1996 /* if contact is up to date, process the failure, otherwise resend a new register with
1997 updated contact first, just in case the faillure is due to incorrect contact */
1998 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1999 return TRUE; /*we are retrying with an updated contact*/
2000 if (status_code==403){
2002 sr=SalReasonForbidden;
2003 }else if (status_code==0){
2004 se=SalErrorNoResponse;
2006 sal->callbacks.register_failure(op,se,sr,reason);
2011 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2012 SalOp *op=find_op(sal,ev);
2014 ms_warning("other_request_reply(): Receiving response to unknown request.");
2018 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2019 update_contact_from_response(op,ev->response);
2020 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2021 sal->callbacks.ping_reply(op);
2023 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2024 /*out of call message acknolegment*/
2025 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2027 if (ev->response->status_code<200){
2028 status=SalTextDeliveryInProgress;
2029 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2030 status=SalTextDeliveryDone;
2033 sal->callbacks.text_delivery_update(op,status);
2037 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2038 SalOp *op=find_op(sal,ev);
2040 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2041 if (op->sipfrag_pending){
2042 send_notify_for_refer(op->did,op->sipfrag_pending);
2043 op->sipfrag_pending=NULL;
2049 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2050 ms_message("linphone process event get a message %d\n",ev->type);
2052 case EXOSIP_CALL_ANSWERED:
2053 ms_message("CALL_ANSWERED\n");
2054 call_accepted(sal,ev);
2055 authentication_ok(sal,ev);
2057 case EXOSIP_CALL_CLOSED:
2058 case EXOSIP_CALL_CANCELLED:
2059 ms_message("CALL_CLOSED or CANCELLED\n");
2060 call_terminated(sal,ev);
2062 case EXOSIP_CALL_TIMEOUT:
2063 case EXOSIP_CALL_NOANSWER:
2064 ms_message("CALL_TIMEOUT or NOANSWER\n");
2065 return call_failure(sal,ev);
2067 case EXOSIP_CALL_REQUESTFAILURE:
2068 case EXOSIP_CALL_GLOBALFAILURE:
2069 case EXOSIP_CALL_SERVERFAILURE:
2070 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2071 return call_failure(sal,ev);
2073 case EXOSIP_CALL_RELEASED:
2074 ms_message("CALL_RELEASED\n");
2075 call_released(sal, ev);
2077 case EXOSIP_CALL_INVITE:
2078 ms_message("CALL_NEW\n");
2079 inc_new_call(sal,ev);
2081 case EXOSIP_CALL_REINVITE:
2082 handle_reinvite(sal,ev);
2084 case EXOSIP_CALL_ACK:
2085 ms_message("CALL_ACK");
2088 case EXOSIP_CALL_REDIRECTED:
2089 ms_message("CALL_REDIRECTED");
2090 eXosip_default_action(ev);
2092 case EXOSIP_CALL_PROCEEDING:
2093 ms_message("CALL_PROCEEDING");
2094 call_proceeding(sal,ev);
2096 case EXOSIP_CALL_RINGING:
2097 ms_message("CALL_RINGING");
2098 call_ringing(sal,ev);
2099 authentication_ok(sal,ev);
2101 case EXOSIP_CALL_MESSAGE_NEW:
2102 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2103 call_message_new(sal,ev);
2105 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2107 (ev->response->status_code==407 || ev->response->status_code==401)){
2108 return process_authentication(sal,ev);
2111 case EXOSIP_CALL_MESSAGE_ANSWERED:
2112 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2113 process_in_call_reply(sal,ev);
2115 case EXOSIP_IN_SUBSCRIPTION_NEW:
2116 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2117 sal_exosip_subscription_recv(sal,ev);
2119 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2120 ms_message("CALL_SUBSCRIPTION_NEW ");
2121 sal_exosip_in_subscription_closed(sal,ev);
2123 case EXOSIP_SUBSCRIPTION_UPDATE:
2124 ms_message("CALL_SUBSCRIPTION_UPDATE");
2126 case EXOSIP_SUBSCRIPTION_NOTIFY:
2127 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2128 sal_exosip_notify_recv(sal,ev);
2130 case EXOSIP_SUBSCRIPTION_ANSWERED:
2131 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2132 sal_exosip_subscription_answered(sal,ev);
2134 case EXOSIP_SUBSCRIPTION_CLOSED:
2135 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2136 sal_exosip_subscription_closed(sal,ev);
2138 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2139 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2140 return process_authentication(sal,ev);
2142 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2143 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2144 sal_exosip_subscription_closed(sal,ev);
2146 case EXOSIP_REGISTRATION_FAILURE:
2147 ms_message("REGISTRATION_FAILURE\n");
2148 return registration_failure(sal,ev);
2150 case EXOSIP_REGISTRATION_SUCCESS:
2151 authentication_ok(sal,ev);
2152 registration_success(sal,ev);
2154 case EXOSIP_MESSAGE_NEW:
2155 other_request(sal,ev);
2157 case EXOSIP_MESSAGE_PROCEEDING:
2158 case EXOSIP_MESSAGE_ANSWERED:
2159 case EXOSIP_MESSAGE_REDIRECTED:
2160 case EXOSIP_MESSAGE_SERVERFAILURE:
2161 case EXOSIP_MESSAGE_GLOBALFAILURE:
2162 other_request_reply(sal,ev);
2164 case EXOSIP_MESSAGE_REQUESTFAILURE:
2165 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2167 switch (ev->response->status_code) {
2170 return process_authentication(sal,ev);
2172 eXosip_automatic_action ();
2177 other_request_reply(sal,ev);
2180 ms_message("Unhandled exosip event ! %i",ev->type);
2186 int sal_iterate(Sal *sal){
2188 while((ev=eXosip_event_wait(0,0))!=NULL){
2189 if (process_event(sal,ev))
2190 eXosip_event_free(ev);
2192 #ifdef HAVE_EXOSIP_TRYLOCK
2193 if (eXosip_trylock()==0){
2194 eXosip_automatic_refresh();
2197 ms_warning("eXosip_trylock busy.");
2201 eXosip_automatic_refresh();
2207 static void register_set_contact(osip_message_t *msg, const char *contact){
2208 osip_uri_param_t *param = NULL;
2209 osip_contact_t *ct=NULL;
2211 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2212 osip_message_get_contact(msg,0,&ct);
2214 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2215 if (param && param->gvalue)
2216 line=osip_strdup(param->gvalue);
2218 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2219 osip_message_set_contact(msg,contact);
2220 osip_message_get_contact(msg,0,&ct);
2221 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2224 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2226 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2228 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2229 osip_message_set_route(msg,tmp);
2233 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2234 osip_message_t *msg;
2235 const char *contact=sal_op_get_contact(h);
2237 sal_op_set_route(h,proxy);
2239 SalAddress *from_parsed=sal_address_new(from);
2241 char *uri, *domain_ptr = NULL;
2242 if (from_parsed==NULL) {
2243 ms_warning("sal_register() bad from %s",from);
2246 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2247 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2248 uri = sal_address_as_string_uri_only(from_parsed);
2249 if (uri) domain_ptr = strchr(uri, '@');
2251 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2253 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2255 if (uri) ms_free(uri);
2256 sal_address_destroy(from_parsed);
2258 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2260 if (contact) register_set_contact(msg,contact);
2261 sal_register_add_route(msg,proxy);
2262 sal_add_register(h->base.root,h);
2264 ms_error("Could not build initial register.");
2270 eXosip_register_build_register(h->rid,expires,&msg);
2271 sal_register_add_route(msg,proxy);
2274 eXosip_register_send_register(h->rid,msg);
2278 return (msg != NULL) ? 0 : -1;
2281 int sal_register_refresh(SalOp *op, int expires){
2282 osip_message_t *msg=NULL;
2283 const char *contact=sal_op_get_contact(op);
2286 ms_error("Unexistant registration context, not possible to refresh.");
2289 #ifdef HAVE_EXOSIP_TRYLOCK
2292 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2293 * 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
2294 * the exosip lock in a non blocking way, and give up if it takes too long*/
2295 while (eXosip_trylock()!=0){
2297 if (tries>30) {/*after 3 seconds, give up*/
2298 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2306 eXosip_register_build_register(op->rid,expires,&msg);
2308 if (contact) register_set_contact(msg,contact);
2309 sal_register_add_route(msg,sal_op_get_route(op));
2310 eXosip_register_send_register(op->rid,msg);
2311 }else ms_error("Could not build REGISTER refresh message.");
2313 return (msg != NULL) ? 0 : -1;
2317 int sal_unregister(SalOp *h){
2318 osip_message_t *msg=NULL;
2320 eXosip_register_build_register(h->rid,0,&msg);
2321 if (msg) eXosip_register_send_register(h->rid,msg);
2322 else ms_warning("Could not build unREGISTER !");
2327 SalAddress * sal_address_new(const char *uri){
2329 osip_from_init(&from);
2331 // Remove front spaces
2332 while (uri[0]==' ') {
2336 if (osip_from_parse(from,uri)!=0){
2337 osip_from_free(from);
2340 if (from->displayname!=NULL && from->displayname[0]=='"'){
2341 char *unquoted=osip_strdup_without_quote(from->displayname);
2342 osip_free(from->displayname);
2343 from->displayname=unquoted;
2345 return (SalAddress*)from;
2348 SalAddress * sal_address_clone(const SalAddress *addr){
2349 osip_from_t *ret=NULL;
2350 osip_from_clone((osip_from_t*)addr,&ret);
2351 return (SalAddress*)ret;
2354 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2356 const char *sal_address_get_scheme(const SalAddress *addr){
2357 const osip_from_t *u=(const osip_from_t*)addr;
2358 return null_if_empty(u->url->scheme);
2361 const char *sal_address_get_display_name(const SalAddress* addr){
2362 const osip_from_t *u=(const osip_from_t*)addr;
2363 return null_if_empty(u->displayname);
2366 const char *sal_address_get_username(const SalAddress *addr){
2367 const osip_from_t *u=(const osip_from_t*)addr;
2368 return null_if_empty(u->url->username);
2371 const char *sal_address_get_domain(const SalAddress *addr){
2372 const osip_from_t *u=(const osip_from_t*)addr;
2373 return null_if_empty(u->url->host);
2376 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2377 osip_from_t *u=(osip_from_t*)addr;
2378 if (u->displayname!=NULL){
2379 osip_free(u->displayname);
2380 u->displayname=NULL;
2382 if (display_name!=NULL && display_name[0]!='\0'){
2383 u->displayname=osip_strdup(display_name);
2387 void sal_address_set_username(SalAddress *addr, const char *username){
2388 osip_from_t *uri=(osip_from_t*)addr;
2389 if (uri->url->username!=NULL){
2390 osip_free(uri->url->username);
2391 uri->url->username=NULL;
2394 uri->url->username=osip_strdup(username);
2397 void sal_address_set_domain(SalAddress *addr, const char *host){
2398 osip_from_t *uri=(osip_from_t*)addr;
2399 if (uri->url->host!=NULL){
2400 osip_free(uri->url->host);
2401 uri->url->host=NULL;
2404 uri->url->host=osip_strdup(host);
2407 void sal_address_set_port(SalAddress *addr, const char *port){
2408 osip_from_t *uri=(osip_from_t*)addr;
2409 if (uri->url->port!=NULL){
2410 osip_free(uri->url->port);
2411 uri->url->port=NULL;
2414 uri->url->port=osip_strdup(port);
2417 void sal_address_set_port_int(SalAddress *uri, int port){
2420 /*this is the default, special case to leave the port field blank*/
2421 sal_address_set_port(uri,NULL);
2424 snprintf(tmp,sizeof(tmp),"%i",port);
2425 sal_address_set_port(uri,tmp);
2428 void sal_address_clean(SalAddress *addr){
2429 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2430 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2433 char *sal_address_as_string(const SalAddress *u){
2435 osip_from_t *from=(osip_from_t *)u;
2436 char *old_displayname=NULL;
2437 /* hack to force use of quotes around the displayname*/
2438 if (from->displayname!=NULL
2439 && from->displayname[0]!='"'){
2440 old_displayname=from->displayname;
2441 from->displayname=osip_enquote(from->displayname);
2443 osip_from_to_str(from,&tmp);
2444 if (old_displayname!=NULL){
2445 ms_free(from->displayname);
2446 from->displayname=old_displayname;
2453 char *sal_address_as_string_uri_only(const SalAddress *u){
2454 char *tmp=NULL,*ret;
2455 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2460 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2461 osip_uri_param_t *param=NULL;
2462 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2464 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2466 osip_free(param->gvalue);
2467 param->gvalue=value ? osip_strdup(value) : NULL;
2472 void sal_address_destroy(SalAddress *u){
2473 osip_from_free((osip_from_t*)u);
2476 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2477 ctx->keepalive_period=value;
2478 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2480 unsigned int sal_get_keepalive_period(Sal *ctx) {
2481 return ctx->keepalive_period;
2484 const char * sal_address_get_port(const SalAddress *addr) {
2485 const osip_from_t *u=(const osip_from_t*)addr;
2486 return null_if_empty(u->url->port);
2489 int sal_address_get_port_int(const SalAddress *uri) {
2490 const char* port = sal_address_get_port(uri);
2497 SalTransport sal_address_get_transport(const SalAddress* addr) {
2498 const osip_from_t *u=(const osip_from_t*)addr;
2499 osip_uri_param_t *transport_param=NULL;
2500 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2501 if (transport_param == NULL){
2502 return SalTransportUDP;
2504 return sal_transport_parse(transport_param->gvalue);
2507 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2508 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2511 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2512 int sal_call_update(SalOp *h, const char *subject){
2514 osip_message_t *reinvite=NULL;
2517 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2522 osip_message_set_subject(reinvite,subject);
2523 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2524 if (h->base.contact){
2525 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2526 osip_message_set_contact(reinvite,h->base.contact);
2528 if (h->base.root->session_expires!=0){
2529 osip_message_set_header(reinvite, "Session-expires", "200");
2530 osip_message_set_supported(reinvite, "timer");
2532 if (h->base.local_media){
2533 h->sdp_offering=TRUE;
2534 set_sdp_from_desc(reinvite,h->base.local_media);
2535 }else h->sdp_offering=FALSE;
2537 err = eXosip_call_send_request(h->did, reinvite);
2541 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2542 ctx->reuse_authorization=value;