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 bool_t terminating=FALSE;
942 if (h->pending_auth && strcmp(h->pending_auth->request->sip_method,"BYE")==0) {
945 if (h->terminated && !terminating) return;
947 if (h->pending_auth){
948 push_auth_to_exosip(info);
950 /*FIXME exosip does not take into account this update register message*/
952 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
956 update_contact_from_response(h,h->pending_auth->response);
958 eXosip_default_action(h->pending_auth);
960 ms_message("eXosip_default_action() done");
961 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
963 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
964 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
967 void sal_op_cancel_authentication(SalOp *h) {
969 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
970 } else if (h->cid >0) {
971 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
973 ms_warning("Auth failure not handled");
977 static void set_network_origin(SalOp *op, osip_message_t *req){
978 const char *received=NULL;
981 SalTransport transport;
982 if (extract_received_rport(req,&received,&rport,&transport)!=0){
983 osip_via_t *via=NULL;
985 osip_message_get_via(req,0,&via);
986 received=osip_via_get_host(via);
987 tmp=osip_via_get_port(via);
988 if (tmp) rport=atoi(tmp);
990 if (transport != SalTransportUDP) {
991 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
993 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
995 __sal_op_set_network_origin(op,origin);
998 static void set_remote_ua(SalOp* op, osip_message_t *req){
999 if (op->base.remote_ua==NULL){
1000 osip_header_t *h=NULL;
1001 osip_message_get_user_agent(req,0,&h);
1003 op->base.remote_ua=ms_strdup(h->hvalue);
1008 static void set_replaces(SalOp *op, osip_message_t *req){
1009 osip_header_t *h=NULL;
1012 ms_free(op->replaces);
1015 osip_message_header_get_byname(req,"replaces",0,&h);
1017 if (h->hvalue && h->hvalue[0]!='\0'){
1018 op->replaces=ms_strdup(h->hvalue);
1023 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1025 return sal_find_call(sal,ev->cid);
1028 return sal_find_register(sal,ev->rid);
1031 return sal_find_out_subscribe(sal,ev->sid);
1034 return sal_find_in_subscribe(sal,ev->nid);
1036 if (ev->response) return sal_find_other(sal,ev->response);
1037 else if (ev->request) return sal_find_other(sal,ev->request);
1041 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1042 SalOp *op=sal_op_new(sal);
1043 osip_from_t *from,*to;
1044 osip_call_info_t *call_info;
1046 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1047 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1048 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1050 set_network_origin(op,ev->request);
1051 set_remote_ua(op,ev->request);
1052 set_replaces(op,ev->request);
1055 op->sdp_offering=FALSE;
1056 op->base.remote_media=sal_media_description_new();
1057 sdp_to_media_description(sdp,op->base.remote_media);
1058 sdp_message_free(sdp);
1059 }else op->sdp_offering=TRUE;
1061 from=osip_message_get_from(ev->request);
1062 to=osip_message_get_to(ev->request);
1063 osip_from_to_str(from,&tmp);
1064 sal_op_set_from(op,tmp);
1066 osip_from_to_str(to,&tmp);
1067 sal_op_set_to(op,tmp);
1070 osip_message_get_call_info(ev->request,0,&call_info);
1073 osip_call_info_to_str(call_info,&tmp);
1074 if( strstr(tmp,"answer-after=") != NULL)
1076 op->auto_answer_asked=TRUE;
1077 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1085 sal_add_call(op->base.root,op);
1086 sal->callbacks.call_received(op);
1089 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1090 SalOp *op=find_op(sal,ev);
1094 ms_warning("Reinvite for non-existing operation !");
1099 sdp=eXosip_get_sdp_info(ev->request);
1100 if (op->base.remote_media){
1101 sal_media_description_unref(op->base.remote_media);
1102 op->base.remote_media=NULL;
1105 sal_media_description_unref(op->result);
1109 op->sdp_offering=FALSE;
1110 op->base.remote_media=sal_media_description_new();
1111 sdp_to_media_description(sdp,op->base.remote_media);
1112 sdp_message_free(sdp);
1115 op->sdp_offering=TRUE;
1117 sal->callbacks.call_updating(op);
1120 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1121 SalOp *op=find_op(sal,ev);
1125 ms_warning("ack for non-existing call !");
1128 if (op->terminated) {
1129 ms_warning("ack for terminated call, ignoring");
1133 if (op->sdp_offering){
1134 sdp=eXosip_get_sdp_info(ev->ack);
1136 if (op->base.remote_media)
1137 sal_media_description_unref(op->base.remote_media);
1138 op->base.remote_media=sal_media_description_new();
1139 sdp_to_media_description(sdp,op->base.remote_media);
1141 sdp_message_free(sdp);
1147 sal->callbacks.call_ack(op);
1150 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1151 const char *received;
1153 SalTransport transport;
1154 if (extract_received_rport(response,&received,&rport,&transport)==0){
1155 const char *contact=sal_op_get_contact(op);
1157 /*no contact given yet, use from instead*/
1158 contact=sal_op_get_from(op);
1161 SalAddress *addr=sal_address_new(contact);
1163 sal_address_set_domain(addr,received);
1164 sal_address_set_port_int(addr,rport);
1165 if (transport!=SalTransportUDP)
1166 sal_address_set_transport(addr,transport);
1167 tmp=sal_address_as_string(addr);
1168 ms_message("Contact address updated to %s",tmp);
1169 sal_op_set_contact(op,tmp);
1170 sal_address_destroy(addr);
1176 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1177 SalOp *op=find_op(sal,ev);
1179 if (op==NULL || op->terminated==TRUE) {
1180 ms_warning("This call has been canceled.");
1182 eXosip_call_terminate(ev->cid,ev->did);
1190 /* update contact if received and rport are set by the server
1191 note: will only be used by remote for next INVITE, if any...*/
1192 update_contact_from_response(op,ev->response);
1196 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1198 SalOp *op=find_op(sal,ev);
1199 if (call_proceeding(sal, ev)==-1) return;
1201 set_remote_ua(op,ev->response);
1202 sdp=eXosip_get_sdp_info(ev->response);
1204 op->base.remote_media=sal_media_description_new();
1205 sdp_to_media_description(sdp,op->base.remote_media);
1206 sdp_message_free(sdp);
1207 if (op->base.local_media) sdp_process(op);
1209 sal->callbacks.call_ringing(op);
1212 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1214 osip_message_t *msg=NULL;
1215 SalOp *op=find_op(sal,ev);
1216 const char *contact;
1218 if (op==NULL || op->terminated==TRUE) {
1219 ms_warning("This call has been already terminated.");
1221 eXosip_call_terminate(ev->cid,ev->did);
1227 set_remote_ua(op,ev->response);
1229 sdp=eXosip_get_sdp_info(ev->response);
1231 op->base.remote_media=sal_media_description_new();
1232 sdp_to_media_description(sdp,op->base.remote_media);
1233 sdp_message_free(sdp);
1234 if (op->base.local_media) sdp_process(op);
1236 eXosip_call_build_ack(ev->did,&msg);
1238 ms_warning("This call has been already terminated.");
1240 eXosip_call_terminate(ev->cid,ev->did);
1244 contact=sal_op_get_contact(op);
1246 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1247 osip_message_set_contact(msg,contact);
1249 if (op->sdp_answer){
1250 set_sdp(msg,op->sdp_answer);
1251 sdp_message_free(op->sdp_answer);
1252 op->sdp_answer=NULL;
1254 eXosip_call_send_ack(ev->did,msg);
1255 sal->callbacks.call_accepted(op);
1258 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1260 SalOp *op=find_op(sal,ev);
1262 ms_warning("Call terminated for already closed call ?");
1266 osip_from_to_str(ev->request->from,&from);
1268 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1269 if (from) osip_free(from);
1270 op->terminated=TRUE;
1273 static void call_released(Sal *sal, eXosip_event_t *ev){
1274 SalOp *op=find_op(sal,ev);
1276 ms_warning("No op associated to this call_released()");
1279 if (!op->terminated){
1280 /* no response received so far */
1281 call_failure(sal,ev);
1283 sal->callbacks.call_released(op);
1286 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1287 const char *prx_realm=NULL,*www_realm=NULL;
1288 osip_proxy_authenticate_t *prx_auth;
1289 osip_www_authenticate_t *www_auth;
1291 *username=osip_uri_get_username(resp->from->url);
1292 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1293 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1295 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1297 www_realm=osip_www_authenticate_get_realm(www_auth);
1301 }else if (www_realm){
1309 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1310 osip_authorization_t *auth=NULL;
1311 osip_proxy_authorization_t *prx_auth=NULL;
1313 *username=osip_uri_get_username(msg->from->url);
1314 osip_message_get_authorization(msg, 0, &auth);
1316 *realm=osip_authorization_get_realm(auth);
1319 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1321 *realm=osip_proxy_authorization_get_realm(prx_auth);
1327 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1328 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1329 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1333 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1334 if (op->pending_auth){
1335 return get_auth_data(op->pending_auth,realm,username);
1340 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1342 const char *username,*realm;
1345 ms_warning("No operation associated with this authentication !");
1348 if (get_auth_data(ev,&realm,&username)==0){
1349 if (op->pending_auth!=NULL){
1350 eXosip_event_free(op->pending_auth);
1351 op->pending_auth=ev;
1353 op->pending_auth=ev;
1354 sal_add_pending_auth(sal,op);
1357 sal->callbacks.auth_requested(op,realm,username);
1363 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1365 const char *username,*realm;
1368 ms_warning("No operation associated with this authentication_ok!");
1371 if (op->pending_auth){
1372 eXosip_event_free(op->pending_auth);
1373 sal_remove_pending_auth(sal,op);
1374 op->pending_auth=NULL;
1376 if (get_auth_data(ev,&realm,&username)==0){
1377 sal->callbacks.auth_success(op,realm,username);
1381 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1384 char* computedReason=NULL;
1385 const char *reason=NULL;
1386 SalError error=SalErrorUnknown;
1387 SalReason sr=SalReasonUnknown;
1390 op=(SalOp*)find_op(sal,ev);
1393 ms_warning("Call failure reported for a closed call, ignored.");
1398 code=osip_message_get_status_code(ev->response);
1399 reason=osip_message_get_reason_phrase(ev->response);
1400 osip_header_t *h=NULL;
1401 if (!osip_message_header_get_byname( ev->response
1405 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1406 reason = computedReason;
1414 return process_authentication(sal,ev);
1417 error=SalErrorUnknown;
1420 error=SalErrorFailure;
1421 sr=SalReasonNotFound;
1424 error=SalErrorFailure;
1428 eXosip_default_action(ev);
1432 error=SalErrorFailure;
1433 sr=SalReasonTemporarilyUnavailable;
1435 error=SalErrorFailure;
1441 error=SalErrorFailure;
1442 sr=SalReasonDoNotDisturb;
1445 error=SalErrorFailure;
1446 sr=SalReasonDeclined;
1450 error=SalErrorFailure;
1451 sr=SalReasonUnknown;
1452 }else error=SalErrorNoResponse;
1454 op->terminated=TRUE;
1455 sal->callbacks.call_failure(op,error,sr,reason,code);
1456 if (computedReason != NULL){
1457 ms_free(computedReason);
1462 /* Request remote side to send us VFU */
1463 void sal_call_send_vfu_request(SalOp *h){
1464 osip_message_t *msg=NULL;
1466 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1470 " <picture_fast_update></picture_fast_update>"
1478 eXosip_call_build_info(h->did,&msg);
1480 osip_message_set_body(msg,info_body,strlen(info_body));
1481 osip_message_set_content_type(msg,"application/media_control+xml");
1482 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1483 osip_message_set_content_length(msg,clen);
1484 eXosip_call_send_request(h->did,msg);
1485 ms_message("Sending VFU request !");
1490 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1491 SalOp *op=find_op(sal,ev);
1492 osip_body_t *body=NULL;
1495 ms_warning("media control xml received without operation context!");
1499 osip_message_get_body(ev->request,0,&body);
1500 if (body && body->body!=NULL &&
1501 strstr(body->body,"picture_fast_update")){
1502 osip_message_t *ans=NULL;
1503 ms_message("Receiving VFU request !");
1504 if (sal->callbacks.vfu_request){
1505 sal->callbacks.vfu_request(op);
1506 eXosip_call_build_answer(ev->tid,200,&ans);
1508 eXosip_call_send_answer(ev->tid,200,ans);
1512 /*in all other cases we must say it is not implemented.*/
1514 osip_message_t *ans=NULL;
1516 eXosip_call_build_answer(ev->tid,501,&ans);
1518 eXosip_call_send_answer(ev->tid,501,ans);
1523 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1524 SalOp *op=find_op(sal,ev);
1525 osip_body_t *body=NULL;
1528 ms_warning("media dtmf relay received without operation context!");
1532 osip_message_get_body(ev->request,0,&body);
1533 if (body && body->body!=NULL){
1534 osip_message_t *ans=NULL;
1535 const char *name=strstr(body->body,"Signal");
1536 if (name==NULL) name=strstr(body->body,"signal");
1538 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1541 name+=strlen("signal");
1542 if (sscanf(name," = %1s",tmp)==1){
1543 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1544 if (sal->callbacks.dtmf_received != NULL)
1545 sal->callbacks.dtmf_received(op, tmp[0]);
1549 eXosip_call_build_answer(ev->tid,200,&ans);
1551 eXosip_call_send_answer(ev->tid,200,ans);
1556 static void fill_options_answer(osip_message_t *options){
1557 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1558 osip_message_set_accept(options,"application/sdp");
1561 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1562 osip_header_t *h=NULL;
1563 osip_message_t *ans=NULL;
1564 ms_message("Receiving REFER request !");
1565 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1568 osip_from_t *from=NULL;
1570 osip_from_init(&from);
1572 if (osip_from_parse(from,h->hvalue)==0){
1574 osip_uri_header_t *uh=NULL;
1575 osip_header_t *referred_by=NULL;
1576 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1577 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1578 ms_message("Found replaces in Refer-To");
1580 ms_free(op->replaces);
1582 op->replaces=ms_strdup(uh->gvalue);
1584 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1585 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1586 if (op->referred_by)
1587 ms_free(op->referred_by);
1588 op->referred_by=ms_strdup(referred_by->hvalue);
1591 osip_uri_header_freelist(&from->url->url_headers);
1592 osip_from_to_str(from,&tmp);
1593 sal->callbacks.refer_received(sal,op,tmp);
1595 osip_from_free(from);
1598 eXosip_call_build_answer(ev->tid,202,&ans);
1600 eXosip_call_send_answer(ev->tid,202,ans);
1605 ms_warning("cannot do anything with the refer without destination\n");
1609 static void process_notify(Sal *sal, eXosip_event_t *ev){
1610 osip_header_t *h=NULL;
1612 SalOp *op=find_op(sal,ev);
1613 osip_message_t *ans=NULL;
1615 ms_message("Receiving NOTIFY request !");
1616 osip_from_to_str(ev->request->from,&from);
1617 osip_message_header_get_byname(ev->request,"Event",0,&h);
1619 osip_body_t *body=NULL;
1620 //osip_content_type_t *ct=NULL;
1621 osip_message_get_body(ev->request,0,&body);
1622 //ct=osip_message_get_content_type(ev->request);
1623 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1624 /*special handling of refer events*/
1625 if (body && body->body){
1626 osip_message_t *msg;
1627 osip_message_init(&msg);
1628 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1629 int code=osip_message_get_status_code(msg);
1631 sal->callbacks.notify_refer(op,SalReferTrying);
1632 }else if (code==200){
1633 sal->callbacks.notify_refer(op,SalReferSuccess);
1634 }else if (code>=400){
1635 sal->callbacks.notify_refer(op,SalReferFailed);
1638 osip_message_free(msg);
1641 /*generic handling*/
1642 sal->callbacks.notify(op,from,h->hvalue);
1645 /*answer that we received the notify*/
1647 eXosip_call_build_answer(ev->tid,200,&ans);
1649 eXosip_call_send_answer(ev->tid,200,ans);
1654 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1655 osip_message_t *ans=NULL;
1657 if (MSG_IS_INFO(ev->request)){
1658 osip_content_type_t *ct;
1659 ct=osip_message_get_content_type(ev->request);
1660 if (ct && ct->subtype){
1661 if (strcmp(ct->subtype,"media_control+xml")==0)
1662 process_media_control_xml(sal,ev);
1663 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1664 process_dtmf_relay(sal,ev);
1666 ms_message("Unhandled SIP INFO.");
1667 /*send an "Not implemented" answer*/
1669 eXosip_call_build_answer(ev->tid,501,&ans);
1671 eXosip_call_send_answer(ev->tid,501,ans);
1675 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1677 eXosip_call_build_answer(ev->tid,200,&ans);
1679 eXosip_call_send_answer(ev->tid,200,ans);
1682 }else if(MSG_IS_MESSAGE(ev->request)){
1683 /* SIP messages could be received into call */
1684 text_received(sal, ev);
1686 eXosip_call_build_answer(ev->tid,200,&ans);
1688 eXosip_call_send_answer(ev->tid,200,ans);
1690 }else if(MSG_IS_REFER(ev->request)){
1691 SalOp *op=find_op(sal,ev);
1693 ms_message("Receiving REFER request !");
1694 process_refer(sal,op,ev);
1695 }else if(MSG_IS_NOTIFY(ev->request)){
1696 process_notify(sal,ev);
1697 }else if (MSG_IS_OPTIONS(ev->request)){
1699 eXosip_call_build_answer(ev->tid,200,&ans);
1701 fill_options_answer(ans);
1702 eXosip_call_send_answer(ev->tid,200,ans);
1706 }else ms_warning("call_message_new: No request ?");
1709 static void inc_update(Sal *sal, eXosip_event_t *ev){
1710 osip_message_t *msg=NULL;
1711 ms_message("Processing incoming UPDATE");
1713 eXosip_message_build_answer(ev->tid,200,&msg);
1715 eXosip_message_send_answer(ev->tid,200,msg);
1719 static bool_t comes_from_local_if(osip_message_t *msg){
1720 osip_via_t *via=NULL;
1721 osip_message_get_via(msg,0,&via);
1724 host=osip_via_get_host(via);
1725 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1726 osip_generic_param_t *param=NULL;
1727 osip_via_param_get_byname(via,"received",¶m);
1728 if (param==NULL) return TRUE;
1729 if (param->gvalue &&
1730 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1738 static void text_received(Sal *sal, eXosip_event_t *ev){
1739 osip_body_t *body=NULL;
1740 char *from=NULL,*msg=NULL;
1741 osip_content_type_t* content_type;
1742 osip_uri_param_t* external_body_url;
1743 char unquoted_external_body_url [256];
1744 int external_body_size=0;
1746 char message_id[256]={0};
1748 content_type= osip_message_get_content_type(ev->request);
1749 if (!content_type) {
1750 ms_error("Could not get message because no content type");
1753 osip_from_to_str(ev->request->from,&from);
1754 if (content_type->type
1755 && strcmp(content_type->type, "text")==0
1756 && content_type->subtype
1757 && strcmp(content_type->subtype, "plain")==0 ) {
1758 osip_message_get_body(ev->request,0,&body);
1760 ms_error("Could not get text message from SIP body");
1765 }else if (content_type->type
1766 && strcmp(content_type->type, "message")==0
1767 && content_type->subtype
1768 && strcmp(content_type->subtype, "external-body")==0 ) {
1770 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1771 /*remove both first and last character*/
1772 strncpy(unquoted_external_body_url
1773 ,&external_body_url->gvalue[1]
1774 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1775 unquoted_external_body_url[external_body_size-1]='\0';
1777 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1781 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1785 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1786 salmsg.message_id=message_id;
1787 sal->callbacks.text_received(sal,&salmsg);
1793 static void other_request(Sal *sal, eXosip_event_t *ev){
1794 ms_message("in other_request");
1795 if (ev->request==NULL) return;
1796 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1797 text_received(sal,ev);
1798 eXosip_message_send_answer(ev->tid,200,NULL);
1799 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1800 osip_message_t *options=NULL;
1801 eXosip_options_build_answer(ev->tid,200,&options);
1802 fill_options_answer(options);
1803 eXosip_options_send_answer(ev->tid,200,options);
1804 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1805 ms_message("Receiving REFER request !");
1806 if (comes_from_local_if(ev->request)) {
1807 process_refer(sal,NULL,ev);
1808 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1809 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1814 osip_message_to_str(ev->request,&tmp,&msglen);
1816 ms_message("Unsupported request received:\n%s",tmp);
1819 /*answer with a 501 Not implemented*/
1820 eXosip_message_send_answer(ev->tid,501,NULL);
1824 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1825 osip_via_t *via=NULL;
1826 osip_message_get_via(msg,0,&via);
1828 osip_free(via->port);
1829 via->port=osip_strdup(port);
1830 osip_free(via->host);
1831 via->host=osip_strdup(ip);
1836 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1837 osip_contact_t *ctt=NULL;
1838 const char *received;
1840 SalTransport transport;
1843 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1844 osip_message_get_contact(request,0,&ctt);
1846 ms_warning("fix_message_contact(): no contact to update");
1849 if (expire_last_contact){
1850 osip_contact_t *oldct=NULL,*prevct;
1851 osip_generic_param_t *param=NULL;
1852 osip_contact_clone(ctt,&oldct);
1853 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1854 osip_contact_free(prevct);
1855 osip_list_remove(&request->contacts,1);
1857 osip_list_add(&request->contacts,oldct,1);
1858 osip_contact_param_get_byname(oldct,"expires",¶m);
1860 if (param->gvalue) osip_free(param->gvalue);
1861 param->gvalue=osip_strdup("0");
1863 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1866 if (ctt->url->host!=NULL){
1867 osip_free(ctt->url->host);
1869 ctt->url->host=osip_strdup(received);
1870 if (ctt->url->port!=NULL){
1871 osip_free(ctt->url->port);
1873 snprintf(port,sizeof(port),"%i",rport);
1874 ctt->url->port=osip_strdup(port);
1875 if (op->masquerade_via) masquerade_via(request,received,port);
1877 if (transport != SalTransportUDP) {
1878 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1883 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1884 osip_contact_t *ctt=NULL;
1885 SalAddress* ori_contact_address=NULL;
1886 const char *received;
1888 SalTransport transport;
1890 osip_message_t *msg=NULL;
1891 Sal* sal=op->base.root;
1893 bool_t found_valid_contact=FALSE;
1894 bool_t from_request=FALSE;
1896 if (sal->double_reg==FALSE ) return FALSE;
1898 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1901 osip_message_get_contact(last_answer,i,&ctt);
1902 if (!from_request && ctt==NULL) {
1903 osip_message_get_contact(orig_request,0,&ctt);
1907 osip_contact_to_str(ctt,&tmp);
1908 ori_contact_address = sal_address_new(tmp);
1910 /*check if contact is up to date*/
1911 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1912 && sal_address_get_port_int(ori_contact_address) == rport
1913 && sal_address_get_transport(ori_contact_address) == transport) {
1915 ms_message("Register response has up to date contact, doing nothing.");
1917 ms_warning("Register response does not have up to date contact, but last request had."
1918 "Stupid registrar detected, giving up.");
1920 found_valid_contact=TRUE;
1923 sal_address_destroy(ori_contact_address);
1926 }while(!found_valid_contact);
1927 if (!found_valid_contact)
1928 ms_message("Contact do not match, resending register.");
1932 eXosip_register_build_register(op->rid,op->expires,&msg);
1935 ms_warning("Fail to create a contact updated register.");
1938 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1939 eXosip_register_send_register(op->rid,msg);
1941 ms_message("Resending new register with updated contact");
1942 update_contact_from_response(op,last_answer);
1945 ms_warning("Fail to send updated register.");
1953 static void registration_success(Sal *sal, eXosip_event_t *ev){
1954 SalOp *op=sal_find_register(sal,ev->rid);
1955 osip_header_t *h=NULL;
1958 ms_error("Receiving register response for unknown operation");
1961 osip_message_get_expires(ev->request,0,&h);
1962 if (h!=NULL && atoi(h->hvalue)!=0){
1964 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1965 sal->callbacks.register_success(op,registered);
1968 sal->callbacks.register_success(op,FALSE);
1972 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1974 const char *reason=NULL;
1975 SalOp *op=sal_find_register(sal,ev->rid);
1976 SalReason sr=SalReasonUnknown;
1977 SalError se=SalErrorUnknown;
1980 ms_error("Receiving register failure for unknown operation");
1984 status_code=osip_message_get_status_code(ev->response);
1985 reason=osip_message_get_reason_phrase(ev->response);
1987 switch(status_code){
1990 return process_authentication(sal,ev);
1992 case 423: /*interval too brief*/
1993 {/*retry with greater interval */
1994 osip_header_t *h=NULL;
1995 osip_message_t *msg=NULL;
1996 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1997 if (h && h->hvalue && h->hvalue[0]!='\0'){
1998 int val=atoi(h->hvalue);
1999 if (val>op->expires)
2001 }else op->expires*=2;
2003 eXosip_register_build_register(op->rid,op->expires,&msg);
2004 eXosip_register_send_register(op->rid,msg);
2008 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
2009 in vias, such as ekiga.net
2010 On the opposite, freephonie.net bugs when via are masqueraded.
2012 op->masquerade_via=TRUE;
2014 /* if contact is up to date, process the failure, otherwise resend a new register with
2015 updated contact first, just in case the faillure is due to incorrect contact */
2016 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2017 return TRUE; /*we are retrying with an updated contact*/
2018 if (status_code==403){
2020 sr=SalReasonForbidden;
2021 }else if (status_code==0){
2022 se=SalErrorNoResponse;
2024 sal->callbacks.register_failure(op,se,sr,reason);
2029 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2030 SalOp *op=find_op(sal,ev);
2032 ms_warning("other_request_reply(): Receiving response to unknown request.");
2036 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2037 update_contact_from_response(op,ev->response);
2038 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2039 sal->callbacks.ping_reply(op);
2041 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2042 /*out of call message acknolegment*/
2043 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2045 if (ev->response->status_code<200){
2046 status=SalTextDeliveryInProgress;
2047 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2048 status=SalTextDeliveryDone;
2051 sal->callbacks.text_delivery_update(op,status);
2055 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2056 SalOp *op=find_op(sal,ev);
2058 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2059 if (op->sipfrag_pending){
2060 send_notify_for_refer(op->did,op->sipfrag_pending);
2061 op->sipfrag_pending=NULL;
2067 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2068 ms_message("linphone process event get a message %d\n",ev->type);
2070 case EXOSIP_CALL_ANSWERED:
2071 ms_message("CALL_ANSWERED\n");
2072 call_accepted(sal,ev);
2073 authentication_ok(sal,ev);
2075 case EXOSIP_CALL_CLOSED:
2076 case EXOSIP_CALL_CANCELLED:
2077 ms_message("CALL_CLOSED or CANCELLED\n");
2078 call_terminated(sal,ev);
2080 case EXOSIP_CALL_TIMEOUT:
2081 case EXOSIP_CALL_NOANSWER:
2082 ms_message("CALL_TIMEOUT or NOANSWER\n");
2083 return call_failure(sal,ev);
2085 case EXOSIP_CALL_REQUESTFAILURE:
2086 case EXOSIP_CALL_GLOBALFAILURE:
2087 case EXOSIP_CALL_SERVERFAILURE:
2088 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2089 return call_failure(sal,ev);
2091 case EXOSIP_CALL_RELEASED:
2092 ms_message("CALL_RELEASED\n");
2093 call_released(sal, ev);
2095 case EXOSIP_CALL_INVITE:
2096 ms_message("CALL_NEW\n");
2097 inc_new_call(sal,ev);
2099 case EXOSIP_CALL_REINVITE:
2100 handle_reinvite(sal,ev);
2102 case EXOSIP_CALL_ACK:
2103 ms_message("CALL_ACK");
2106 case EXOSIP_CALL_REDIRECTED:
2107 ms_message("CALL_REDIRECTED");
2108 eXosip_default_action(ev);
2110 case EXOSIP_CALL_PROCEEDING:
2111 ms_message("CALL_PROCEEDING");
2112 call_proceeding(sal,ev);
2114 case EXOSIP_CALL_RINGING:
2115 ms_message("CALL_RINGING");
2116 call_ringing(sal,ev);
2117 authentication_ok(sal,ev);
2119 case EXOSIP_CALL_MESSAGE_NEW:
2120 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2121 call_message_new(sal,ev);
2123 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2125 (ev->response->status_code==407 || ev->response->status_code==401)){
2126 return process_authentication(sal,ev);
2129 case EXOSIP_CALL_MESSAGE_ANSWERED:
2130 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2131 process_in_call_reply(sal,ev);
2133 case EXOSIP_IN_SUBSCRIPTION_NEW:
2134 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2135 sal_exosip_subscription_recv(sal,ev);
2137 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2138 ms_message("CALL_SUBSCRIPTION_NEW ");
2139 sal_exosip_in_subscription_closed(sal,ev);
2141 case EXOSIP_SUBSCRIPTION_UPDATE:
2142 ms_message("CALL_SUBSCRIPTION_UPDATE");
2144 case EXOSIP_SUBSCRIPTION_NOTIFY:
2145 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2146 sal_exosip_notify_recv(sal,ev);
2148 case EXOSIP_SUBSCRIPTION_ANSWERED:
2149 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2150 sal_exosip_subscription_answered(sal,ev);
2152 case EXOSIP_SUBSCRIPTION_CLOSED:
2153 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2154 sal_exosip_subscription_closed(sal,ev);
2156 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2157 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2158 return process_authentication(sal,ev);
2160 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2161 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2162 sal_exosip_subscription_closed(sal,ev);
2164 case EXOSIP_REGISTRATION_FAILURE:
2165 ms_message("REGISTRATION_FAILURE\n");
2166 return registration_failure(sal,ev);
2168 case EXOSIP_REGISTRATION_SUCCESS:
2169 authentication_ok(sal,ev);
2170 registration_success(sal,ev);
2172 case EXOSIP_MESSAGE_NEW:
2173 other_request(sal,ev);
2175 case EXOSIP_MESSAGE_PROCEEDING:
2176 case EXOSIP_MESSAGE_ANSWERED:
2177 case EXOSIP_MESSAGE_REDIRECTED:
2178 case EXOSIP_MESSAGE_SERVERFAILURE:
2179 case EXOSIP_MESSAGE_GLOBALFAILURE:
2180 other_request_reply(sal,ev);
2182 case EXOSIP_MESSAGE_REQUESTFAILURE:
2183 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2185 switch (ev->response->status_code) {
2188 return process_authentication(sal,ev);
2190 eXosip_automatic_action ();
2195 other_request_reply(sal,ev);
2198 ms_message("Unhandled exosip event ! %i",ev->type);
2204 int sal_iterate(Sal *sal){
2206 while((ev=eXosip_event_wait(0,0))!=NULL){
2207 if (process_event(sal,ev))
2208 eXosip_event_free(ev);
2210 #ifdef HAVE_EXOSIP_TRYLOCK
2211 if (eXosip_trylock()==0){
2212 eXosip_automatic_refresh();
2215 ms_warning("eXosip_trylock busy.");
2219 eXosip_automatic_refresh();
2225 static void register_set_contact(osip_message_t *msg, const char *contact){
2226 osip_uri_param_t *param = NULL;
2227 osip_contact_t *ct=NULL;
2229 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2230 osip_message_get_contact(msg,0,&ct);
2232 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2233 if (param && param->gvalue)
2234 line=osip_strdup(param->gvalue);
2236 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2237 osip_message_set_contact(msg,contact);
2238 osip_message_get_contact(msg,0,&ct);
2239 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2242 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2243 osip_route_t *route;
2245 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2247 osip_route_init(&route);
2248 if (osip_route_parse(route,proxy)==0){
2249 osip_uri_param_t *lr_param = NULL;
2250 osip_uri_uparam_get_byname(route->url, "lr", &lr_param);
2251 if (lr_param == NULL){
2252 osip_uri_uparam_add(route->url,osip_strdup("lr"),NULL);
2254 osip_list_add(&msg->routes,route,0);
2257 osip_route_free(route);
2261 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2262 osip_message_t *msg;
2263 const char *contact=sal_op_get_contact(h);
2265 sal_op_set_route(h,proxy);
2267 SalAddress *from_parsed=sal_address_new(from);
2269 char *uri, *domain_ptr = NULL;
2270 if (from_parsed==NULL) {
2271 ms_warning("sal_register() bad from %s",from);
2274 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2275 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2276 uri = sal_address_as_string_uri_only(from_parsed);
2277 if (uri) domain_ptr = strchr(uri, '@');
2279 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2281 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2283 if (uri) ms_free(uri);
2284 sal_address_destroy(from_parsed);
2286 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2288 if (contact) register_set_contact(msg,contact);
2289 sal_register_add_route(msg,proxy);
2290 sal_add_register(h->base.root,h);
2292 ms_error("Could not build initial register.");
2298 eXosip_register_build_register(h->rid,expires,&msg);
2299 sal_register_add_route(msg,proxy);
2302 eXosip_register_send_register(h->rid,msg);
2306 return (msg != NULL) ? 0 : -1;
2309 int sal_register_refresh(SalOp *op, int expires){
2310 osip_message_t *msg=NULL;
2311 const char *contact=sal_op_get_contact(op);
2314 ms_error("Unexistant registration context, not possible to refresh.");
2317 #ifdef HAVE_EXOSIP_TRYLOCK
2320 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2321 * 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
2322 * the exosip lock in a non blocking way, and give up if it takes too long*/
2323 while (eXosip_trylock()!=0){
2325 if (tries>30) {/*after 3 seconds, give up*/
2326 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2334 eXosip_register_build_register(op->rid,expires,&msg);
2336 if (contact) register_set_contact(msg,contact);
2337 sal_register_add_route(msg,sal_op_get_route(op));
2338 eXosip_register_send_register(op->rid,msg);
2339 }else ms_error("Could not build REGISTER refresh message.");
2341 return (msg != NULL) ? 0 : -1;
2345 int sal_unregister(SalOp *h){
2346 osip_message_t *msg=NULL;
2348 eXosip_register_build_register(h->rid,0,&msg);
2349 if (msg) eXosip_register_send_register(h->rid,msg);
2350 else ms_warning("Could not build unREGISTER !");
2355 SalAddress * sal_address_new(const char *uri){
2357 osip_from_init(&from);
2359 // Remove front spaces
2360 while (uri[0]==' ') {
2364 if (osip_from_parse(from,uri)!=0){
2365 osip_from_free(from);
2368 if (from->displayname!=NULL && from->displayname[0]=='"'){
2369 char *unquoted=osip_strdup_without_quote(from->displayname);
2370 osip_free(from->displayname);
2371 from->displayname=unquoted;
2373 return (SalAddress*)from;
2376 SalAddress * sal_address_clone(const SalAddress *addr){
2377 osip_from_t *ret=NULL;
2378 osip_from_clone((osip_from_t*)addr,&ret);
2379 return (SalAddress*)ret;
2382 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2384 const char *sal_address_get_scheme(const SalAddress *addr){
2385 const osip_from_t *u=(const osip_from_t*)addr;
2386 return null_if_empty(u->url->scheme);
2389 const char *sal_address_get_display_name(const SalAddress* addr){
2390 const osip_from_t *u=(const osip_from_t*)addr;
2391 return null_if_empty(u->displayname);
2394 const char *sal_address_get_username(const SalAddress *addr){
2395 const osip_from_t *u=(const osip_from_t*)addr;
2396 return null_if_empty(u->url->username);
2399 const char *sal_address_get_domain(const SalAddress *addr){
2400 const osip_from_t *u=(const osip_from_t*)addr;
2401 return null_if_empty(u->url->host);
2404 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2405 osip_from_t *u=(osip_from_t*)addr;
2406 if (u->displayname!=NULL){
2407 osip_free(u->displayname);
2408 u->displayname=NULL;
2410 if (display_name!=NULL && display_name[0]!='\0'){
2411 u->displayname=osip_strdup(display_name);
2415 void sal_address_set_username(SalAddress *addr, const char *username){
2416 osip_from_t *uri=(osip_from_t*)addr;
2417 if (uri->url->username!=NULL){
2418 osip_free(uri->url->username);
2419 uri->url->username=NULL;
2422 uri->url->username=osip_strdup(username);
2425 void sal_address_set_domain(SalAddress *addr, const char *host){
2426 osip_from_t *uri=(osip_from_t*)addr;
2427 if (uri->url->host!=NULL){
2428 osip_free(uri->url->host);
2429 uri->url->host=NULL;
2432 uri->url->host=osip_strdup(host);
2435 void sal_address_set_port(SalAddress *addr, const char *port){
2436 osip_from_t *uri=(osip_from_t*)addr;
2437 if (uri->url->port!=NULL){
2438 osip_free(uri->url->port);
2439 uri->url->port=NULL;
2442 uri->url->port=osip_strdup(port);
2445 void sal_address_set_port_int(SalAddress *uri, int port){
2448 /*this is the default, special case to leave the port field blank*/
2449 sal_address_set_port(uri,NULL);
2452 snprintf(tmp,sizeof(tmp),"%i",port);
2453 sal_address_set_port(uri,tmp);
2456 void sal_address_clean(SalAddress *addr){
2457 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2458 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2461 char *sal_address_as_string(const SalAddress *u){
2463 osip_from_t *from=(osip_from_t *)u;
2464 char *old_displayname=NULL;
2465 /* hack to force use of quotes around the displayname*/
2466 if (from->displayname!=NULL
2467 && from->displayname[0]!='"'){
2468 old_displayname=from->displayname;
2469 from->displayname=osip_enquote(from->displayname);
2471 osip_from_to_str(from,&tmp);
2472 if (old_displayname!=NULL){
2473 ms_free(from->displayname);
2474 from->displayname=old_displayname;
2481 char *sal_address_as_string_uri_only(const SalAddress *u){
2482 char *tmp=NULL,*ret;
2483 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2488 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2489 osip_uri_param_t *param=NULL;
2490 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2492 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2494 osip_free(param->gvalue);
2495 param->gvalue=value ? osip_strdup(value) : NULL;
2500 void sal_address_destroy(SalAddress *u){
2501 osip_from_free((osip_from_t*)u);
2504 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2505 ctx->keepalive_period=value;
2506 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2508 unsigned int sal_get_keepalive_period(Sal *ctx) {
2509 return ctx->keepalive_period;
2512 const char * sal_address_get_port(const SalAddress *addr) {
2513 const osip_from_t *u=(const osip_from_t*)addr;
2514 return null_if_empty(u->url->port);
2517 int sal_address_get_port_int(const SalAddress *uri) {
2518 const char* port = sal_address_get_port(uri);
2525 SalTransport sal_address_get_transport(const SalAddress* addr) {
2526 const osip_from_t *u=(const osip_from_t*)addr;
2527 osip_uri_param_t *transport_param=NULL;
2528 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2529 if (transport_param == NULL){
2530 return SalTransportUDP;
2532 return sal_transport_parse(transport_param->gvalue);
2535 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2536 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2539 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2540 int sal_call_update(SalOp *h, const char *subject){
2542 osip_message_t *reinvite=NULL;
2545 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2550 osip_message_set_subject(reinvite,subject);
2551 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2552 if (h->base.contact){
2553 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2554 osip_message_set_contact(reinvite,h->base.contact);
2556 if (h->base.root->session_expires!=0){
2557 osip_message_set_header(reinvite, "Session-expires", "200");
2558 osip_message_set_supported(reinvite, "timer");
2560 if (h->base.local_media){
2561 h->sdp_offering=TRUE;
2562 set_sdp_from_desc(reinvite,h->base.local_media);
2563 }else h->sdp_offering=FALSE;
2565 err = eXosip_call_send_request(h->did, reinvite);
2569 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2570 ctx->reuse_authorization=value;