3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "sal_eXosip2.h"
24 #include "offeranswer.h"
27 // Necessary to make it linked
28 static void for_linker() { eXosip_transport_hook_register(NULL); }
30 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
32 static void text_received(Sal *sal, eXosip_event_t *ev);
34 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
35 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact);
36 static void update_contact_from_response(SalOp *op, osip_message_t *response);
38 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
40 while(!osip_list_eol(l,0)) {
41 data=osip_list_get(l,0);
42 osip_list_remove(l,0);
43 if (data) freefunc(data);
47 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
48 if (eXosip_guess_localip(address_family,ip,iplen)<0){
49 /*default to something */
50 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
51 ms_error("Could not find default routable ip address !");
56 static SalOp * sal_find_call(Sal *sal, int cid){
59 for(elem=sal->calls;elem!=NULL;elem=elem->next){
60 op=(SalOp*)elem->data;
61 if (op->cid==cid) return op;
66 static void sal_add_call(Sal *sal, SalOp *op){
67 sal->calls=ms_list_append(sal->calls,op);
70 static void sal_remove_call(Sal *sal, SalOp *op){
71 sal->calls=ms_list_remove(sal->calls, op);
74 static SalOp * sal_find_register(Sal *sal, int rid){
77 for(elem=sal->registers;elem!=NULL;elem=elem->next){
78 op=(SalOp*)elem->data;
79 if (op->rid==rid) return op;
84 static void sal_add_register(Sal *sal, SalOp *op){
85 sal->registers=ms_list_append(sal->registers,op);
88 static void sal_remove_register(Sal *sal, int rid){
91 for(elem=sal->registers;elem!=NULL;elem=elem->next){
92 op=(SalOp*)elem->data;
94 sal->registers=ms_list_remove_link(sal->registers,elem);
100 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
103 osip_call_id_t *callid=osip_message_get_call_id(message);
105 ms_error("There is no call-id in this message !");
108 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
109 op=(SalOp*)elem->data;
110 if (osip_call_id_match(callid,op->call_id)==0) return op;
115 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
116 osip_call_id_t *callid=osip_message_get_call_id(request);
118 ms_error("There is no call id in the request !");
121 osip_call_id_clone(callid,&op->call_id);
122 sal->other_transactions=ms_list_append(sal->other_transactions,op);
125 static void sal_remove_other(Sal *sal, SalOp *op){
126 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
130 static void sal_add_pending_auth(Sal *sal, SalOp *op){
131 sal->pending_auths=ms_list_append(sal->pending_auths,op);
135 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
136 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
139 void sal_exosip_fix_route(SalOp *op){
140 if (sal_op_get_route(op)!=NULL){
141 osip_route_t *rt=NULL;
142 osip_uri_param_t *lr_param=NULL;
144 osip_route_init(&rt);
145 if (osip_route_parse(rt,sal_op_get_route(op))<0){
146 ms_warning("Bad route %s!",sal_op_get_route(op));
147 sal_op_set_route(op,NULL);
149 /* check if the lr parameter is set , if not add it */
150 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
153 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
154 osip_route_to_str(rt,&tmproute);
155 sal_op_set_route(op,tmproute);
163 SalOp * sal_op_new(Sal *sal){
164 SalOp *op=ms_new0(SalOp,1);
165 __sal_op_init(op,sal);
166 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
168 op->supports_session_timers=FALSE;
169 op->sdp_offering=TRUE;
170 op->pending_auth=NULL;
175 op->referred_by=NULL;
176 op->masquerade_via=FALSE;
177 op->auto_answer_asked=FALSE;
179 op->terminated=FALSE;
183 bool_t sal_call_autoanswer_asked(SalOp *op)
185 return op->auto_answer_asked;
188 void sal_op_release(SalOp *op){
190 sdp_message_free(op->sdp_answer);
191 if (op->pending_auth)
192 eXosip_event_free(op->pending_auth);
194 sal_remove_register(op->base.root,op->rid);
195 eXosip_register_remove(op->rid);
198 ms_message("Cleaning cid %i",op->cid);
199 sal_remove_call(op->base.root,op);
202 sal_remove_out_subscribe(op->base.root,op);
205 sal_remove_in_subscribe(op->base.root,op);
207 osip_call_id_free(op->call_id);
210 if (op->pending_auth){
211 sal_remove_pending_auth(op->base.root,op);
214 sal_media_description_unref(op->result);
216 sal_remove_other(op->base.root,op);
217 osip_call_id_free(op->call_id);
220 ms_free(op->replaces);
222 if (op->referred_by){
223 ms_free(op->referred_by);
226 sal_auth_info_delete(op->auth_info);
231 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
232 int ortp_level=ORTP_DEBUG;
238 ortp_level=ORTP_MESSAGE;
241 ortp_level=ORTP_WARNING;
245 ortp_level=ORTP_ERROR;
248 ortp_level=ORTP_FATAL;
250 case END_TRACE_LEVEL:
253 if (ortp_log_level_enabled(level)){
254 int len=strlen(chfr);
255 char *chfrdup=ortp_strdup(chfr);
256 /*need to remove endline*/
258 if (chfrdup[len-1]=='\n')
260 if (chfrdup[len-2]=='\r')
263 ortp_logv(ortp_level,chfrdup,ap);
270 static bool_t firsttime=TRUE;
273 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
278 sal->keepalive_period=30;
279 sal->double_reg=TRUE;
280 sal->use_rports=TRUE;
282 sal->reuse_authorization=FALSE;
284 sal->verify_server_certs=TRUE;
285 sal->expire_old_contact=FALSE;
286 sal->add_dates=FALSE;
291 void sal_uninit(Sal* sal){
294 ms_free(sal->rootCa);
298 void sal_set_user_pointer(Sal *sal, void *user_data){
302 void *sal_get_user_pointer(const Sal *sal){
306 static void unimplemented_stub(){
307 ms_warning("Unimplemented SAL callback");
310 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
311 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
312 if (ctx->callbacks.call_received==NULL)
313 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
314 if (ctx->callbacks.call_ringing==NULL)
315 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
316 if (ctx->callbacks.call_accepted==NULL)
317 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
318 if (ctx->callbacks.call_failure==NULL)
319 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
320 if (ctx->callbacks.call_terminated==NULL)
321 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
322 if (ctx->callbacks.call_released==NULL)
323 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
324 if (ctx->callbacks.call_updating==NULL)
325 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
326 if (ctx->callbacks.auth_requested==NULL)
327 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
328 if (ctx->callbacks.auth_success==NULL)
329 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
330 if (ctx->callbacks.register_success==NULL)
331 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
332 if (ctx->callbacks.register_failure==NULL)
333 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
334 if (ctx->callbacks.dtmf_received==NULL)
335 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
336 if (ctx->callbacks.notify==NULL)
337 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
338 if (ctx->callbacks.notify_presence==NULL)
339 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
340 if (ctx->callbacks.subscribe_received==NULL)
341 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
342 if (ctx->callbacks.text_received==NULL)
343 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
344 if (ctx->callbacks.ping_reply==NULL)
345 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
348 int sal_unlisten_ports(Sal *ctx){
357 int sal_reset_transports(Sal *ctx){
358 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
360 ms_message("Exosip transports reset.");
361 eXosip_reset_transports();
365 ms_warning("sal_reset_transports() not implemented in this version.");
371 static void set_tls_options(Sal *ctx){
373 eXosip_tls_ctx_t tlsCtx;
374 memset(&tlsCtx, 0, sizeof(tlsCtx));
375 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
376 eXosip_set_tls_ctx(&tlsCtx);
378 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
379 eXosip_tls_verify_certificate(ctx->verify_server_certs);
383 void sal_set_dscp(Sal *ctx, int dscp){
385 #ifdef HAVE_EXOSIP_DSCP
387 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 const char *sal_get_root_ca(Sal* ctx) {
495 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
496 ctx->verify_server_certs=verify;
497 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
498 eXosip_tls_verify_certificate(verify);
502 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
503 osip_via_t *via=NULL;
504 osip_generic_param_t *param=NULL;
505 const char *rport=NULL;
509 osip_message_get_via(msg,0,&via);
511 ms_warning("extract_received_rport(): no via.");
515 *transport = sal_transport_parse(via->protocol);
517 if (via->port && via->port[0]!='\0')
518 *rportval=atoi(via->port);
520 osip_via_param_get_byname(via,"rport",¶m);
523 if (rport && rport[0]!='\0') *rportval=atoi(rport);
527 osip_via_param_get_byname(via,"received",¶m);
528 if (param) *received=param->gvalue;
530 if (rport==NULL && *received==NULL){
531 ms_warning("extract_received_rport(): no rport and no received parameters.");
537 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
541 sdp_message_to_str(msg,&sdp);
543 snprintf(clen,sizeof(clen),"%i",sdplen);
544 osip_message_set_body(sip,sdp,sdplen);
545 osip_message_set_content_type(sip,"application/sdp");
546 osip_message_set_content_length(sip,clen);
550 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
551 sdp_message_t *msg=media_description_to_sdp(desc);
553 ms_error("Fail to print sdp message !");
557 sdp_message_free(msg);
560 static void sdp_process(SalOp *h){
561 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
563 sal_media_description_unref(h->result);
565 h->result=sal_media_description_new();
566 if (h->sdp_offering){
567 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
571 sdp_message_free(h->sdp_answer);
573 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
574 h->sdp_answer=media_description_to_sdp(h->result);
575 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
576 It should contains media parameters constraint from the remote offer, not our response*/
577 strcpy(h->result->addr,h->base.remote_media->addr);
578 h->result->bandwidth=h->base.remote_media->bandwidth;
580 for(i=0;i<h->result->nstreams;++i){
581 if (h->result->streams[i].rtp_port>0){
582 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
583 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
584 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
585 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
586 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
587 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
589 if (h->result->streams[i].proto == SalProtoRtpSavp) {
590 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
598 int sal_call_is_offerer(const SalOp *h){
599 return h->sdp_offering;
602 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
604 sal_media_description_ref(desc);
605 if (h->base.local_media)
606 sal_media_description_unref(h->base.local_media);
607 h->base.local_media=desc;
608 if (h->base.remote_media){
609 /*case of an incoming call where we modify the local capabilities between the time
610 * the call is ringing and it is accepted (for example if you want to accept without video*/
611 /*reset the sdp answer so that it is computed again*/
613 sdp_message_free(h->sdp_answer);
620 int sal_call(SalOp *h, const char *from, const char *to){
623 osip_message_t *invite=NULL;
624 osip_call_id_t *callid;
625 sal_op_set_from(h,from);
627 sal_exosip_fix_route(h);
629 h->terminated = FALSE;
631 route = sal_op_get_route(h);
632 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
634 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
635 err, from, to, route);
638 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
639 if (h->base.contact){
640 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
641 osip_message_set_contact(invite,h->base.contact);
643 if (h->base.root->session_expires!=0){
644 osip_message_set_header(invite, "Session-expires", "200");
645 osip_message_set_supported(invite, "timer");
647 if (h->base.local_media){
648 h->sdp_offering=TRUE;
649 set_sdp_from_desc(invite,h->base.local_media);
650 }else h->sdp_offering=FALSE;
652 osip_message_set_header(invite,"Replaces",h->replaces);
654 osip_message_set_header(invite,"Referred-By",h->referred_by);
658 err=eXosip_call_send_initial_invite(invite);
662 ms_error("Fail to send invite ! Error code %d", err);
665 callid=osip_message_get_call_id(invite);
666 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
667 sal_add_call(h->base.root,h);
672 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
675 /*if early media send also 180 and 183 */
679 eXosip_call_build_answer(h->tid,183,&msg);
683 set_sdp(msg,h->sdp_answer);
684 sdp_message_free(h->sdp_answer);
687 eXosip_call_send_answer(h->tid,183,msg);
692 eXosip_call_send_answer(h->tid,180,NULL);
698 int sal_call_accept(SalOp * h){
700 const char *contact=sal_op_get_contact(h);
702 int err=eXosip_call_build_answer(h->tid,200,&msg);
703 if (err<0 || msg==NULL){
704 ms_error("Fail to build answer for call: err=%i",err);
707 if (h->base.root->session_expires!=0){
708 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
712 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
713 osip_message_set_contact(msg,contact);
716 if (h->base.local_media){
717 /*this is the case where we received an invite without SDP*/
718 if (h->sdp_offering) {
719 set_sdp_from_desc(msg,h->base.local_media);
721 if (h->sdp_answer==NULL) sdp_process(h);
723 set_sdp(msg,h->sdp_answer);
724 sdp_message_free(h->sdp_answer);
729 ms_error("You are accepting a call but not defined any media capabilities !");
731 eXosip_call_send_answer(h->tid,200,msg);
735 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
736 if (reason==SalReasonBusy){
738 eXosip_call_send_answer(h->tid,486,NULL);
741 else if (reason==SalReasonTemporarilyUnavailable){
743 eXosip_call_send_answer(h->tid,480,NULL);
745 }else if (reason==SalReasonDoNotDisturb){
747 eXosip_call_send_answer(h->tid,600,NULL);
749 }else if (reason==SalReasonMedia){
751 eXosip_call_send_answer(h->tid,415,NULL);
753 }else if (redirect!=NULL && reason==SalReasonRedirect){
756 if (strstr(redirect,"sip:")!=0) code=302;
759 eXosip_call_build_answer(h->tid,code,&msg);
760 osip_message_set_contact(msg,redirect);
761 eXosip_call_send_answer(h->tid,code,msg);
763 }else sal_call_terminate(h);
767 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
768 return h->base.remote_media;
771 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
772 if (h->base.local_media && h->base.remote_media && !h->result){
778 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
779 if (refered_call->replaces)
780 h->replaces=ms_strdup(refered_call->replaces);
781 if (refered_call->referred_by)
782 h->referred_by=ms_strdup(refered_call->referred_by);
786 static int send_notify_for_refer(int did, const char *sipfrag){
789 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
792 ms_warning("Could not build NOTIFY for refer.");
795 osip_message_set_content_type(msg,"message/sipfrag");
796 osip_message_set_header(msg,"Event","refer");
797 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
798 eXosip_call_send_request(did,msg);
803 /* currently only support to notify trying and 200Ok*/
804 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
807 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
809 else if (newcall->cid!=-1){
810 if (newcall->did==-1){
811 /* not yet established*/
812 if (!newcall->terminated){
814 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
817 if (!newcall->terminated){
818 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
819 /* we need previous notify transaction to complete, so buffer the request for later*/
820 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
828 int sal_ping(SalOp *op, const char *from, const char *to){
829 osip_message_t *options=NULL;
831 sal_op_set_from(op,from);
832 sal_op_set_to(op,to);
833 sal_exosip_fix_route(op);
835 eXosip_options_build_request (&options, sal_op_get_to(op),
836 sal_op_get_from(op),sal_op_get_route(op));
838 if (op->base.root->session_expires!=0){
839 osip_message_set_header(options, "Session-expires", "200");
840 osip_message_set_supported(options, "timer");
842 sal_add_other(sal_op_get_sal(op),op,options);
843 return eXosip_options_send_request(options);
848 int sal_call_refer(SalOp *h, const char *refer_to){
849 osip_message_t *msg=NULL;
852 eXosip_call_build_refer(h->did,refer_to, &msg);
853 if (msg) err=eXosip_call_send_request(h->did, msg);
859 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
860 osip_message_t *msg=NULL;
861 char referto[256]={0};
864 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
865 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
869 eXosip_call_build_refer(h->did,referto, &msg);
870 osip_message_set_header(msg,"Referred-By",h->base.from);
871 if (msg) err=eXosip_call_send_request(h->did, msg);
877 SalOp *sal_call_get_replaces(SalOp *h){
878 if (h!=NULL && h->replaces!=NULL){
881 cid=eXosip_call_find_by_replaces(h->replaces);
884 SalOp *ret=sal_find_call(h->base.root,cid);
891 int sal_call_send_dtmf(SalOp *h, char dtmf){
892 osip_message_t *msg=NULL;
897 eXosip_call_build_info(h->did,&msg);
899 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
900 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
901 osip_message_set_content_type(msg,"application/dtmf-relay");
902 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
903 osip_message_set_content_length(msg,clen);
904 eXosip_call_send_request(h->did,msg);
910 static void push_auth_to_exosip(const SalAuthInfo *info){
912 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
913 else userid=info->userid;
914 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
915 eXosip_add_authentication_info (info->username,userid,
916 info->password, NULL,info->realm);
919 * Just for symmetry ;-)
921 static void pop_auth_from_exosip() {
922 eXosip_clear_authentication_info();
925 int sal_call_terminate(SalOp *h){
927 if (h == NULL) return -1;
928 if (h->auth_info) push_auth_to_exosip(h->auth_info);
930 err=eXosip_call_terminate(h->cid,h->did);
932 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
934 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
940 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
941 if (h->terminated) return;
942 if (h->pending_auth){
943 push_auth_to_exosip(info);
945 /*FIXME exosip does not take into account this update register message*/
947 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
951 update_contact_from_response(h,h->pending_auth->response);
953 eXosip_default_action(h->pending_auth);
955 ms_message("eXosip_default_action() done");
956 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
958 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
959 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
962 void sal_op_cancel_authentication(SalOp *h) {
964 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
965 } else if (h->cid >0) {
966 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
968 ms_warning("Auth failure not handled");
972 static void set_network_origin(SalOp *op, osip_message_t *req){
973 const char *received=NULL;
976 SalTransport transport;
977 if (extract_received_rport(req,&received,&rport,&transport)!=0){
978 osip_via_t *via=NULL;
980 osip_message_get_via(req,0,&via);
981 received=osip_via_get_host(via);
982 tmp=osip_via_get_port(via);
983 if (tmp) rport=atoi(tmp);
985 if (transport != SalTransportUDP) {
986 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
988 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
990 __sal_op_set_network_origin(op,origin);
993 static void set_remote_ua(SalOp* op, osip_message_t *req){
994 if (op->base.remote_ua==NULL){
995 osip_header_t *h=NULL;
996 osip_message_get_user_agent(req,0,&h);
998 op->base.remote_ua=ms_strdup(h->hvalue);
1003 static void set_replaces(SalOp *op, osip_message_t *req){
1004 osip_header_t *h=NULL;
1007 ms_free(op->replaces);
1010 osip_message_header_get_byname(req,"replaces",0,&h);
1012 if (h->hvalue && h->hvalue[0]!='\0'){
1013 op->replaces=ms_strdup(h->hvalue);
1018 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1020 return sal_find_call(sal,ev->cid);
1023 return sal_find_register(sal,ev->rid);
1026 return sal_find_out_subscribe(sal,ev->sid);
1029 return sal_find_in_subscribe(sal,ev->nid);
1031 if (ev->response) return sal_find_other(sal,ev->response);
1032 else if (ev->request) return sal_find_other(sal,ev->request);
1036 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1037 SalOp *op=sal_op_new(sal);
1038 osip_from_t *from,*to;
1039 osip_call_info_t *call_info;
1041 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1042 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1043 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1045 set_network_origin(op,ev->request);
1046 set_remote_ua(op,ev->request);
1047 set_replaces(op,ev->request);
1050 op->sdp_offering=FALSE;
1051 op->base.remote_media=sal_media_description_new();
1052 sdp_to_media_description(sdp,op->base.remote_media);
1053 sdp_message_free(sdp);
1054 }else op->sdp_offering=TRUE;
1056 from=osip_message_get_from(ev->request);
1057 to=osip_message_get_to(ev->request);
1058 osip_from_to_str(from,&tmp);
1059 sal_op_set_from(op,tmp);
1061 osip_from_to_str(to,&tmp);
1062 sal_op_set_to(op,tmp);
1065 osip_message_get_call_info(ev->request,0,&call_info);
1068 osip_call_info_to_str(call_info,&tmp);
1069 if( strstr(tmp,"answer-after=") != NULL)
1071 op->auto_answer_asked=TRUE;
1072 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1080 sal_add_call(op->base.root,op);
1081 sal->callbacks.call_received(op);
1084 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1085 SalOp *op=find_op(sal,ev);
1089 ms_warning("Reinvite for non-existing operation !");
1094 sdp=eXosip_get_sdp_info(ev->request);
1095 if (op->base.remote_media){
1096 sal_media_description_unref(op->base.remote_media);
1097 op->base.remote_media=NULL;
1100 sal_media_description_unref(op->result);
1104 op->sdp_offering=FALSE;
1105 op->base.remote_media=sal_media_description_new();
1106 sdp_to_media_description(sdp,op->base.remote_media);
1107 sdp_message_free(sdp);
1110 op->sdp_offering=TRUE;
1112 sal->callbacks.call_updating(op);
1115 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1116 SalOp *op=find_op(sal,ev);
1120 ms_warning("ack for non-existing call !");
1123 if (op->terminated) {
1124 ms_warning("ack for terminated call, ignoring");
1128 if (op->sdp_offering){
1129 sdp=eXosip_get_sdp_info(ev->ack);
1131 if (op->base.remote_media)
1132 sal_media_description_unref(op->base.remote_media);
1133 op->base.remote_media=sal_media_description_new();
1134 sdp_to_media_description(sdp,op->base.remote_media);
1136 sdp_message_free(sdp);
1142 sal->callbacks.call_ack(op);
1145 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1146 const char *received;
1148 SalTransport transport;
1149 if (extract_received_rport(response,&received,&rport,&transport)==0){
1150 const char *contact=sal_op_get_contact(op);
1152 /*no contact given yet, use from instead*/
1153 contact=sal_op_get_from(op);
1156 SalAddress *addr=sal_address_new(contact);
1158 sal_address_set_domain(addr,received);
1159 sal_address_set_port_int(addr,rport);
1160 if (transport!=SalTransportUDP)
1161 sal_address_set_transport(addr,transport);
1162 tmp=sal_address_as_string(addr);
1163 ms_message("Contact address updated to %s",tmp);
1164 sal_op_set_contact(op,tmp);
1165 sal_address_destroy(addr);
1171 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1172 SalOp *op=find_op(sal,ev);
1174 if (op==NULL || op->terminated==TRUE) {
1175 ms_warning("This call has been canceled.");
1177 eXosip_call_terminate(ev->cid,ev->did);
1185 /* update contact if received and rport are set by the server
1186 note: will only be used by remote for next INVITE, if any...*/
1187 update_contact_from_response(op,ev->response);
1191 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1193 SalOp *op=find_op(sal,ev);
1194 if (call_proceeding(sal, ev)==-1) return;
1196 set_remote_ua(op,ev->response);
1197 sdp=eXosip_get_sdp_info(ev->response);
1199 op->base.remote_media=sal_media_description_new();
1200 sdp_to_media_description(sdp,op->base.remote_media);
1201 sdp_message_free(sdp);
1202 if (op->base.local_media) sdp_process(op);
1204 sal->callbacks.call_ringing(op);
1207 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1209 osip_message_t *msg=NULL;
1210 SalOp *op=find_op(sal,ev);
1211 const char *contact;
1213 if (op==NULL || op->terminated==TRUE) {
1214 ms_warning("This call has been already terminated.");
1216 eXosip_call_terminate(ev->cid,ev->did);
1222 set_remote_ua(op,ev->response);
1224 sdp=eXosip_get_sdp_info(ev->response);
1226 op->base.remote_media=sal_media_description_new();
1227 sdp_to_media_description(sdp,op->base.remote_media);
1228 sdp_message_free(sdp);
1229 if (op->base.local_media) sdp_process(op);
1231 eXosip_call_build_ack(ev->did,&msg);
1233 ms_warning("This call has been already terminated.");
1235 eXosip_call_terminate(ev->cid,ev->did);
1239 contact=sal_op_get_contact(op);
1241 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1242 osip_message_set_contact(msg,contact);
1244 if (op->sdp_answer){
1245 set_sdp(msg,op->sdp_answer);
1246 sdp_message_free(op->sdp_answer);
1247 op->sdp_answer=NULL;
1249 eXosip_call_send_ack(ev->did,msg);
1250 sal->callbacks.call_accepted(op);
1253 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1255 SalOp *op=find_op(sal,ev);
1257 ms_warning("Call terminated for already closed call ?");
1261 osip_from_to_str(ev->request->from,&from);
1263 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1264 if (from) osip_free(from);
1265 op->terminated=TRUE;
1268 static void call_released(Sal *sal, eXosip_event_t *ev){
1269 SalOp *op=find_op(sal,ev);
1271 ms_warning("No op associated to this call_released()");
1274 if (!op->terminated){
1275 /* no response received so far */
1276 call_failure(sal,ev);
1278 sal->callbacks.call_released(op);
1281 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1282 const char *prx_realm=NULL,*www_realm=NULL;
1283 osip_proxy_authenticate_t *prx_auth;
1284 osip_www_authenticate_t *www_auth;
1286 *username=osip_uri_get_username(resp->from->url);
1287 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1288 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1290 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1292 www_realm=osip_www_authenticate_get_realm(www_auth);
1296 }else if (www_realm){
1304 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1305 osip_authorization_t *auth=NULL;
1306 osip_proxy_authorization_t *prx_auth=NULL;
1308 *username=osip_uri_get_username(msg->from->url);
1309 osip_message_get_authorization(msg, 0, &auth);
1311 *realm=osip_authorization_get_realm(auth);
1314 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1316 *realm=osip_proxy_authorization_get_realm(prx_auth);
1322 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1323 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1324 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1328 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1329 if (op->pending_auth){
1330 return get_auth_data(op->pending_auth,realm,username);
1335 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1337 const char *username,*realm;
1340 ms_warning("No operation associated with this authentication !");
1343 if (get_auth_data(ev,&realm,&username)==0){
1344 if (op->pending_auth!=NULL){
1345 eXosip_event_free(op->pending_auth);
1346 op->pending_auth=ev;
1348 op->pending_auth=ev;
1349 sal_add_pending_auth(sal,op);
1352 sal->callbacks.auth_requested(op,realm,username);
1358 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1360 const char *username,*realm;
1363 ms_warning("No operation associated with this authentication_ok!");
1366 if (op->pending_auth){
1367 eXosip_event_free(op->pending_auth);
1368 sal_remove_pending_auth(sal,op);
1369 op->pending_auth=NULL;
1371 if (get_auth_data(ev,&realm,&username)==0){
1372 sal->callbacks.auth_success(op,realm,username);
1376 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1379 char* computedReason=NULL;
1380 const char *reason=NULL;
1381 SalError error=SalErrorUnknown;
1382 SalReason sr=SalReasonUnknown;
1385 op=(SalOp*)find_op(sal,ev);
1388 ms_warning("Call failure reported for a closed call, ignored.");
1393 code=osip_message_get_status_code(ev->response);
1394 reason=osip_message_get_reason_phrase(ev->response);
1395 osip_header_t *h=NULL;
1396 if (!osip_message_header_get_byname( ev->response
1400 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1401 reason = computedReason;
1409 return process_authentication(sal,ev);
1412 error=SalErrorUnknown;
1415 error=SalErrorFailure;
1416 sr=SalReasonNotFound;
1419 error=SalErrorFailure;
1423 eXosip_default_action(ev);
1427 error=SalErrorFailure;
1428 sr=SalReasonTemporarilyUnavailable;
1430 error=SalErrorFailure;
1436 error=SalErrorFailure;
1437 sr=SalReasonDoNotDisturb;
1440 error=SalErrorFailure;
1441 sr=SalReasonDeclined;
1445 error=SalErrorFailure;
1446 sr=SalReasonUnknown;
1447 }else error=SalErrorNoResponse;
1449 op->terminated=TRUE;
1450 sal->callbacks.call_failure(op,error,sr,reason,code);
1451 if (computedReason != NULL){
1452 ms_free(computedReason);
1457 /* Request remote side to send us VFU */
1458 void sal_call_send_vfu_request(SalOp *h){
1459 osip_message_t *msg=NULL;
1461 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1465 " <picture_fast_update></picture_fast_update>"
1473 eXosip_call_build_info(h->did,&msg);
1475 osip_message_set_body(msg,info_body,strlen(info_body));
1476 osip_message_set_content_type(msg,"application/media_control+xml");
1477 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1478 osip_message_set_content_length(msg,clen);
1479 eXosip_call_send_request(h->did,msg);
1480 ms_message("Sending VFU request !");
1485 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1486 SalOp *op=find_op(sal,ev);
1487 osip_body_t *body=NULL;
1490 ms_warning("media control xml received without operation context!");
1494 osip_message_get_body(ev->request,0,&body);
1495 if (body && body->body!=NULL &&
1496 strstr(body->body,"picture_fast_update")){
1497 osip_message_t *ans=NULL;
1498 ms_message("Receiving VFU request !");
1499 if (sal->callbacks.vfu_request){
1500 sal->callbacks.vfu_request(op);
1501 eXosip_call_build_answer(ev->tid,200,&ans);
1503 eXosip_call_send_answer(ev->tid,200,ans);
1507 /*in all other cases we must say it is not implemented.*/
1509 osip_message_t *ans=NULL;
1511 eXosip_call_build_answer(ev->tid,501,&ans);
1513 eXosip_call_send_answer(ev->tid,501,ans);
1518 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1519 SalOp *op=find_op(sal,ev);
1520 osip_body_t *body=NULL;
1523 ms_warning("media dtmf relay received without operation context!");
1527 osip_message_get_body(ev->request,0,&body);
1528 if (body && body->body!=NULL){
1529 osip_message_t *ans=NULL;
1530 const char *name=strstr(body->body,"Signal");
1531 if (name==NULL) name=strstr(body->body,"signal");
1533 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1536 name+=strlen("signal");
1537 if (sscanf(name," = %1s",tmp)==1){
1538 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1539 if (sal->callbacks.dtmf_received != NULL)
1540 sal->callbacks.dtmf_received(op, tmp[0]);
1544 eXosip_call_build_answer(ev->tid,200,&ans);
1546 eXosip_call_send_answer(ev->tid,200,ans);
1551 static void fill_options_answer(osip_message_t *options){
1552 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1553 osip_message_set_accept(options,"application/sdp");
1556 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1557 osip_header_t *h=NULL;
1558 osip_message_t *ans=NULL;
1559 ms_message("Receiving REFER request !");
1560 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1563 osip_from_t *from=NULL;
1565 osip_from_init(&from);
1567 if (osip_from_parse(from,h->hvalue)==0){
1569 osip_uri_header_t *uh=NULL;
1570 osip_header_t *referred_by=NULL;
1571 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1572 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1573 ms_message("Found replaces in Refer-To");
1575 ms_free(op->replaces);
1577 op->replaces=ms_strdup(uh->gvalue);
1579 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1580 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1581 if (op->referred_by)
1582 ms_free(op->referred_by);
1583 op->referred_by=ms_strdup(referred_by->hvalue);
1586 osip_uri_header_freelist(&from->url->url_headers);
1587 osip_from_to_str(from,&tmp);
1588 sal->callbacks.refer_received(sal,op,tmp);
1590 osip_from_free(from);
1593 eXosip_call_build_answer(ev->tid,202,&ans);
1595 eXosip_call_send_answer(ev->tid,202,ans);
1600 ms_warning("cannot do anything with the refer without destination\n");
1604 static void process_notify(Sal *sal, eXosip_event_t *ev){
1605 osip_header_t *h=NULL;
1607 SalOp *op=find_op(sal,ev);
1608 osip_message_t *ans=NULL;
1610 ms_message("Receiving NOTIFY request !");
1611 osip_from_to_str(ev->request->from,&from);
1612 osip_message_header_get_byname(ev->request,"Event",0,&h);
1614 osip_body_t *body=NULL;
1615 //osip_content_type_t *ct=NULL;
1616 osip_message_get_body(ev->request,0,&body);
1617 //ct=osip_message_get_content_type(ev->request);
1618 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1619 /*special handling of refer events*/
1620 if (body && body->body){
1621 osip_message_t *msg;
1622 osip_message_init(&msg);
1623 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1624 int code=osip_message_get_status_code(msg);
1626 sal->callbacks.notify_refer(op,SalReferTrying);
1627 }else if (code==200){
1628 sal->callbacks.notify_refer(op,SalReferSuccess);
1629 }else if (code>=400){
1630 sal->callbacks.notify_refer(op,SalReferFailed);
1633 osip_message_free(msg);
1636 /*generic handling*/
1637 sal->callbacks.notify(op,from,h->hvalue);
1640 /*answer that we received the notify*/
1642 eXosip_call_build_answer(ev->tid,200,&ans);
1644 eXosip_call_send_answer(ev->tid,200,ans);
1649 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1650 osip_message_t *ans=NULL;
1652 if (MSG_IS_INFO(ev->request)){
1653 osip_content_type_t *ct;
1654 ct=osip_message_get_content_type(ev->request);
1655 if (ct && ct->subtype){
1656 if (strcmp(ct->subtype,"media_control+xml")==0)
1657 process_media_control_xml(sal,ev);
1658 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1659 process_dtmf_relay(sal,ev);
1661 ms_message("Unhandled SIP INFO.");
1662 /*send an "Not implemented" answer*/
1664 eXosip_call_build_answer(ev->tid,501,&ans);
1666 eXosip_call_send_answer(ev->tid,501,ans);
1670 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1672 eXosip_call_build_answer(ev->tid,200,&ans);
1674 eXosip_call_send_answer(ev->tid,200,ans);
1677 }else if(MSG_IS_MESSAGE(ev->request)){
1678 /* SIP messages could be received into call */
1679 text_received(sal, ev);
1681 eXosip_call_build_answer(ev->tid,200,&ans);
1683 eXosip_call_send_answer(ev->tid,200,ans);
1685 }else if(MSG_IS_REFER(ev->request)){
1686 SalOp *op=find_op(sal,ev);
1688 ms_message("Receiving REFER request !");
1689 process_refer(sal,op,ev);
1690 }else if(MSG_IS_NOTIFY(ev->request)){
1691 process_notify(sal,ev);
1692 }else if (MSG_IS_OPTIONS(ev->request)){
1694 eXosip_call_build_answer(ev->tid,200,&ans);
1696 fill_options_answer(ans);
1697 eXosip_call_send_answer(ev->tid,200,ans);
1701 }else ms_warning("call_message_new: No request ?");
1704 static void inc_update(Sal *sal, eXosip_event_t *ev){
1705 osip_message_t *msg=NULL;
1706 ms_message("Processing incoming UPDATE");
1708 eXosip_message_build_answer(ev->tid,200,&msg);
1710 eXosip_message_send_answer(ev->tid,200,msg);
1714 static bool_t comes_from_local_if(osip_message_t *msg){
1715 osip_via_t *via=NULL;
1716 osip_message_get_via(msg,0,&via);
1719 host=osip_via_get_host(via);
1720 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1721 osip_generic_param_t *param=NULL;
1722 osip_via_param_get_byname(via,"received",¶m);
1723 if (param==NULL) return TRUE;
1724 if (param->gvalue &&
1725 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1733 static void text_received(Sal *sal, eXosip_event_t *ev){
1734 osip_body_t *body=NULL;
1735 char *from=NULL,*msg=NULL;
1736 osip_content_type_t* content_type;
1737 osip_uri_param_t* external_body_url;
1738 char unquoted_external_body_url [256];
1739 int external_body_size=0;
1741 char message_id[256]={0};
1743 content_type= osip_message_get_content_type(ev->request);
1744 if (!content_type) {
1745 ms_error("Could not get message because no content type");
1748 osip_from_to_str(ev->request->from,&from);
1749 if (content_type->type
1750 && strcmp(content_type->type, "text")==0
1751 && content_type->subtype
1752 && strcmp(content_type->subtype, "plain")==0 ) {
1753 osip_message_get_body(ev->request,0,&body);
1755 ms_error("Could not get text message from SIP body");
1760 }else if (content_type->type
1761 && strcmp(content_type->type, "message")==0
1762 && content_type->subtype
1763 && strcmp(content_type->subtype, "external-body")==0 ) {
1765 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1766 /*remove both first and last character*/
1767 strncpy(unquoted_external_body_url
1768 ,&external_body_url->gvalue[1]
1769 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1770 unquoted_external_body_url[external_body_size-1]='\0';
1772 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1776 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1780 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1781 salmsg.message_id=message_id;
1782 sal->callbacks.text_received(sal,&salmsg);
1788 static void other_request(Sal *sal, eXosip_event_t *ev){
1789 ms_message("in other_request");
1790 if (ev->request==NULL) return;
1791 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1792 text_received(sal,ev);
1793 eXosip_message_send_answer(ev->tid,200,NULL);
1794 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1795 osip_message_t *options=NULL;
1796 eXosip_options_build_answer(ev->tid,200,&options);
1797 fill_options_answer(options);
1798 eXosip_options_send_answer(ev->tid,200,options);
1799 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1800 ms_message("Receiving REFER request !");
1801 if (comes_from_local_if(ev->request)) {
1802 process_refer(sal,NULL,ev);
1803 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1804 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1809 osip_message_to_str(ev->request,&tmp,&msglen);
1811 ms_message("Unsupported request received:\n%s",tmp);
1814 /*answer with a 501 Not implemented*/
1815 eXosip_message_send_answer(ev->tid,501,NULL);
1819 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1820 osip_via_t *via=NULL;
1821 osip_message_get_via(msg,0,&via);
1823 osip_free(via->port);
1824 via->port=osip_strdup(port);
1825 osip_free(via->host);
1826 via->host=osip_strdup(ip);
1831 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1832 osip_contact_t *ctt=NULL;
1833 const char *received;
1835 SalTransport transport;
1838 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1839 osip_message_get_contact(request,0,&ctt);
1841 ms_warning("fix_message_contact(): no contact to update");
1844 if (expire_last_contact){
1845 osip_contact_t *oldct=NULL,*prevct;
1846 osip_generic_param_t *param=NULL;
1847 osip_contact_clone(ctt,&oldct);
1848 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1849 osip_contact_free(prevct);
1850 osip_list_remove(&request->contacts,1);
1852 osip_list_add(&request->contacts,oldct,1);
1853 osip_contact_param_get_byname(oldct,"expires",¶m);
1855 if (param->gvalue) osip_free(param->gvalue);
1856 param->gvalue=osip_strdup("0");
1858 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1861 if (ctt->url->host!=NULL){
1862 osip_free(ctt->url->host);
1864 ctt->url->host=osip_strdup(received);
1865 if (ctt->url->port!=NULL){
1866 osip_free(ctt->url->port);
1868 snprintf(port,sizeof(port),"%i",rport);
1869 ctt->url->port=osip_strdup(port);
1870 if (op->masquerade_via) masquerade_via(request,received,port);
1872 if (transport != SalTransportUDP) {
1873 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1878 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1879 osip_contact_t *ctt=NULL;
1880 SalAddress* ori_contact_address=NULL;
1881 const char *received;
1883 SalTransport transport;
1885 osip_message_t *msg=NULL;
1886 Sal* sal=op->base.root;
1888 bool_t found_valid_contact=FALSE;
1889 bool_t from_request=FALSE;
1891 if (sal->double_reg==FALSE ) return FALSE;
1893 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1896 osip_message_get_contact(last_answer,i,&ctt);
1897 if (!from_request && ctt==NULL) {
1898 osip_message_get_contact(orig_request,0,&ctt);
1902 osip_contact_to_str(ctt,&tmp);
1903 ori_contact_address = sal_address_new(tmp);
1905 /*check if contact is up to date*/
1906 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1907 && sal_address_get_port_int(ori_contact_address) == rport
1908 && sal_address_get_transport(ori_contact_address) == transport) {
1910 ms_message("Register response has up to date contact, doing nothing.");
1912 ms_warning("Register response does not have up to date contact, but last request had."
1913 "Stupid registrar detected, giving up.");
1915 found_valid_contact=TRUE;
1918 sal_address_destroy(ori_contact_address);
1921 }while(!found_valid_contact);
1922 if (!found_valid_contact)
1923 ms_message("Contact do not match, resending register.");
1927 eXosip_register_build_register(op->rid,op->expires,&msg);
1930 ms_warning("Fail to create a contact updated register.");
1933 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1934 eXosip_register_send_register(op->rid,msg);
1936 ms_message("Resending new register with updated contact");
1937 update_contact_from_response(op,last_answer);
1940 ms_warning("Fail to send updated register.");
1948 static void registration_success(Sal *sal, eXosip_event_t *ev){
1949 SalOp *op=sal_find_register(sal,ev->rid);
1950 osip_header_t *h=NULL;
1953 ms_error("Receiving register response for unknown operation");
1956 osip_message_get_expires(ev->request,0,&h);
1957 if (h!=NULL && atoi(h->hvalue)!=0){
1959 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1960 sal->callbacks.register_success(op,registered);
1963 sal->callbacks.register_success(op,FALSE);
1967 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1969 const char *reason=NULL;
1970 SalOp *op=sal_find_register(sal,ev->rid);
1971 SalReason sr=SalReasonUnknown;
1972 SalError se=SalErrorUnknown;
1975 ms_error("Receiving register failure for unknown operation");
1979 status_code=osip_message_get_status_code(ev->response);
1980 reason=osip_message_get_reason_phrase(ev->response);
1982 switch(status_code){
1985 return process_authentication(sal,ev);
1987 case 423: /*interval too brief*/
1988 {/*retry with greater interval */
1989 osip_header_t *h=NULL;
1990 osip_message_t *msg=NULL;
1991 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1992 if (h && h->hvalue && h->hvalue[0]!='\0'){
1993 int val=atoi(h->hvalue);
1994 if (val>op->expires)
1996 }else op->expires*=2;
1998 eXosip_register_build_register(op->rid,op->expires,&msg);
1999 eXosip_register_send_register(op->rid,msg);
2003 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2004 in vias, such as ekiga.net
2005 On the opposite, freephonie.net bugs when via are masqueraded.
2007 op->masquerade_via=TRUE;
2009 /* if contact is up to date, process the failure, otherwise resend a new register with
2010 updated contact first, just in case the faillure is due to incorrect contact */
2011 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2012 return TRUE; /*we are retrying with an updated contact*/
2013 if (status_code==403){
2015 sr=SalReasonForbidden;
2016 }else if (status_code==0){
2017 se=SalErrorNoResponse;
2019 sal->callbacks.register_failure(op,se,sr,reason);
2024 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2025 SalOp *op=find_op(sal,ev);
2027 ms_warning("other_request_reply(): Receiving response to unknown request.");
2031 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2032 update_contact_from_response(op,ev->response);
2033 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2034 sal->callbacks.ping_reply(op);
2036 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2037 /*out of call message acknolegment*/
2038 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2040 if (ev->response->status_code<200){
2041 status=SalTextDeliveryInProgress;
2042 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2043 status=SalTextDeliveryDone;
2046 sal->callbacks.text_delivery_update(op,status);
2050 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2051 SalOp *op=find_op(sal,ev);
2053 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2054 if (op->sipfrag_pending){
2055 send_notify_for_refer(op->did,op->sipfrag_pending);
2056 op->sipfrag_pending=NULL;
2062 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2063 ms_message("linphone process event get a message %d\n",ev->type);
2065 case EXOSIP_CALL_ANSWERED:
2066 ms_message("CALL_ANSWERED\n");
2067 call_accepted(sal,ev);
2068 authentication_ok(sal,ev);
2070 case EXOSIP_CALL_CLOSED:
2071 case EXOSIP_CALL_CANCELLED:
2072 ms_message("CALL_CLOSED or CANCELLED\n");
2073 call_terminated(sal,ev);
2075 case EXOSIP_CALL_TIMEOUT:
2076 case EXOSIP_CALL_NOANSWER:
2077 ms_message("CALL_TIMEOUT or NOANSWER\n");
2078 return call_failure(sal,ev);
2080 case EXOSIP_CALL_REQUESTFAILURE:
2081 case EXOSIP_CALL_GLOBALFAILURE:
2082 case EXOSIP_CALL_SERVERFAILURE:
2083 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2084 return call_failure(sal,ev);
2086 case EXOSIP_CALL_RELEASED:
2087 ms_message("CALL_RELEASED\n");
2088 call_released(sal, ev);
2090 case EXOSIP_CALL_INVITE:
2091 ms_message("CALL_NEW\n");
2092 inc_new_call(sal,ev);
2094 case EXOSIP_CALL_REINVITE:
2095 handle_reinvite(sal,ev);
2097 case EXOSIP_CALL_ACK:
2098 ms_message("CALL_ACK");
2101 case EXOSIP_CALL_REDIRECTED:
2102 ms_message("CALL_REDIRECTED");
2103 eXosip_default_action(ev);
2105 case EXOSIP_CALL_PROCEEDING:
2106 ms_message("CALL_PROCEEDING");
2107 call_proceeding(sal,ev);
2109 case EXOSIP_CALL_RINGING:
2110 ms_message("CALL_RINGING");
2111 call_ringing(sal,ev);
2112 authentication_ok(sal,ev);
2114 case EXOSIP_CALL_MESSAGE_NEW:
2115 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2116 call_message_new(sal,ev);
2118 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2120 (ev->response->status_code==407 || ev->response->status_code==401)){
2121 return process_authentication(sal,ev);
2124 case EXOSIP_CALL_MESSAGE_ANSWERED:
2125 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2126 process_in_call_reply(sal,ev);
2128 case EXOSIP_IN_SUBSCRIPTION_NEW:
2129 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2130 sal_exosip_subscription_recv(sal,ev);
2132 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2133 ms_message("CALL_SUBSCRIPTION_NEW ");
2134 sal_exosip_in_subscription_closed(sal,ev);
2136 case EXOSIP_SUBSCRIPTION_UPDATE:
2137 ms_message("CALL_SUBSCRIPTION_UPDATE");
2139 case EXOSIP_SUBSCRIPTION_NOTIFY:
2140 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2141 sal_exosip_notify_recv(sal,ev);
2143 case EXOSIP_SUBSCRIPTION_ANSWERED:
2144 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2145 sal_exosip_subscription_answered(sal,ev);
2147 case EXOSIP_SUBSCRIPTION_CLOSED:
2148 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2149 sal_exosip_subscription_closed(sal,ev);
2151 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2152 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2153 return process_authentication(sal,ev);
2155 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2156 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2157 sal_exosip_subscription_closed(sal,ev);
2159 case EXOSIP_REGISTRATION_FAILURE:
2160 ms_message("REGISTRATION_FAILURE\n");
2161 return registration_failure(sal,ev);
2163 case EXOSIP_REGISTRATION_SUCCESS:
2164 authentication_ok(sal,ev);
2165 registration_success(sal,ev);
2167 case EXOSIP_MESSAGE_NEW:
2168 other_request(sal,ev);
2170 case EXOSIP_MESSAGE_PROCEEDING:
2171 case EXOSIP_MESSAGE_ANSWERED:
2172 case EXOSIP_MESSAGE_REDIRECTED:
2173 case EXOSIP_MESSAGE_SERVERFAILURE:
2174 case EXOSIP_MESSAGE_GLOBALFAILURE:
2175 other_request_reply(sal,ev);
2177 case EXOSIP_MESSAGE_REQUESTFAILURE:
2178 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2180 switch (ev->response->status_code) {
2183 return process_authentication(sal,ev);
2185 eXosip_automatic_action ();
2190 other_request_reply(sal,ev);
2193 ms_message("Unhandled exosip event ! %i",ev->type);
2199 int sal_iterate(Sal *sal){
2201 while((ev=eXosip_event_wait(0,0))!=NULL){
2202 if (process_event(sal,ev))
2203 eXosip_event_free(ev);
2205 #ifdef HAVE_EXOSIP_TRYLOCK
2206 if (eXosip_trylock()==0){
2207 eXosip_automatic_refresh();
2210 ms_warning("eXosip_trylock busy.");
2214 eXosip_automatic_refresh();
2220 static void register_set_contact(osip_message_t *msg, const char *contact){
2221 osip_uri_param_t *param = NULL;
2222 osip_contact_t *ct=NULL;
2224 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2225 osip_message_get_contact(msg,0,&ct);
2227 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2228 if (param && param->gvalue)
2229 line=osip_strdup(param->gvalue);
2231 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2232 osip_message_set_contact(msg,contact);
2233 osip_message_get_contact(msg,0,&ct);
2234 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2237 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2238 osip_route_t *route;
2240 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2242 osip_route_init(&route);
2243 if (osip_route_parse(route,proxy)==0){
2244 osip_uri_param_t *lr_param = NULL;
2245 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2246 if (lr_param == NULL){
2247 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2249 osip_list_add(&msg->routes,route,0);
2252 osip_route_free(route);
2256 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2257 osip_message_t *msg;
2258 const char *contact=sal_op_get_contact(h);
2260 sal_op_set_route(h,proxy);
2262 SalAddress *from_parsed=sal_address_new(from);
2264 char *uri, *domain_ptr = NULL;
2265 if (from_parsed==NULL) {
2266 ms_warning("sal_register() bad from %s",from);
2269 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2270 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2271 uri = sal_address_as_string_uri_only(from_parsed);
2272 if (uri) domain_ptr = strchr(uri, '@');
2274 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2276 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2278 if (uri) ms_free(uri);
2279 sal_address_destroy(from_parsed);
2281 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2283 if (contact) register_set_contact(msg,contact);
2284 sal_register_add_route(msg,proxy);
2285 sal_add_register(h->base.root,h);
2287 ms_error("Could not build initial register.");
2293 eXosip_register_build_register(h->rid,expires,&msg);
2294 sal_register_add_route(msg,proxy);
2297 eXosip_register_send_register(h->rid,msg);
2301 return (msg != NULL) ? 0 : -1;
2304 int sal_register_refresh(SalOp *op, int expires){
2305 osip_message_t *msg=NULL;
2306 const char *contact=sal_op_get_contact(op);
2309 ms_error("Unexistant registration context, not possible to refresh.");
2312 #ifdef HAVE_EXOSIP_TRYLOCK
2315 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2316 * 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
2317 * the exosip lock in a non blocking way, and give up if it takes too long*/
2318 while (eXosip_trylock()!=0){
2320 if (tries>30) {/*after 3 seconds, give up*/
2321 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2329 eXosip_register_build_register(op->rid,expires,&msg);
2331 if (contact) register_set_contact(msg,contact);
2332 sal_register_add_route(msg,sal_op_get_route(op));
2333 eXosip_register_send_register(op->rid,msg);
2334 }else ms_error("Could not build REGISTER refresh message.");
2336 return (msg != NULL) ? 0 : -1;
2340 int sal_unregister(SalOp *h){
2341 osip_message_t *msg=NULL;
2343 eXosip_register_build_register(h->rid,0,&msg);
2344 if (msg) eXosip_register_send_register(h->rid,msg);
2345 else ms_warning("Could not build unREGISTER !");
2350 SalAddress * sal_address_new(const char *uri){
2352 osip_from_init(&from);
2354 // Remove front spaces
2355 while (uri[0]==' ') {
2359 if (osip_from_parse(from,uri)!=0){
2360 osip_from_free(from);
2363 if (from->displayname!=NULL && from->displayname[0]=='"'){
2364 char *unquoted=osip_strdup_without_quote(from->displayname);
2365 osip_free(from->displayname);
2366 from->displayname=unquoted;
2368 return (SalAddress*)from;
2371 SalAddress * sal_address_clone(const SalAddress *addr){
2372 osip_from_t *ret=NULL;
2373 osip_from_clone((osip_from_t*)addr,&ret);
2374 return (SalAddress*)ret;
2377 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2379 const char *sal_address_get_scheme(const SalAddress *addr){
2380 const osip_from_t *u=(const osip_from_t*)addr;
2381 return null_if_empty(u->url->scheme);
2384 const char *sal_address_get_display_name(const SalAddress* addr){
2385 const osip_from_t *u=(const osip_from_t*)addr;
2386 return null_if_empty(u->displayname);
2389 const char *sal_address_get_username(const SalAddress *addr){
2390 const osip_from_t *u=(const osip_from_t*)addr;
2391 return null_if_empty(u->url->username);
2394 const char *sal_address_get_domain(const SalAddress *addr){
2395 const osip_from_t *u=(const osip_from_t*)addr;
2396 return null_if_empty(u->url->host);
2399 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2400 osip_from_t *u=(osip_from_t*)addr;
2401 if (u->displayname!=NULL){
2402 osip_free(u->displayname);
2403 u->displayname=NULL;
2405 if (display_name!=NULL && display_name[0]!='\0'){
2406 u->displayname=osip_strdup(display_name);
2410 void sal_address_set_username(SalAddress *addr, const char *username){
2411 osip_from_t *uri=(osip_from_t*)addr;
2412 if (uri->url->username!=NULL){
2413 osip_free(uri->url->username);
2414 uri->url->username=NULL;
2417 uri->url->username=osip_strdup(username);
2420 void sal_address_set_domain(SalAddress *addr, const char *host){
2421 osip_from_t *uri=(osip_from_t*)addr;
2422 if (uri->url->host!=NULL){
2423 osip_free(uri->url->host);
2424 uri->url->host=NULL;
2427 uri->url->host=osip_strdup(host);
2430 void sal_address_set_port(SalAddress *addr, const char *port){
2431 osip_from_t *uri=(osip_from_t*)addr;
2432 if (uri->url->port!=NULL){
2433 osip_free(uri->url->port);
2434 uri->url->port=NULL;
2437 uri->url->port=osip_strdup(port);
2440 void sal_address_set_port_int(SalAddress *uri, int port){
2443 /*this is the default, special case to leave the port field blank*/
2444 sal_address_set_port(uri,NULL);
2447 snprintf(tmp,sizeof(tmp),"%i",port);
2448 sal_address_set_port(uri,tmp);
2451 void sal_address_clean(SalAddress *addr){
2452 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2453 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2456 char *sal_address_as_string(const SalAddress *u){
2458 osip_from_t *from=(osip_from_t *)u;
2459 char *old_displayname=NULL;
2460 /* hack to force use of quotes around the displayname*/
2461 if (from->displayname!=NULL
2462 && from->displayname[0]!='"'){
2463 old_displayname=from->displayname;
2464 from->displayname=osip_enquote(from->displayname);
2466 osip_from_to_str(from,&tmp);
2467 if (old_displayname!=NULL){
2468 ms_free(from->displayname);
2469 from->displayname=old_displayname;
2476 char *sal_address_as_string_uri_only(const SalAddress *u){
2477 char *tmp=NULL,*ret;
2478 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2483 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2484 osip_uri_param_t *param=NULL;
2485 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2487 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2489 osip_free(param->gvalue);
2490 param->gvalue=value ? osip_strdup(value) : NULL;
2495 void sal_address_destroy(SalAddress *u){
2496 osip_from_free((osip_from_t*)u);
2499 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2500 ctx->keepalive_period=value;
2501 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2503 unsigned int sal_get_keepalive_period(Sal *ctx) {
2504 return ctx->keepalive_period;
2507 const char * sal_address_get_port(const SalAddress *addr) {
2508 const osip_from_t *u=(const osip_from_t*)addr;
2509 return null_if_empty(u->url->port);
2512 int sal_address_get_port_int(const SalAddress *uri) {
2513 const char* port = sal_address_get_port(uri);
2520 SalTransport sal_address_get_transport(const SalAddress* addr) {
2521 const osip_from_t *u=(const osip_from_t*)addr;
2522 osip_uri_param_t *transport_param=NULL;
2523 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2524 if (transport_param == NULL){
2525 return SalTransportUDP;
2527 return sal_transport_parse(transport_param->gvalue);
2530 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2531 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2534 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2535 int sal_call_update(SalOp *h, const char *subject){
2537 osip_message_t *reinvite=NULL;
2540 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2545 osip_message_set_subject(reinvite,subject);
2546 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2547 if (h->base.contact){
2548 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2549 osip_message_set_contact(reinvite,h->base.contact);
2551 if (h->base.root->session_expires!=0){
2552 osip_message_set_header(reinvite, "Session-expires", "200");
2553 osip_message_set_supported(reinvite, "timer");
2555 if (h->base.local_media){
2556 h->sdp_offering=TRUE;
2557 set_sdp_from_desc(reinvite,h->base.local_media);
2558 }else h->sdp_offering=FALSE;
2560 err = eXosip_call_send_request(h->did, reinvite);
2564 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2565 ctx->reuse_authorization=value;