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;
289 void sal_uninit(Sal* sal){
292 ms_free(sal->rootCa);
296 void sal_set_user_pointer(Sal *sal, void *user_data){
300 void *sal_get_user_pointer(const Sal *sal){
304 static void unimplemented_stub(){
305 ms_warning("Unimplemented SAL callback");
308 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
309 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
310 if (ctx->callbacks.call_received==NULL)
311 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
312 if (ctx->callbacks.call_ringing==NULL)
313 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
314 if (ctx->callbacks.call_accepted==NULL)
315 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
316 if (ctx->callbacks.call_failure==NULL)
317 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
318 if (ctx->callbacks.call_terminated==NULL)
319 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
320 if (ctx->callbacks.call_released==NULL)
321 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
322 if (ctx->callbacks.call_updating==NULL)
323 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
324 if (ctx->callbacks.auth_requested==NULL)
325 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
326 if (ctx->callbacks.auth_success==NULL)
327 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
328 if (ctx->callbacks.register_success==NULL)
329 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
330 if (ctx->callbacks.register_failure==NULL)
331 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
332 if (ctx->callbacks.dtmf_received==NULL)
333 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
334 if (ctx->callbacks.notify==NULL)
335 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
336 if (ctx->callbacks.notify_presence==NULL)
337 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
338 if (ctx->callbacks.subscribe_received==NULL)
339 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
340 if (ctx->callbacks.text_received==NULL)
341 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
342 if (ctx->callbacks.ping_reply==NULL)
343 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
344 if (ctx->callbacks.message_external_body==NULL)
345 ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)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 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
386 int proto=IPPROTO_UDP;
387 int keepalive = ctx->keepalive_period;
390 case SalTransportUDP:
392 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
394 case SalTransportTCP:
395 case SalTransportTLS:
398 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
399 set_tls_options(ctx);
402 ms_warning("unexpected proto, using datagram");
404 /*see if it looks like an IPv6 address*/
405 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
406 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
407 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
408 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
410 ipv6=strchr(addr,':')!=NULL;
411 eXosip_enable_ipv6(ipv6);
413 if (is_secure && tr == SalTransportUDP){
414 ms_fatal("SIP over DTLS is not supported yet.");
417 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
422 ortp_socket_t sal_get_socket(Sal *ctx){
423 #ifdef HAVE_EXOSIP_GET_SOCKET
424 return eXosip_get_socket(IPPROTO_UDP);
426 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
431 void sal_set_user_agent(Sal *ctx, const char *user_agent){
432 eXosip_set_user_agent(user_agent);
435 void sal_use_session_timers(Sal *ctx, int expires){
436 ctx->session_expires=expires;
439 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
440 ctx->one_matching_codec=one_matching_codec;
443 MSList *sal_get_pending_auths(Sal *sal){
444 return ms_list_copy(sal->pending_auths);
447 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
448 ctx->double_reg=enabled;
451 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
452 ctx->expire_old_contact=enabled;
455 void sal_use_rport(Sal *ctx, bool_t use_rports){
456 ctx->use_rports=use_rports;
458 void sal_use_101(Sal *ctx, bool_t use_101){
459 ctx->use_101=use_101;
462 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
464 ms_free(ctx->rootCa);
465 ctx->rootCa = ms_strdup(rootCa);
466 set_tls_options(ctx);
469 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
470 ctx->verify_server_certs=verify;
471 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
472 eXosip_tls_verify_certificate(verify);
476 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
477 osip_via_t *via=NULL;
478 osip_generic_param_t *param=NULL;
479 const char *rport=NULL;
483 osip_message_get_via(msg,0,&via);
485 ms_warning("extract_received_rport(): no via.");
489 *transport = sal_transport_parse(via->protocol);
491 if (via->port && via->port[0]!='\0')
492 *rportval=atoi(via->port);
494 osip_via_param_get_byname(via,"rport",¶m);
497 if (rport && rport[0]!='\0') *rportval=atoi(rport);
501 osip_via_param_get_byname(via,"received",¶m);
502 if (param) *received=param->gvalue;
504 if (rport==NULL && *received==NULL){
505 ms_warning("extract_received_rport(): no rport and no received parameters.");
511 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
515 sdp_message_to_str(msg,&sdp);
517 snprintf(clen,sizeof(clen),"%i",sdplen);
518 osip_message_set_body(sip,sdp,sdplen);
519 osip_message_set_content_type(sip,"application/sdp");
520 osip_message_set_content_length(sip,clen);
524 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
525 sdp_message_t *msg=media_description_to_sdp(desc);
527 ms_error("Fail to print sdp message !");
531 sdp_message_free(msg);
534 static void sdp_process(SalOp *h){
535 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
537 sal_media_description_unref(h->result);
539 h->result=sal_media_description_new();
540 if (h->sdp_offering){
541 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
545 sdp_message_free(h->sdp_answer);
547 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
548 h->sdp_answer=media_description_to_sdp(h->result);
549 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
550 It should contains media parameters constraint from the remote offer, not our response*/
551 strcpy(h->result->addr,h->base.remote_media->addr);
552 h->result->bandwidth=h->base.remote_media->bandwidth;
554 for(i=0;i<h->result->nstreams;++i){
555 if (h->result->streams[i].rtp_port>0){
556 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
557 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
558 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
559 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
560 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
561 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
563 if (h->result->streams[i].proto == SalProtoRtpSavp) {
564 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
572 int sal_call_is_offerer(const SalOp *h){
573 return h->sdp_offering;
576 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
578 sal_media_description_ref(desc);
579 if (h->base.local_media)
580 sal_media_description_unref(h->base.local_media);
581 h->base.local_media=desc;
582 if (h->base.remote_media){
583 /*case of an incoming call where we modify the local capabilities between the time
584 * the call is ringing and it is accepted (for example if you want to accept without video*/
585 /*reset the sdp answer so that it is computed again*/
587 sdp_message_free(h->sdp_answer);
594 int sal_call(SalOp *h, const char *from, const char *to){
597 osip_message_t *invite=NULL;
598 sal_op_set_from(h,from);
600 sal_exosip_fix_route(h);
602 h->terminated = FALSE;
604 route = sal_op_get_route(h);
605 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
607 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
608 err, from, to, route);
611 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
612 if (h->base.contact){
613 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
614 osip_message_set_contact(invite,h->base.contact);
616 if (h->base.root->session_expires!=0){
617 osip_message_set_header(invite, "Session-expires", "200");
618 osip_message_set_supported(invite, "timer");
620 if (h->base.local_media){
621 h->sdp_offering=TRUE;
622 set_sdp_from_desc(invite,h->base.local_media);
623 }else h->sdp_offering=FALSE;
625 osip_message_set_header(invite,"Replaces",h->replaces);
627 osip_message_set_header(invite,"Referred-By",h->referred_by);
631 err=eXosip_call_send_initial_invite(invite);
635 ms_error("Fail to send invite ! Error code %d", err);
638 sal_add_call(h->base.root,h);
643 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
646 /*if early media send also 180 and 183 */
650 eXosip_call_build_answer(h->tid,183,&msg);
654 set_sdp(msg,h->sdp_answer);
655 sdp_message_free(h->sdp_answer);
658 eXosip_call_send_answer(h->tid,183,msg);
663 eXosip_call_send_answer(h->tid,180,NULL);
669 int sal_call_accept(SalOp * h){
671 const char *contact=sal_op_get_contact(h);
673 int err=eXosip_call_build_answer(h->tid,200,&msg);
674 if (err<0 || msg==NULL){
675 ms_error("Fail to build answer for call: err=%i",err);
678 if (h->base.root->session_expires!=0){
679 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
683 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
684 osip_message_set_contact(msg,contact);
687 if (h->base.local_media){
688 /*this is the case where we received an invite without SDP*/
689 if (h->sdp_offering) {
690 set_sdp_from_desc(msg,h->base.local_media);
692 if (h->sdp_answer==NULL) sdp_process(h);
694 set_sdp(msg,h->sdp_answer);
695 sdp_message_free(h->sdp_answer);
700 ms_error("You are accepting a call but not defined any media capabilities !");
702 eXosip_call_send_answer(h->tid,200,msg);
706 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
707 if (reason==SalReasonBusy){
709 eXosip_call_send_answer(h->tid,486,NULL);
712 else if (reason==SalReasonTemporarilyUnavailable){
714 eXosip_call_send_answer(h->tid,480,NULL);
716 }else if (reason==SalReasonDoNotDisturb){
718 eXosip_call_send_answer(h->tid,600,NULL);
720 }else if (reason==SalReasonMedia){
722 eXosip_call_send_answer(h->tid,415,NULL);
724 }else if (redirect!=NULL && reason==SalReasonRedirect){
727 if (strstr(redirect,"sip:")!=0) code=302;
730 eXosip_call_build_answer(h->tid,code,&msg);
731 osip_message_set_contact(msg,redirect);
732 eXosip_call_send_answer(h->tid,code,msg);
734 }else sal_call_terminate(h);
738 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
739 return h->base.remote_media;
742 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
743 if (h->base.local_media && h->base.remote_media && !h->result){
749 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
750 if (refered_call->replaces)
751 h->replaces=ms_strdup(refered_call->replaces);
752 if (refered_call->referred_by)
753 h->referred_by=ms_strdup(refered_call->referred_by);
757 static int send_notify_for_refer(int did, const char *sipfrag){
760 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
763 ms_warning("Could not build NOTIFY for refer.");
766 osip_message_set_content_type(msg,"message/sipfrag");
767 osip_message_set_header(msg,"Event","refer");
768 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
769 eXosip_call_send_request(did,msg);
774 /* currently only support to notify trying and 200Ok*/
775 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
778 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
780 else if (newcall->cid!=-1){
781 if (newcall->did==-1){
782 /* not yet established*/
783 if (!newcall->terminated){
785 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
788 if (!newcall->terminated){
789 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
790 /* we need previous notify transaction to complete, so buffer the request for later*/
791 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
799 int sal_ping(SalOp *op, const char *from, const char *to){
800 osip_message_t *options=NULL;
802 sal_op_set_from(op,from);
803 sal_op_set_to(op,to);
804 sal_exosip_fix_route(op);
806 eXosip_options_build_request (&options, sal_op_get_to(op),
807 sal_op_get_from(op),sal_op_get_route(op));
809 if (op->base.root->session_expires!=0){
810 osip_message_set_header(options, "Session-expires", "200");
811 osip_message_set_supported(options, "timer");
813 sal_add_other(sal_op_get_sal(op),op,options);
814 return eXosip_options_send_request(options);
819 int sal_call_refer(SalOp *h, const char *refer_to){
820 osip_message_t *msg=NULL;
823 eXosip_call_build_refer(h->did,refer_to, &msg);
824 if (msg) err=eXosip_call_send_request(h->did, msg);
830 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
831 osip_message_t *msg=NULL;
832 char referto[256]={0};
835 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
836 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
840 eXosip_call_build_refer(h->did,referto, &msg);
841 osip_message_set_header(msg,"Referred-By",h->base.from);
842 if (msg) err=eXosip_call_send_request(h->did, msg);
848 SalOp *sal_call_get_replaces(SalOp *h){
849 if (h!=NULL && h->replaces!=NULL){
852 cid=eXosip_call_find_by_replaces(h->replaces);
855 SalOp *ret=sal_find_call(h->base.root,cid);
862 int sal_call_send_dtmf(SalOp *h, char dtmf){
863 osip_message_t *msg=NULL;
868 eXosip_call_build_info(h->did,&msg);
870 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
871 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
872 osip_message_set_content_type(msg,"application/dtmf-relay");
873 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
874 osip_message_set_content_length(msg,clen);
875 eXosip_call_send_request(h->did,msg);
881 static void push_auth_to_exosip(const SalAuthInfo *info){
883 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
884 else userid=info->userid;
885 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
886 eXosip_add_authentication_info (info->username,userid,
887 info->password, NULL,info->realm);
890 * Just for symmetry ;-)
892 static void pop_auth_from_exosip() {
893 eXosip_clear_authentication_info();
896 int sal_call_terminate(SalOp *h){
898 if (h == NULL) return -1;
899 if (h->auth_info) push_auth_to_exosip(h->auth_info);
901 err=eXosip_call_terminate(h->cid,h->did);
903 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
905 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
911 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
912 if (h->terminated) return;
913 if (h->pending_auth){
914 push_auth_to_exosip(info);
916 /*FIXME exosip does not take into account this update register message*/
918 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
922 update_contact_from_response(h,h->pending_auth->response);
924 eXosip_default_action(h->pending_auth);
926 ms_message("eXosip_default_action() done");
927 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
929 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
930 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
933 void sal_op_cancel_authentication(SalOp *h) {
935 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
936 } else if (h->cid >0) {
937 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
939 ms_warning("Auth failure not handled");
943 static void set_network_origin(SalOp *op, osip_message_t *req){
944 const char *received=NULL;
947 SalTransport transport;
948 if (extract_received_rport(req,&received,&rport,&transport)!=0){
949 osip_via_t *via=NULL;
951 osip_message_get_via(req,0,&via);
952 received=osip_via_get_host(via);
953 tmp=osip_via_get_port(via);
954 if (tmp) rport=atoi(tmp);
956 if (transport != SalTransportUDP) {
957 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
959 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
961 __sal_op_set_network_origin(op,origin);
964 static void set_remote_ua(SalOp* op, osip_message_t *req){
965 if (op->base.remote_ua==NULL){
966 osip_header_t *h=NULL;
967 osip_message_get_user_agent(req,0,&h);
969 op->base.remote_ua=ms_strdup(h->hvalue);
974 static void set_replaces(SalOp *op, osip_message_t *req){
975 osip_header_t *h=NULL;
978 ms_free(op->replaces);
981 osip_message_header_get_byname(req,"replaces",0,&h);
983 if (h->hvalue && h->hvalue[0]!='\0'){
984 op->replaces=ms_strdup(h->hvalue);
989 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
991 return sal_find_call(sal,ev->cid);
994 return sal_find_register(sal,ev->rid);
997 return sal_find_out_subscribe(sal,ev->sid);
1000 return sal_find_in_subscribe(sal,ev->nid);
1002 if (ev->response) return sal_find_other(sal,ev->response);
1003 else if (ev->request) return sal_find_other(sal,ev->request);
1007 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1008 SalOp *op=sal_op_new(sal);
1009 osip_from_t *from,*to;
1010 osip_call_info_t *call_info;
1012 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1014 set_network_origin(op,ev->request);
1015 set_remote_ua(op,ev->request);
1016 set_replaces(op,ev->request);
1019 op->sdp_offering=FALSE;
1020 op->base.remote_media=sal_media_description_new();
1021 sdp_to_media_description(sdp,op->base.remote_media);
1022 sdp_message_free(sdp);
1023 }else op->sdp_offering=TRUE;
1025 from=osip_message_get_from(ev->request);
1026 to=osip_message_get_to(ev->request);
1027 osip_from_to_str(from,&tmp);
1028 sal_op_set_from(op,tmp);
1030 osip_from_to_str(to,&tmp);
1031 sal_op_set_to(op,tmp);
1034 osip_message_get_call_info(ev->request,0,&call_info);
1037 osip_call_info_to_str(call_info,&tmp);
1038 if( strstr(tmp,"answer-after=") != NULL)
1040 op->auto_answer_asked=TRUE;
1041 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1050 sal_add_call(op->base.root,op);
1051 sal->callbacks.call_received(op);
1054 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1055 SalOp *op=find_op(sal,ev);
1059 ms_warning("Reinvite for non-existing operation !");
1064 sdp=eXosip_get_sdp_info(ev->request);
1065 if (op->base.remote_media){
1066 sal_media_description_unref(op->base.remote_media);
1067 op->base.remote_media=NULL;
1070 sal_media_description_unref(op->result);
1074 op->sdp_offering=FALSE;
1075 op->base.remote_media=sal_media_description_new();
1076 sdp_to_media_description(sdp,op->base.remote_media);
1077 sdp_message_free(sdp);
1080 op->sdp_offering=TRUE;
1082 sal->callbacks.call_updating(op);
1085 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1086 SalOp *op=find_op(sal,ev);
1090 ms_warning("ack for non-existing call !");
1093 if (op->terminated) {
1094 ms_warning("ack for terminated call, ignoring");
1098 if (op->sdp_offering){
1099 sdp=eXosip_get_sdp_info(ev->ack);
1101 if (op->base.remote_media)
1102 sal_media_description_unref(op->base.remote_media);
1103 op->base.remote_media=sal_media_description_new();
1104 sdp_to_media_description(sdp,op->base.remote_media);
1106 sdp_message_free(sdp);
1112 sal->callbacks.call_ack(op);
1115 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1116 const char *received;
1118 SalTransport transport;
1119 if (extract_received_rport(response,&received,&rport,&transport)==0){
1120 const char *contact=sal_op_get_contact(op);
1122 /*no contact given yet, use from instead*/
1123 contact=sal_op_get_from(op);
1126 SalAddress *addr=sal_address_new(contact);
1128 sal_address_set_domain(addr,received);
1129 sal_address_set_port_int(addr,rport);
1130 if (transport!=SalTransportUDP)
1131 sal_address_set_transport(addr,transport);
1132 tmp=sal_address_as_string(addr);
1133 ms_message("Contact address updated to %s",tmp);
1134 sal_op_set_contact(op,tmp);
1135 sal_address_destroy(addr);
1141 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1142 SalOp *op=find_op(sal,ev);
1144 if (op==NULL || op->terminated==TRUE) {
1145 ms_warning("This call has been canceled.");
1147 eXosip_call_terminate(ev->cid,ev->did);
1155 /* update contact if received and rport are set by the server
1156 note: will only be used by remote for next INVITE, if any...*/
1157 update_contact_from_response(op,ev->response);
1161 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1163 SalOp *op=find_op(sal,ev);
1164 if (call_proceeding(sal, ev)==-1) return;
1166 set_remote_ua(op,ev->response);
1167 sdp=eXosip_get_sdp_info(ev->response);
1169 op->base.remote_media=sal_media_description_new();
1170 sdp_to_media_description(sdp,op->base.remote_media);
1171 sdp_message_free(sdp);
1172 if (op->base.local_media) sdp_process(op);
1174 sal->callbacks.call_ringing(op);
1177 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1179 osip_message_t *msg=NULL;
1180 SalOp *op=find_op(sal,ev);
1181 const char *contact;
1183 if (op==NULL || op->terminated==TRUE) {
1184 ms_warning("This call has been already terminated.");
1186 eXosip_call_terminate(ev->cid,ev->did);
1192 set_remote_ua(op,ev->response);
1194 sdp=eXosip_get_sdp_info(ev->response);
1196 op->base.remote_media=sal_media_description_new();
1197 sdp_to_media_description(sdp,op->base.remote_media);
1198 sdp_message_free(sdp);
1199 if (op->base.local_media) sdp_process(op);
1201 eXosip_call_build_ack(ev->did,&msg);
1203 ms_warning("This call has been already terminated.");
1205 eXosip_call_terminate(ev->cid,ev->did);
1209 contact=sal_op_get_contact(op);
1211 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1212 osip_message_set_contact(msg,contact);
1214 if (op->sdp_answer){
1215 set_sdp(msg,op->sdp_answer);
1216 sdp_message_free(op->sdp_answer);
1217 op->sdp_answer=NULL;
1219 eXosip_call_send_ack(ev->did,msg);
1220 sal->callbacks.call_accepted(op);
1223 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1225 SalOp *op=find_op(sal,ev);
1227 ms_warning("Call terminated for already closed call ?");
1231 osip_from_to_str(ev->request->from,&from);
1233 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1234 if (from) osip_free(from);
1235 op->terminated=TRUE;
1238 static void call_released(Sal *sal, eXosip_event_t *ev){
1239 SalOp *op=find_op(sal,ev);
1241 ms_warning("No op associated to this call_released()");
1244 if (!op->terminated){
1245 /* no response received so far */
1246 call_failure(sal,ev);
1248 sal->callbacks.call_released(op);
1251 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1252 const char *prx_realm=NULL,*www_realm=NULL;
1253 osip_proxy_authenticate_t *prx_auth;
1254 osip_www_authenticate_t *www_auth;
1256 *username=osip_uri_get_username(resp->from->url);
1257 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1258 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1260 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1262 www_realm=osip_www_authenticate_get_realm(www_auth);
1266 }else if (www_realm){
1274 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1275 osip_authorization_t *auth=NULL;
1276 osip_proxy_authorization_t *prx_auth=NULL;
1278 *username=osip_uri_get_username(msg->from->url);
1279 osip_message_get_authorization(msg, 0, &auth);
1281 *realm=osip_authorization_get_realm(auth);
1284 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1286 *realm=osip_proxy_authorization_get_realm(prx_auth);
1292 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1293 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1294 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1298 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1299 if (op->pending_auth){
1300 return get_auth_data(op->pending_auth,realm,username);
1305 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1307 const char *username,*realm;
1310 ms_warning("No operation associated with this authentication !");
1313 if (get_auth_data(ev,&realm,&username)==0){
1314 if (op->pending_auth!=NULL){
1315 eXosip_event_free(op->pending_auth);
1316 op->pending_auth=ev;
1318 op->pending_auth=ev;
1319 sal_add_pending_auth(sal,op);
1322 sal->callbacks.auth_requested(op,realm,username);
1328 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1330 const char *username,*realm;
1333 ms_warning("No operation associated with this authentication_ok!");
1336 if (op->pending_auth){
1337 eXosip_event_free(op->pending_auth);
1338 sal_remove_pending_auth(sal,op);
1339 op->pending_auth=NULL;
1341 if (get_auth_data(ev,&realm,&username)==0){
1342 sal->callbacks.auth_success(op,realm,username);
1346 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1349 char* computedReason=NULL;
1350 const char *reason=NULL;
1351 SalError error=SalErrorUnknown;
1352 SalReason sr=SalReasonUnknown;
1355 op=(SalOp*)find_op(sal,ev);
1358 ms_warning("Call failure reported for a closed call, ignored.");
1363 code=osip_message_get_status_code(ev->response);
1364 reason=osip_message_get_reason_phrase(ev->response);
1365 osip_header_t *h=NULL;
1366 if (!osip_message_header_get_byname( ev->response
1370 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1371 reason = computedReason;
1379 return process_authentication(sal,ev);
1382 error=SalErrorUnknown;
1385 error=SalErrorFailure;
1386 sr=SalReasonNotFound;
1389 error=SalErrorFailure;
1393 eXosip_default_action(ev);
1397 error=SalErrorFailure;
1398 sr=SalReasonTemporarilyUnavailable;
1400 error=SalErrorFailure;
1406 error=SalErrorFailure;
1407 sr=SalReasonDoNotDisturb;
1410 error=SalErrorFailure;
1411 sr=SalReasonDeclined;
1415 error=SalErrorFailure;
1416 sr=SalReasonUnknown;
1417 }else error=SalErrorNoResponse;
1419 op->terminated=TRUE;
1420 sal->callbacks.call_failure(op,error,sr,reason,code);
1421 if (computedReason != NULL){
1422 ms_free(computedReason);
1427 /* Request remote side to send us VFU */
1428 void sal_call_send_vfu_request(SalOp *h){
1429 osip_message_t *msg=NULL;
1431 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1435 " <picture_fast_update></picture_fast_update>"
1443 eXosip_call_build_info(h->did,&msg);
1445 osip_message_set_body(msg,info_body,strlen(info_body));
1446 osip_message_set_content_type(msg,"application/media_control+xml");
1447 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1448 osip_message_set_content_length(msg,clen);
1449 eXosip_call_send_request(h->did,msg);
1450 ms_message("Sending VFU request !");
1455 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1456 SalOp *op=find_op(sal,ev);
1457 osip_body_t *body=NULL;
1460 ms_warning("media control xml received without operation context!");
1464 osip_message_get_body(ev->request,0,&body);
1465 if (body && body->body!=NULL &&
1466 strstr(body->body,"picture_fast_update")){
1467 osip_message_t *ans=NULL;
1468 ms_message("Receiving VFU request !");
1469 if (sal->callbacks.vfu_request){
1470 sal->callbacks.vfu_request(op);
1471 eXosip_call_build_answer(ev->tid,200,&ans);
1473 eXosip_call_send_answer(ev->tid,200,ans);
1477 /*in all other cases we must say it is not implemented.*/
1479 osip_message_t *ans=NULL;
1481 eXosip_call_build_answer(ev->tid,501,&ans);
1483 eXosip_call_send_answer(ev->tid,501,ans);
1488 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1489 SalOp *op=find_op(sal,ev);
1490 osip_body_t *body=NULL;
1493 ms_warning("media dtmf relay received without operation context!");
1497 osip_message_get_body(ev->request,0,&body);
1498 if (body && body->body!=NULL){
1499 osip_message_t *ans=NULL;
1500 const char *name=strstr(body->body,"Signal");
1501 if (name==NULL) name=strstr(body->body,"signal");
1503 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1506 name+=strlen("signal");
1507 if (sscanf(name," = %1s",tmp)==1){
1508 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1509 if (sal->callbacks.dtmf_received != NULL)
1510 sal->callbacks.dtmf_received(op, tmp[0]);
1514 eXosip_call_build_answer(ev->tid,200,&ans);
1516 eXosip_call_send_answer(ev->tid,200,ans);
1521 static void fill_options_answer(osip_message_t *options){
1522 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1523 osip_message_set_accept(options,"application/sdp");
1526 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1527 osip_header_t *h=NULL;
1528 osip_message_t *ans=NULL;
1529 ms_message("Receiving REFER request !");
1530 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1533 osip_from_t *from=NULL;
1535 osip_from_init(&from);
1537 if (osip_from_parse(from,h->hvalue)==0){
1539 osip_uri_header_t *uh=NULL;
1540 osip_header_t *referred_by=NULL;
1541 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1542 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1543 ms_message("Found replaces in Refer-To");
1545 ms_free(op->replaces);
1547 op->replaces=ms_strdup(uh->gvalue);
1549 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1550 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1551 if (op->referred_by)
1552 ms_free(op->referred_by);
1553 op->referred_by=ms_strdup(referred_by->hvalue);
1556 osip_uri_header_freelist(&from->url->url_headers);
1557 osip_from_to_str(from,&tmp);
1558 sal->callbacks.refer_received(sal,op,tmp);
1560 osip_from_free(from);
1563 eXosip_call_build_answer(ev->tid,202,&ans);
1565 eXosip_call_send_answer(ev->tid,202,ans);
1570 ms_warning("cannot do anything with the refer without destination\n");
1574 static void process_notify(Sal *sal, eXosip_event_t *ev){
1575 osip_header_t *h=NULL;
1577 SalOp *op=find_op(sal,ev);
1578 osip_message_t *ans=NULL;
1580 ms_message("Receiving NOTIFY request !");
1581 osip_from_to_str(ev->request->from,&from);
1582 osip_message_header_get_byname(ev->request,"Event",0,&h);
1584 osip_body_t *body=NULL;
1585 //osip_content_type_t *ct=NULL;
1586 osip_message_get_body(ev->request,0,&body);
1587 //ct=osip_message_get_content_type(ev->request);
1588 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1589 /*special handling of refer events*/
1590 if (body && body->body){
1591 osip_message_t *msg;
1592 osip_message_init(&msg);
1593 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1594 int code=osip_message_get_status_code(msg);
1596 sal->callbacks.notify_refer(op,SalReferTrying);
1597 }else if (code==200){
1598 sal->callbacks.notify_refer(op,SalReferSuccess);
1599 }else if (code>=400){
1600 sal->callbacks.notify_refer(op,SalReferFailed);
1603 osip_message_free(msg);
1606 /*generic handling*/
1607 sal->callbacks.notify(op,from,h->hvalue);
1610 /*answer that we received the notify*/
1612 eXosip_call_build_answer(ev->tid,200,&ans);
1614 eXosip_call_send_answer(ev->tid,200,ans);
1619 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1620 osip_message_t *ans=NULL;
1622 if (MSG_IS_INFO(ev->request)){
1623 osip_content_type_t *ct;
1624 ct=osip_message_get_content_type(ev->request);
1625 if (ct && ct->subtype){
1626 if (strcmp(ct->subtype,"media_control+xml")==0)
1627 process_media_control_xml(sal,ev);
1628 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1629 process_dtmf_relay(sal,ev);
1631 ms_message("Unhandled SIP INFO.");
1632 /*send an "Not implemented" answer*/
1634 eXosip_call_build_answer(ev->tid,501,&ans);
1636 eXosip_call_send_answer(ev->tid,501,ans);
1640 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1642 eXosip_call_build_answer(ev->tid,200,&ans);
1644 eXosip_call_send_answer(ev->tid,200,ans);
1647 }else if(MSG_IS_MESSAGE(ev->request)){
1648 /* SIP messages could be received into call */
1649 text_received(sal, ev);
1651 eXosip_call_build_answer(ev->tid,200,&ans);
1653 eXosip_call_send_answer(ev->tid,200,ans);
1655 }else if(MSG_IS_REFER(ev->request)){
1656 SalOp *op=find_op(sal,ev);
1658 ms_message("Receiving REFER request !");
1659 process_refer(sal,op,ev);
1660 }else if(MSG_IS_NOTIFY(ev->request)){
1661 process_notify(sal,ev);
1662 }else if (MSG_IS_OPTIONS(ev->request)){
1664 eXosip_call_build_answer(ev->tid,200,&ans);
1666 fill_options_answer(ans);
1667 eXosip_call_send_answer(ev->tid,200,ans);
1671 }else ms_warning("call_message_new: No request ?");
1674 static void inc_update(Sal *sal, eXosip_event_t *ev){
1675 osip_message_t *msg=NULL;
1676 ms_message("Processing incoming UPDATE");
1678 eXosip_message_build_answer(ev->tid,200,&msg);
1680 eXosip_message_send_answer(ev->tid,200,msg);
1684 static bool_t comes_from_local_if(osip_message_t *msg){
1685 osip_via_t *via=NULL;
1686 osip_message_get_via(msg,0,&via);
1689 host=osip_via_get_host(via);
1690 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1691 osip_generic_param_t *param=NULL;
1692 osip_via_param_get_byname(via,"received",¶m);
1693 if (param==NULL) return TRUE;
1694 if (param->gvalue &&
1695 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1703 static void text_received(Sal *sal, eXosip_event_t *ev){
1704 osip_body_t *body=NULL;
1705 char *from=NULL,*msg;
1706 osip_content_type_t* content_type;
1707 osip_uri_param_t* external_body_url;
1708 char unquoted_external_body_url [256];
1709 int external_body_size=0;
1711 content_type= osip_message_get_content_type(ev->request);
1712 if (!content_type) {
1713 ms_error("Could not get message because no content type");
1716 osip_from_to_str(ev->request->from,&from);
1717 if (content_type->type
1718 && strcmp(content_type->type, "text")==0
1719 && content_type->subtype
1720 && strcmp(content_type->subtype, "plain")==0 ) {
1721 osip_message_get_body(ev->request,0,&body);
1723 ms_error("Could not get text message from SIP body");
1727 sal->callbacks.text_received(sal,from,msg);
1728 } if (content_type->type
1729 && strcmp(content_type->type, "message")==0
1730 && content_type->subtype
1731 && strcmp(content_type->subtype, "external-body")==0 ) {
1733 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1734 /*remove both first and last character*/
1735 strncpy(unquoted_external_body_url
1736 ,&external_body_url->gvalue[1]
1737 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1738 unquoted_external_body_url[external_body_size-1]='\0';
1739 sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
1742 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1749 static void other_request(Sal *sal, eXosip_event_t *ev){
1750 ms_message("in other_request");
1751 if (ev->request==NULL) return;
1752 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1753 text_received(sal,ev);
1754 eXosip_message_send_answer(ev->tid,200,NULL);
1755 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1756 osip_message_t *options=NULL;
1757 eXosip_options_build_answer(ev->tid,200,&options);
1758 fill_options_answer(options);
1759 eXosip_options_send_answer(ev->tid,200,options);
1760 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1761 ms_message("Receiving REFER request !");
1762 if (comes_from_local_if(ev->request)) {
1763 process_refer(sal,NULL,ev);
1764 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1765 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1770 osip_message_to_str(ev->request,&tmp,&msglen);
1772 ms_message("Unsupported request received:\n%s",tmp);
1775 /*answer with a 501 Not implemented*/
1776 eXosip_message_send_answer(ev->tid,501,NULL);
1780 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1781 osip_via_t *via=NULL;
1782 osip_message_get_via(msg,0,&via);
1784 osip_free(via->port);
1785 via->port=osip_strdup(port);
1786 osip_free(via->host);
1787 via->host=osip_strdup(ip);
1792 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1793 osip_contact_t *ctt=NULL;
1794 const char *received;
1796 SalTransport transport;
1799 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1800 osip_message_get_contact(request,0,&ctt);
1802 ms_warning("fix_message_contact(): no contact to update");
1805 if (expire_last_contact){
1806 osip_contact_t *oldct=NULL,*prevct;
1807 osip_generic_param_t *param=NULL;
1808 osip_contact_clone(ctt,&oldct);
1809 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1810 osip_contact_free(prevct);
1811 osip_list_remove(&request->contacts,1);
1813 osip_list_add(&request->contacts,oldct,1);
1814 osip_contact_param_get_byname(oldct,"expires",¶m);
1816 if (param->gvalue) osip_free(param->gvalue);
1817 param->gvalue=osip_strdup("0");
1819 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1822 if (ctt->url->host!=NULL){
1823 osip_free(ctt->url->host);
1825 ctt->url->host=osip_strdup(received);
1826 if (ctt->url->port!=NULL){
1827 osip_free(ctt->url->port);
1829 snprintf(port,sizeof(port),"%i",rport);
1830 ctt->url->port=osip_strdup(port);
1831 if (op->masquerade_via) masquerade_via(request,received,port);
1833 if (transport != SalTransportUDP) {
1834 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1839 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1840 osip_contact_t *ctt=NULL;
1841 SalAddress* ori_contact_address=NULL;
1842 const char *received;
1844 SalTransport transport;
1846 osip_message_t *msg=NULL;
1847 Sal* sal=op->base.root;
1849 bool_t found_valid_contact=FALSE;
1850 bool_t from_request=FALSE;
1852 if (sal->double_reg==FALSE ) return FALSE;
1854 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1857 osip_message_get_contact(last_answer,i,&ctt);
1858 if (!from_request && ctt==NULL) {
1859 osip_message_get_contact(orig_request,0,&ctt);
1863 osip_contact_to_str(ctt,&tmp);
1864 ori_contact_address = sal_address_new(tmp);
1866 /*check if contact is up to date*/
1867 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1868 && sal_address_get_port_int(ori_contact_address) == rport
1869 && sal_address_get_transport(ori_contact_address) == transport) {
1871 ms_message("Register response has up to date contact, doing nothing.");
1873 ms_warning("Register response does not have up to date contact, but last request had."
1874 "Stupid registrar detected, giving up.");
1876 found_valid_contact=TRUE;
1879 sal_address_destroy(ori_contact_address);
1882 }while(!found_valid_contact);
1883 if (!found_valid_contact)
1884 ms_message("Contact do not match, resending register.");
1888 eXosip_register_build_register(op->rid,op->expires,&msg);
1891 ms_warning("Fail to create a contact updated register.");
1894 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1895 eXosip_register_send_register(op->rid,msg);
1897 ms_message("Resending new register with updated contact");
1898 update_contact_from_response(op,last_answer);
1901 ms_warning("Fail to send updated register.");
1909 static void registration_success(Sal *sal, eXosip_event_t *ev){
1910 SalOp *op=sal_find_register(sal,ev->rid);
1911 osip_header_t *h=NULL;
1914 ms_error("Receiving register response for unknown operation");
1917 osip_message_get_expires(ev->request,0,&h);
1918 if (h!=NULL && atoi(h->hvalue)!=0){
1920 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1921 sal->callbacks.register_success(op,registered);
1924 sal->callbacks.register_success(op,FALSE);
1928 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1930 const char *reason=NULL;
1931 SalOp *op=sal_find_register(sal,ev->rid);
1932 SalReason sr=SalReasonUnknown;
1933 SalError se=SalErrorUnknown;
1936 ms_error("Receiving register failure for unknown operation");
1940 status_code=osip_message_get_status_code(ev->response);
1941 reason=osip_message_get_reason_phrase(ev->response);
1943 switch(status_code){
1946 return process_authentication(sal,ev);
1948 case 423: /*interval too brief*/
1949 {/*retry with greater interval */
1950 osip_header_t *h=NULL;
1951 osip_message_t *msg=NULL;
1952 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1953 if (h && h->hvalue && h->hvalue[0]!='\0'){
1954 int val=atoi(h->hvalue);
1955 if (val>op->expires)
1957 }else op->expires*=2;
1959 eXosip_register_build_register(op->rid,op->expires,&msg);
1960 eXosip_register_send_register(op->rid,msg);
1964 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1965 in vias, such as ekiga.net
1966 On the opposite, freephonie.net bugs when via are masqueraded.
1968 op->masquerade_via=TRUE;
1970 /* if contact is up to date, process the failure, otherwise resend a new register with
1971 updated contact first, just in case the faillure is due to incorrect contact */
1972 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1973 return TRUE; /*we are retrying with an updated contact*/
1974 if (status_code==403){
1976 sr=SalReasonForbidden;
1977 }else if (status_code==0){
1978 se=SalErrorNoResponse;
1980 sal->callbacks.register_failure(op,se,sr,reason);
1985 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1986 SalOp *op=find_op(sal,ev);
1988 ms_warning("other_request_reply(): Receiving response to unknown request.");
1992 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
1993 update_contact_from_response(op,ev->response);
1994 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
1995 sal->callbacks.ping_reply(op);
1997 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
1998 /*out of call message acknolegment*/
1999 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2001 if (ev->response->status_code<200){
2002 status=SalTextDeliveryInProgress;
2003 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2004 status=SalTextDeliveryDone;
2007 sal->callbacks.text_delivery_update(op,status);
2011 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2012 SalOp *op=find_op(sal,ev);
2014 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2015 if (op->sipfrag_pending){
2016 send_notify_for_refer(op->did,op->sipfrag_pending);
2017 op->sipfrag_pending=NULL;
2023 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2024 ms_message("linphone process event get a message %d\n",ev->type);
2026 case EXOSIP_CALL_ANSWERED:
2027 ms_message("CALL_ANSWERED\n");
2028 call_accepted(sal,ev);
2029 authentication_ok(sal,ev);
2031 case EXOSIP_CALL_CLOSED:
2032 case EXOSIP_CALL_CANCELLED:
2033 ms_message("CALL_CLOSED or CANCELLED\n");
2034 call_terminated(sal,ev);
2036 case EXOSIP_CALL_TIMEOUT:
2037 case EXOSIP_CALL_NOANSWER:
2038 ms_message("CALL_TIMEOUT or NOANSWER\n");
2039 return call_failure(sal,ev);
2041 case EXOSIP_CALL_REQUESTFAILURE:
2042 case EXOSIP_CALL_GLOBALFAILURE:
2043 case EXOSIP_CALL_SERVERFAILURE:
2044 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2045 return call_failure(sal,ev);
2047 case EXOSIP_CALL_RELEASED:
2048 ms_message("CALL_RELEASED\n");
2049 call_released(sal, ev);
2051 case EXOSIP_CALL_INVITE:
2052 ms_message("CALL_NEW\n");
2053 inc_new_call(sal,ev);
2055 case EXOSIP_CALL_REINVITE:
2056 handle_reinvite(sal,ev);
2058 case EXOSIP_CALL_ACK:
2059 ms_message("CALL_ACK");
2062 case EXOSIP_CALL_REDIRECTED:
2063 ms_message("CALL_REDIRECTED");
2064 eXosip_default_action(ev);
2066 case EXOSIP_CALL_PROCEEDING:
2067 ms_message("CALL_PROCEEDING");
2068 call_proceeding(sal,ev);
2070 case EXOSIP_CALL_RINGING:
2071 ms_message("CALL_RINGING");
2072 call_ringing(sal,ev);
2073 authentication_ok(sal,ev);
2075 case EXOSIP_CALL_MESSAGE_NEW:
2076 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2077 call_message_new(sal,ev);
2079 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2081 (ev->response->status_code==407 || ev->response->status_code==401)){
2082 return process_authentication(sal,ev);
2085 case EXOSIP_CALL_MESSAGE_ANSWERED:
2086 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2087 process_in_call_reply(sal,ev);
2089 case EXOSIP_IN_SUBSCRIPTION_NEW:
2090 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2091 sal_exosip_subscription_recv(sal,ev);
2093 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2094 ms_message("CALL_SUBSCRIPTION_NEW ");
2095 sal_exosip_in_subscription_closed(sal,ev);
2097 case EXOSIP_SUBSCRIPTION_UPDATE:
2098 ms_message("CALL_SUBSCRIPTION_UPDATE");
2100 case EXOSIP_SUBSCRIPTION_NOTIFY:
2101 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2102 sal_exosip_notify_recv(sal,ev);
2104 case EXOSIP_SUBSCRIPTION_ANSWERED:
2105 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2106 sal_exosip_subscription_answered(sal,ev);
2108 case EXOSIP_SUBSCRIPTION_CLOSED:
2109 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2110 sal_exosip_subscription_closed(sal,ev);
2112 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2113 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2114 return process_authentication(sal,ev);
2116 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2117 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2118 sal_exosip_subscription_closed(sal,ev);
2120 case EXOSIP_REGISTRATION_FAILURE:
2121 ms_message("REGISTRATION_FAILURE\n");
2122 return registration_failure(sal,ev);
2124 case EXOSIP_REGISTRATION_SUCCESS:
2125 authentication_ok(sal,ev);
2126 registration_success(sal,ev);
2128 case EXOSIP_MESSAGE_NEW:
2129 other_request(sal,ev);
2131 case EXOSIP_MESSAGE_PROCEEDING:
2132 case EXOSIP_MESSAGE_ANSWERED:
2133 case EXOSIP_MESSAGE_REDIRECTED:
2134 case EXOSIP_MESSAGE_SERVERFAILURE:
2135 case EXOSIP_MESSAGE_GLOBALFAILURE:
2136 other_request_reply(sal,ev);
2138 case EXOSIP_MESSAGE_REQUESTFAILURE:
2139 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2141 switch (ev->response->status_code) {
2144 return process_authentication(sal,ev);
2146 eXosip_automatic_action ();
2151 other_request_reply(sal,ev);
2154 ms_message("Unhandled exosip event ! %i",ev->type);
2160 int sal_iterate(Sal *sal){
2162 while((ev=eXosip_event_wait(0,0))!=NULL){
2163 if (process_event(sal,ev))
2164 eXosip_event_free(ev);
2166 #ifdef HAVE_EXOSIP_TRYLOCK
2167 if (eXosip_trylock()==0){
2168 eXosip_automatic_refresh();
2171 ms_warning("eXosip_trylock busy.");
2175 eXosip_automatic_refresh();
2181 static void register_set_contact(osip_message_t *msg, const char *contact){
2182 osip_uri_param_t *param = NULL;
2183 osip_contact_t *ct=NULL;
2185 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2186 osip_message_get_contact(msg,0,&ct);
2188 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2189 if (param && param->gvalue)
2190 line=osip_strdup(param->gvalue);
2192 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2193 osip_message_set_contact(msg,contact);
2194 osip_message_get_contact(msg,0,&ct);
2195 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2198 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2200 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2202 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2203 osip_message_set_route(msg,tmp);
2206 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2207 osip_message_t *msg;
2208 const char *contact=sal_op_get_contact(h);
2210 sal_op_set_route(h,proxy);
2212 SalAddress *from_parsed=sal_address_new(from);
2214 char *uri, *domain_ptr = NULL;
2215 if (from_parsed==NULL) {
2216 ms_warning("sal_register() bad from %s",from);
2219 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2220 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2221 uri = sal_address_as_string_uri_only(from_parsed);
2222 if (uri) domain_ptr = strchr(uri, '@');
2224 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2226 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2228 if (uri) ms_free(uri);
2229 sal_address_destroy(from_parsed);
2231 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2233 if (contact) register_set_contact(msg,contact);
2234 sal_register_add_route(msg,proxy);
2235 sal_add_register(h->base.root,h);
2237 ms_error("Could not build initial register.");
2243 eXosip_register_build_register(h->rid,expires,&msg);
2244 sal_register_add_route(msg,proxy);
2247 eXosip_register_send_register(h->rid,msg);
2250 return (msg != NULL) ? 0 : -1;
2253 int sal_register_refresh(SalOp *op, int expires){
2254 osip_message_t *msg=NULL;
2255 const char *contact=sal_op_get_contact(op);
2259 ms_error("Unexistant registration context, not possible to refresh.");
2262 #ifdef HAVE_EXOSIP_TRYLOCK
2263 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2264 * 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
2265 * the exosip lock in a non blocking way, and give up if it takes too long*/
2266 while (eXosip_trylock()!=0){
2268 if (tries>30) {/*after 3 seconds, give up*/
2269 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2276 eXosip_register_build_register(op->rid,expires,&msg);
2278 if (contact) register_set_contact(msg,contact);
2279 sal_register_add_route(msg,sal_op_get_route(op));
2280 eXosip_register_send_register(op->rid,msg);
2281 }else ms_error("Could not build REGISTER refresh message.");
2283 return (msg != NULL) ? 0 : -1;
2287 int sal_unregister(SalOp *h){
2288 osip_message_t *msg=NULL;
2290 eXosip_register_build_register(h->rid,0,&msg);
2291 if (msg) eXosip_register_send_register(h->rid,msg);
2292 else ms_warning("Could not build unREGISTER !");
2297 SalAddress * sal_address_new(const char *uri){
2299 osip_from_init(&from);
2301 // Remove front spaces
2302 while (uri[0]==' ') {
2306 if (osip_from_parse(from,uri)!=0){
2307 osip_from_free(from);
2310 if (from->displayname!=NULL && from->displayname[0]=='"'){
2311 char *unquoted=osip_strdup_without_quote(from->displayname);
2312 osip_free(from->displayname);
2313 from->displayname=unquoted;
2315 return (SalAddress*)from;
2318 SalAddress * sal_address_clone(const SalAddress *addr){
2319 osip_from_t *ret=NULL;
2320 osip_from_clone((osip_from_t*)addr,&ret);
2321 return (SalAddress*)ret;
2324 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2326 const char *sal_address_get_scheme(const SalAddress *addr){
2327 const osip_from_t *u=(const osip_from_t*)addr;
2328 return null_if_empty(u->url->scheme);
2331 const char *sal_address_get_display_name(const SalAddress* addr){
2332 const osip_from_t *u=(const osip_from_t*)addr;
2333 return null_if_empty(u->displayname);
2336 const char *sal_address_get_username(const SalAddress *addr){
2337 const osip_from_t *u=(const osip_from_t*)addr;
2338 return null_if_empty(u->url->username);
2341 const char *sal_address_get_domain(const SalAddress *addr){
2342 const osip_from_t *u=(const osip_from_t*)addr;
2343 return null_if_empty(u->url->host);
2346 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2347 osip_from_t *u=(osip_from_t*)addr;
2348 if (u->displayname!=NULL){
2349 osip_free(u->displayname);
2350 u->displayname=NULL;
2352 if (display_name!=NULL && display_name[0]!='\0'){
2353 u->displayname=osip_strdup(display_name);
2357 void sal_address_set_username(SalAddress *addr, const char *username){
2358 osip_from_t *uri=(osip_from_t*)addr;
2359 if (uri->url->username!=NULL){
2360 osip_free(uri->url->username);
2361 uri->url->username=NULL;
2364 uri->url->username=osip_strdup(username);
2367 void sal_address_set_domain(SalAddress *addr, const char *host){
2368 osip_from_t *uri=(osip_from_t*)addr;
2369 if (uri->url->host!=NULL){
2370 osip_free(uri->url->host);
2371 uri->url->host=NULL;
2374 uri->url->host=osip_strdup(host);
2377 void sal_address_set_port(SalAddress *addr, const char *port){
2378 osip_from_t *uri=(osip_from_t*)addr;
2379 if (uri->url->port!=NULL){
2380 osip_free(uri->url->port);
2381 uri->url->port=NULL;
2384 uri->url->port=osip_strdup(port);
2387 void sal_address_set_port_int(SalAddress *uri, int port){
2390 /*this is the default, special case to leave the port field blank*/
2391 sal_address_set_port(uri,NULL);
2394 snprintf(tmp,sizeof(tmp),"%i",port);
2395 sal_address_set_port(uri,tmp);
2398 void sal_address_clean(SalAddress *addr){
2399 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2400 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2403 char *sal_address_as_string(const SalAddress *u){
2405 osip_from_t *from=(osip_from_t *)u;
2406 char *old_displayname=NULL;
2407 /* hack to force use of quotes around the displayname*/
2408 if (from->displayname!=NULL
2409 && from->displayname[0]!='"'){
2410 old_displayname=from->displayname;
2411 from->displayname=osip_enquote(from->displayname);
2413 osip_from_to_str(from,&tmp);
2414 if (old_displayname!=NULL){
2415 ms_free(from->displayname);
2416 from->displayname=old_displayname;
2423 char *sal_address_as_string_uri_only(const SalAddress *u){
2424 char *tmp=NULL,*ret;
2425 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2430 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2431 osip_uri_param_t *param=NULL;
2432 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2434 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2436 osip_free(param->gvalue);
2437 param->gvalue=value ? osip_strdup(value) : NULL;
2442 void sal_address_destroy(SalAddress *u){
2443 osip_from_free((osip_from_t*)u);
2446 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2447 ctx->keepalive_period=value;
2448 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2450 unsigned int sal_get_keepalive_period(Sal *ctx) {
2451 return ctx->keepalive_period;
2454 const char * sal_address_get_port(const SalAddress *addr) {
2455 const osip_from_t *u=(const osip_from_t*)addr;
2456 return null_if_empty(u->url->port);
2459 int sal_address_get_port_int(const SalAddress *uri) {
2460 const char* port = sal_address_get_port(uri);
2467 SalTransport sal_address_get_transport(const SalAddress* addr) {
2468 const osip_from_t *u=(const osip_from_t*)addr;
2469 osip_uri_param_t *transport_param=NULL;
2470 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2471 if (transport_param == NULL){
2472 return SalTransportUDP;
2474 return sal_transport_parse(transport_param->gvalue);
2477 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2478 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2481 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2482 int sal_call_update(SalOp *h, const char *subject){
2484 osip_message_t *reinvite=NULL;
2487 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2492 osip_message_set_subject(reinvite,subject);
2493 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2494 if (h->base.contact){
2495 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2496 osip_message_set_contact(reinvite,h->base.contact);
2498 if (h->base.root->session_expires!=0){
2499 osip_message_set_header(reinvite, "Session-expires", "200");
2500 osip_message_set_supported(reinvite, "timer");
2502 if (h->base.local_media){
2503 h->sdp_offering=TRUE;
2504 set_sdp_from_desc(reinvite,h->base.local_media);
2505 }else h->sdp_offering=FALSE;
2507 err = eXosip_call_send_request(h->did, reinvite);
2511 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2512 ctx->reuse_authorization=value;