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;
290 void sal_uninit(Sal* sal){
293 ms_free(sal->rootCa);
297 void sal_set_user_pointer(Sal *sal, void *user_data){
301 void *sal_get_user_pointer(const Sal *sal){
305 static void unimplemented_stub(){
306 ms_warning("Unimplemented SAL callback");
309 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
310 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
311 if (ctx->callbacks.call_received==NULL)
312 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
313 if (ctx->callbacks.call_ringing==NULL)
314 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
315 if (ctx->callbacks.call_accepted==NULL)
316 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
317 if (ctx->callbacks.call_failure==NULL)
318 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
319 if (ctx->callbacks.call_terminated==NULL)
320 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
321 if (ctx->callbacks.call_released==NULL)
322 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
323 if (ctx->callbacks.call_updating==NULL)
324 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
325 if (ctx->callbacks.auth_requested==NULL)
326 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
327 if (ctx->callbacks.auth_success==NULL)
328 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
329 if (ctx->callbacks.register_success==NULL)
330 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
331 if (ctx->callbacks.register_failure==NULL)
332 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
333 if (ctx->callbacks.dtmf_received==NULL)
334 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
335 if (ctx->callbacks.notify==NULL)
336 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
337 if (ctx->callbacks.notify_presence==NULL)
338 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
339 if (ctx->callbacks.subscribe_received==NULL)
340 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
341 if (ctx->callbacks.text_received==NULL)
342 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
343 if (ctx->callbacks.ping_reply==NULL)
344 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
345 if (ctx->callbacks.message_external_body==NULL)
346 ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)unimplemented_stub;
349 int sal_unlisten_ports(Sal *ctx){
358 int sal_reset_transports(Sal *ctx){
359 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
361 ms_message("Exosip transports reset.");
362 eXosip_reset_transports();
366 ms_warning("sal_reset_transports() not implemented in this version.");
372 static void set_tls_options(Sal *ctx){
374 eXosip_tls_ctx_t tlsCtx;
375 memset(&tlsCtx, 0, sizeof(tlsCtx));
376 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
377 eXosip_set_tls_ctx(&tlsCtx);
379 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
380 eXosip_tls_verify_certificate(ctx->verify_server_certs);
384 void sal_set_dscp(Sal *ctx, int dscp){
387 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
390 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
393 int proto=IPPROTO_UDP;
394 int keepalive = ctx->keepalive_period;
397 case SalTransportUDP:
399 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
401 case SalTransportTCP:
402 case SalTransportTLS:
405 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
406 set_tls_options(ctx);
409 ms_warning("unexpected proto, using datagram");
411 /*see if it looks like an IPv6 address*/
412 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
413 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
414 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
415 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
416 sal_set_dscp(ctx,ctx->dscp);
418 ipv6=strchr(addr,':')!=NULL;
419 eXosip_enable_ipv6(ipv6);
421 if (is_secure && tr == SalTransportUDP){
422 ms_fatal("SIP over DTLS is not supported yet.");
425 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
430 ortp_socket_t sal_get_socket(Sal *ctx){
431 #ifdef HAVE_EXOSIP_GET_SOCKET
432 return eXosip_get_socket(IPPROTO_UDP);
434 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
439 void sal_set_user_agent(Sal *ctx, const char *user_agent){
440 eXosip_set_user_agent(user_agent);
443 void sal_use_session_timers(Sal *ctx, int expires){
444 ctx->session_expires=expires;
447 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
448 ctx->one_matching_codec=one_matching_codec;
451 MSList *sal_get_pending_auths(Sal *sal){
452 return ms_list_copy(sal->pending_auths);
455 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
456 ctx->double_reg=enabled;
459 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
460 ctx->expire_old_contact=enabled;
463 void sal_use_rport(Sal *ctx, bool_t use_rports){
464 ctx->use_rports=use_rports;
466 void sal_use_101(Sal *ctx, bool_t use_101){
467 ctx->use_101=use_101;
470 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
472 ms_free(ctx->rootCa);
473 ctx->rootCa = ms_strdup(rootCa);
474 set_tls_options(ctx);
477 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
478 ctx->verify_server_certs=verify;
479 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
480 eXosip_tls_verify_certificate(verify);
484 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
485 osip_via_t *via=NULL;
486 osip_generic_param_t *param=NULL;
487 const char *rport=NULL;
491 osip_message_get_via(msg,0,&via);
493 ms_warning("extract_received_rport(): no via.");
497 *transport = sal_transport_parse(via->protocol);
499 if (via->port && via->port[0]!='\0')
500 *rportval=atoi(via->port);
502 osip_via_param_get_byname(via,"rport",¶m);
505 if (rport && rport[0]!='\0') *rportval=atoi(rport);
509 osip_via_param_get_byname(via,"received",¶m);
510 if (param) *received=param->gvalue;
512 if (rport==NULL && *received==NULL){
513 ms_warning("extract_received_rport(): no rport and no received parameters.");
519 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
523 sdp_message_to_str(msg,&sdp);
525 snprintf(clen,sizeof(clen),"%i",sdplen);
526 osip_message_set_body(sip,sdp,sdplen);
527 osip_message_set_content_type(sip,"application/sdp");
528 osip_message_set_content_length(sip,clen);
532 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
533 sdp_message_t *msg=media_description_to_sdp(desc);
535 ms_error("Fail to print sdp message !");
539 sdp_message_free(msg);
542 static void sdp_process(SalOp *h){
543 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
545 sal_media_description_unref(h->result);
547 h->result=sal_media_description_new();
548 if (h->sdp_offering){
549 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
553 sdp_message_free(h->sdp_answer);
555 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
556 h->sdp_answer=media_description_to_sdp(h->result);
557 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
558 It should contains media parameters constraint from the remote offer, not our response*/
559 strcpy(h->result->addr,h->base.remote_media->addr);
560 h->result->bandwidth=h->base.remote_media->bandwidth;
562 for(i=0;i<h->result->nstreams;++i){
563 if (h->result->streams[i].rtp_port>0){
564 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
565 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
566 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
567 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
568 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
569 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
571 if (h->result->streams[i].proto == SalProtoRtpSavp) {
572 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
580 int sal_call_is_offerer(const SalOp *h){
581 return h->sdp_offering;
584 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
586 sal_media_description_ref(desc);
587 if (h->base.local_media)
588 sal_media_description_unref(h->base.local_media);
589 h->base.local_media=desc;
590 if (h->base.remote_media){
591 /*case of an incoming call where we modify the local capabilities between the time
592 * the call is ringing and it is accepted (for example if you want to accept without video*/
593 /*reset the sdp answer so that it is computed again*/
595 sdp_message_free(h->sdp_answer);
602 int sal_call(SalOp *h, const char *from, const char *to){
605 osip_message_t *invite=NULL;
606 osip_call_id_t *callid;
607 sal_op_set_from(h,from);
609 sal_exosip_fix_route(h);
611 h->terminated = FALSE;
613 route = sal_op_get_route(h);
614 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
616 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
617 err, from, to, route);
620 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
621 if (h->base.contact){
622 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
623 osip_message_set_contact(invite,h->base.contact);
625 if (h->base.root->session_expires!=0){
626 osip_message_set_header(invite, "Session-expires", "200");
627 osip_message_set_supported(invite, "timer");
629 if (h->base.local_media){
630 h->sdp_offering=TRUE;
631 set_sdp_from_desc(invite,h->base.local_media);
632 }else h->sdp_offering=FALSE;
634 osip_message_set_header(invite,"Replaces",h->replaces);
636 osip_message_set_header(invite,"Referred-By",h->referred_by);
640 err=eXosip_call_send_initial_invite(invite);
644 ms_error("Fail to send invite ! Error code %d", err);
647 callid=osip_message_get_call_id(invite);
648 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
649 sal_add_call(h->base.root,h);
654 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
657 /*if early media send also 180 and 183 */
661 eXosip_call_build_answer(h->tid,183,&msg);
665 set_sdp(msg,h->sdp_answer);
666 sdp_message_free(h->sdp_answer);
669 eXosip_call_send_answer(h->tid,183,msg);
674 eXosip_call_send_answer(h->tid,180,NULL);
680 int sal_call_accept(SalOp * h){
682 const char *contact=sal_op_get_contact(h);
684 int err=eXosip_call_build_answer(h->tid,200,&msg);
685 if (err<0 || msg==NULL){
686 ms_error("Fail to build answer for call: err=%i",err);
689 if (h->base.root->session_expires!=0){
690 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
694 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
695 osip_message_set_contact(msg,contact);
698 if (h->base.local_media){
699 /*this is the case where we received an invite without SDP*/
700 if (h->sdp_offering) {
701 set_sdp_from_desc(msg,h->base.local_media);
703 if (h->sdp_answer==NULL) sdp_process(h);
705 set_sdp(msg,h->sdp_answer);
706 sdp_message_free(h->sdp_answer);
711 ms_error("You are accepting a call but not defined any media capabilities !");
713 eXosip_call_send_answer(h->tid,200,msg);
717 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
718 if (reason==SalReasonBusy){
720 eXosip_call_send_answer(h->tid,486,NULL);
723 else if (reason==SalReasonTemporarilyUnavailable){
725 eXosip_call_send_answer(h->tid,480,NULL);
727 }else if (reason==SalReasonDoNotDisturb){
729 eXosip_call_send_answer(h->tid,600,NULL);
731 }else if (reason==SalReasonMedia){
733 eXosip_call_send_answer(h->tid,415,NULL);
735 }else if (redirect!=NULL && reason==SalReasonRedirect){
738 if (strstr(redirect,"sip:")!=0) code=302;
741 eXosip_call_build_answer(h->tid,code,&msg);
742 osip_message_set_contact(msg,redirect);
743 eXosip_call_send_answer(h->tid,code,msg);
745 }else sal_call_terminate(h);
749 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
750 return h->base.remote_media;
753 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
754 if (h->base.local_media && h->base.remote_media && !h->result){
760 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
761 if (refered_call->replaces)
762 h->replaces=ms_strdup(refered_call->replaces);
763 if (refered_call->referred_by)
764 h->referred_by=ms_strdup(refered_call->referred_by);
768 static int send_notify_for_refer(int did, const char *sipfrag){
771 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
774 ms_warning("Could not build NOTIFY for refer.");
777 osip_message_set_content_type(msg,"message/sipfrag");
778 osip_message_set_header(msg,"Event","refer");
779 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
780 eXosip_call_send_request(did,msg);
785 /* currently only support to notify trying and 200Ok*/
786 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
789 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
791 else if (newcall->cid!=-1){
792 if (newcall->did==-1){
793 /* not yet established*/
794 if (!newcall->terminated){
796 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
799 if (!newcall->terminated){
800 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
801 /* we need previous notify transaction to complete, so buffer the request for later*/
802 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
810 int sal_ping(SalOp *op, const char *from, const char *to){
811 osip_message_t *options=NULL;
813 sal_op_set_from(op,from);
814 sal_op_set_to(op,to);
815 sal_exosip_fix_route(op);
817 eXosip_options_build_request (&options, sal_op_get_to(op),
818 sal_op_get_from(op),sal_op_get_route(op));
820 if (op->base.root->session_expires!=0){
821 osip_message_set_header(options, "Session-expires", "200");
822 osip_message_set_supported(options, "timer");
824 sal_add_other(sal_op_get_sal(op),op,options);
825 return eXosip_options_send_request(options);
830 int sal_call_refer(SalOp *h, const char *refer_to){
831 osip_message_t *msg=NULL;
834 eXosip_call_build_refer(h->did,refer_to, &msg);
835 if (msg) err=eXosip_call_send_request(h->did, msg);
841 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
842 osip_message_t *msg=NULL;
843 char referto[256]={0};
846 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
847 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
851 eXosip_call_build_refer(h->did,referto, &msg);
852 osip_message_set_header(msg,"Referred-By",h->base.from);
853 if (msg) err=eXosip_call_send_request(h->did, msg);
859 SalOp *sal_call_get_replaces(SalOp *h){
860 if (h!=NULL && h->replaces!=NULL){
863 cid=eXosip_call_find_by_replaces(h->replaces);
866 SalOp *ret=sal_find_call(h->base.root,cid);
873 int sal_call_send_dtmf(SalOp *h, char dtmf){
874 osip_message_t *msg=NULL;
879 eXosip_call_build_info(h->did,&msg);
881 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
882 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
883 osip_message_set_content_type(msg,"application/dtmf-relay");
884 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
885 osip_message_set_content_length(msg,clen);
886 eXosip_call_send_request(h->did,msg);
892 static void push_auth_to_exosip(const SalAuthInfo *info){
894 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
895 else userid=info->userid;
896 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
897 eXosip_add_authentication_info (info->username,userid,
898 info->password, NULL,info->realm);
901 * Just for symmetry ;-)
903 static void pop_auth_from_exosip() {
904 eXosip_clear_authentication_info();
907 int sal_call_terminate(SalOp *h){
909 if (h == NULL) return -1;
910 if (h->auth_info) push_auth_to_exosip(h->auth_info);
912 err=eXosip_call_terminate(h->cid,h->did);
914 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
916 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
922 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
923 if (h->terminated) return;
924 if (h->pending_auth){
925 push_auth_to_exosip(info);
927 /*FIXME exosip does not take into account this update register message*/
929 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
933 update_contact_from_response(h,h->pending_auth->response);
935 eXosip_default_action(h->pending_auth);
937 ms_message("eXosip_default_action() done");
938 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
940 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
941 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
944 void sal_op_cancel_authentication(SalOp *h) {
946 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
947 } else if (h->cid >0) {
948 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
950 ms_warning("Auth failure not handled");
954 static void set_network_origin(SalOp *op, osip_message_t *req){
955 const char *received=NULL;
958 SalTransport transport;
959 if (extract_received_rport(req,&received,&rport,&transport)!=0){
960 osip_via_t *via=NULL;
962 osip_message_get_via(req,0,&via);
963 received=osip_via_get_host(via);
964 tmp=osip_via_get_port(via);
965 if (tmp) rport=atoi(tmp);
967 if (transport != SalTransportUDP) {
968 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
970 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
972 __sal_op_set_network_origin(op,origin);
975 static void set_remote_ua(SalOp* op, osip_message_t *req){
976 if (op->base.remote_ua==NULL){
977 osip_header_t *h=NULL;
978 osip_message_get_user_agent(req,0,&h);
980 op->base.remote_ua=ms_strdup(h->hvalue);
985 static void set_replaces(SalOp *op, osip_message_t *req){
986 osip_header_t *h=NULL;
989 ms_free(op->replaces);
992 osip_message_header_get_byname(req,"replaces",0,&h);
994 if (h->hvalue && h->hvalue[0]!='\0'){
995 op->replaces=ms_strdup(h->hvalue);
1000 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1002 return sal_find_call(sal,ev->cid);
1005 return sal_find_register(sal,ev->rid);
1008 return sal_find_out_subscribe(sal,ev->sid);
1011 return sal_find_in_subscribe(sal,ev->nid);
1013 if (ev->response) return sal_find_other(sal,ev->response);
1014 else if (ev->request) return sal_find_other(sal,ev->request);
1018 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1019 SalOp *op=sal_op_new(sal);
1020 osip_from_t *from,*to;
1021 osip_call_info_t *call_info;
1023 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1024 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1025 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1027 set_network_origin(op,ev->request);
1028 set_remote_ua(op,ev->request);
1029 set_replaces(op,ev->request);
1032 op->sdp_offering=FALSE;
1033 op->base.remote_media=sal_media_description_new();
1034 sdp_to_media_description(sdp,op->base.remote_media);
1035 sdp_message_free(sdp);
1036 }else op->sdp_offering=TRUE;
1038 from=osip_message_get_from(ev->request);
1039 to=osip_message_get_to(ev->request);
1040 osip_from_to_str(from,&tmp);
1041 sal_op_set_from(op,tmp);
1043 osip_from_to_str(to,&tmp);
1044 sal_op_set_to(op,tmp);
1047 osip_message_get_call_info(ev->request,0,&call_info);
1050 osip_call_info_to_str(call_info,&tmp);
1051 if( strstr(tmp,"answer-after=") != NULL)
1053 op->auto_answer_asked=TRUE;
1054 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1062 sal_add_call(op->base.root,op);
1063 sal->callbacks.call_received(op);
1066 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1067 SalOp *op=find_op(sal,ev);
1071 ms_warning("Reinvite for non-existing operation !");
1076 sdp=eXosip_get_sdp_info(ev->request);
1077 if (op->base.remote_media){
1078 sal_media_description_unref(op->base.remote_media);
1079 op->base.remote_media=NULL;
1082 sal_media_description_unref(op->result);
1086 op->sdp_offering=FALSE;
1087 op->base.remote_media=sal_media_description_new();
1088 sdp_to_media_description(sdp,op->base.remote_media);
1089 sdp_message_free(sdp);
1092 op->sdp_offering=TRUE;
1094 sal->callbacks.call_updating(op);
1097 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1098 SalOp *op=find_op(sal,ev);
1102 ms_warning("ack for non-existing call !");
1105 if (op->terminated) {
1106 ms_warning("ack for terminated call, ignoring");
1110 if (op->sdp_offering){
1111 sdp=eXosip_get_sdp_info(ev->ack);
1113 if (op->base.remote_media)
1114 sal_media_description_unref(op->base.remote_media);
1115 op->base.remote_media=sal_media_description_new();
1116 sdp_to_media_description(sdp,op->base.remote_media);
1118 sdp_message_free(sdp);
1124 sal->callbacks.call_ack(op);
1127 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1128 const char *received;
1130 SalTransport transport;
1131 if (extract_received_rport(response,&received,&rport,&transport)==0){
1132 const char *contact=sal_op_get_contact(op);
1134 /*no contact given yet, use from instead*/
1135 contact=sal_op_get_from(op);
1138 SalAddress *addr=sal_address_new(contact);
1140 sal_address_set_domain(addr,received);
1141 sal_address_set_port_int(addr,rport);
1142 if (transport!=SalTransportUDP)
1143 sal_address_set_transport(addr,transport);
1144 tmp=sal_address_as_string(addr);
1145 ms_message("Contact address updated to %s",tmp);
1146 sal_op_set_contact(op,tmp);
1147 sal_address_destroy(addr);
1153 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1154 SalOp *op=find_op(sal,ev);
1156 if (op==NULL || op->terminated==TRUE) {
1157 ms_warning("This call has been canceled.");
1159 eXosip_call_terminate(ev->cid,ev->did);
1167 /* update contact if received and rport are set by the server
1168 note: will only be used by remote for next INVITE, if any...*/
1169 update_contact_from_response(op,ev->response);
1173 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1175 SalOp *op=find_op(sal,ev);
1176 if (call_proceeding(sal, ev)==-1) return;
1178 set_remote_ua(op,ev->response);
1179 sdp=eXosip_get_sdp_info(ev->response);
1181 op->base.remote_media=sal_media_description_new();
1182 sdp_to_media_description(sdp,op->base.remote_media);
1183 sdp_message_free(sdp);
1184 if (op->base.local_media) sdp_process(op);
1186 sal->callbacks.call_ringing(op);
1189 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1191 osip_message_t *msg=NULL;
1192 SalOp *op=find_op(sal,ev);
1193 const char *contact;
1195 if (op==NULL || op->terminated==TRUE) {
1196 ms_warning("This call has been already terminated.");
1198 eXosip_call_terminate(ev->cid,ev->did);
1204 set_remote_ua(op,ev->response);
1206 sdp=eXosip_get_sdp_info(ev->response);
1208 op->base.remote_media=sal_media_description_new();
1209 sdp_to_media_description(sdp,op->base.remote_media);
1210 sdp_message_free(sdp);
1211 if (op->base.local_media) sdp_process(op);
1213 eXosip_call_build_ack(ev->did,&msg);
1215 ms_warning("This call has been already terminated.");
1217 eXosip_call_terminate(ev->cid,ev->did);
1221 contact=sal_op_get_contact(op);
1223 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1224 osip_message_set_contact(msg,contact);
1226 if (op->sdp_answer){
1227 set_sdp(msg,op->sdp_answer);
1228 sdp_message_free(op->sdp_answer);
1229 op->sdp_answer=NULL;
1231 eXosip_call_send_ack(ev->did,msg);
1232 sal->callbacks.call_accepted(op);
1235 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1237 SalOp *op=find_op(sal,ev);
1239 ms_warning("Call terminated for already closed call ?");
1243 osip_from_to_str(ev->request->from,&from);
1245 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1246 if (from) osip_free(from);
1247 op->terminated=TRUE;
1250 static void call_released(Sal *sal, eXosip_event_t *ev){
1251 SalOp *op=find_op(sal,ev);
1253 ms_warning("No op associated to this call_released()");
1256 if (!op->terminated){
1257 /* no response received so far */
1258 call_failure(sal,ev);
1260 sal->callbacks.call_released(op);
1263 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1264 const char *prx_realm=NULL,*www_realm=NULL;
1265 osip_proxy_authenticate_t *prx_auth;
1266 osip_www_authenticate_t *www_auth;
1268 *username=osip_uri_get_username(resp->from->url);
1269 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1270 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1272 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1274 www_realm=osip_www_authenticate_get_realm(www_auth);
1278 }else if (www_realm){
1286 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1287 osip_authorization_t *auth=NULL;
1288 osip_proxy_authorization_t *prx_auth=NULL;
1290 *username=osip_uri_get_username(msg->from->url);
1291 osip_message_get_authorization(msg, 0, &auth);
1293 *realm=osip_authorization_get_realm(auth);
1296 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1298 *realm=osip_proxy_authorization_get_realm(prx_auth);
1304 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1305 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1306 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1310 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1311 if (op->pending_auth){
1312 return get_auth_data(op->pending_auth,realm,username);
1317 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1319 const char *username,*realm;
1322 ms_warning("No operation associated with this authentication !");
1325 if (get_auth_data(ev,&realm,&username)==0){
1326 if (op->pending_auth!=NULL){
1327 eXosip_event_free(op->pending_auth);
1328 op->pending_auth=ev;
1330 op->pending_auth=ev;
1331 sal_add_pending_auth(sal,op);
1334 sal->callbacks.auth_requested(op,realm,username);
1340 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1342 const char *username,*realm;
1345 ms_warning("No operation associated with this authentication_ok!");
1348 if (op->pending_auth){
1349 eXosip_event_free(op->pending_auth);
1350 sal_remove_pending_auth(sal,op);
1351 op->pending_auth=NULL;
1353 if (get_auth_data(ev,&realm,&username)==0){
1354 sal->callbacks.auth_success(op,realm,username);
1358 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1361 char* computedReason=NULL;
1362 const char *reason=NULL;
1363 SalError error=SalErrorUnknown;
1364 SalReason sr=SalReasonUnknown;
1367 op=(SalOp*)find_op(sal,ev);
1370 ms_warning("Call failure reported for a closed call, ignored.");
1375 code=osip_message_get_status_code(ev->response);
1376 reason=osip_message_get_reason_phrase(ev->response);
1377 osip_header_t *h=NULL;
1378 if (!osip_message_header_get_byname( ev->response
1382 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1383 reason = computedReason;
1391 return process_authentication(sal,ev);
1394 error=SalErrorUnknown;
1397 error=SalErrorFailure;
1398 sr=SalReasonNotFound;
1401 error=SalErrorFailure;
1405 eXosip_default_action(ev);
1409 error=SalErrorFailure;
1410 sr=SalReasonTemporarilyUnavailable;
1412 error=SalErrorFailure;
1418 error=SalErrorFailure;
1419 sr=SalReasonDoNotDisturb;
1422 error=SalErrorFailure;
1423 sr=SalReasonDeclined;
1427 error=SalErrorFailure;
1428 sr=SalReasonUnknown;
1429 }else error=SalErrorNoResponse;
1431 op->terminated=TRUE;
1432 sal->callbacks.call_failure(op,error,sr,reason,code);
1433 if (computedReason != NULL){
1434 ms_free(computedReason);
1439 /* Request remote side to send us VFU */
1440 void sal_call_send_vfu_request(SalOp *h){
1441 osip_message_t *msg=NULL;
1443 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1447 " <picture_fast_update></picture_fast_update>"
1455 eXosip_call_build_info(h->did,&msg);
1457 osip_message_set_body(msg,info_body,strlen(info_body));
1458 osip_message_set_content_type(msg,"application/media_control+xml");
1459 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1460 osip_message_set_content_length(msg,clen);
1461 eXosip_call_send_request(h->did,msg);
1462 ms_message("Sending VFU request !");
1467 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1468 SalOp *op=find_op(sal,ev);
1469 osip_body_t *body=NULL;
1472 ms_warning("media control xml received without operation context!");
1476 osip_message_get_body(ev->request,0,&body);
1477 if (body && body->body!=NULL &&
1478 strstr(body->body,"picture_fast_update")){
1479 osip_message_t *ans=NULL;
1480 ms_message("Receiving VFU request !");
1481 if (sal->callbacks.vfu_request){
1482 sal->callbacks.vfu_request(op);
1483 eXosip_call_build_answer(ev->tid,200,&ans);
1485 eXosip_call_send_answer(ev->tid,200,ans);
1489 /*in all other cases we must say it is not implemented.*/
1491 osip_message_t *ans=NULL;
1493 eXosip_call_build_answer(ev->tid,501,&ans);
1495 eXosip_call_send_answer(ev->tid,501,ans);
1500 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1501 SalOp *op=find_op(sal,ev);
1502 osip_body_t *body=NULL;
1505 ms_warning("media dtmf relay received without operation context!");
1509 osip_message_get_body(ev->request,0,&body);
1510 if (body && body->body!=NULL){
1511 osip_message_t *ans=NULL;
1512 const char *name=strstr(body->body,"Signal");
1513 if (name==NULL) name=strstr(body->body,"signal");
1515 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1518 name+=strlen("signal");
1519 if (sscanf(name," = %1s",tmp)==1){
1520 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1521 if (sal->callbacks.dtmf_received != NULL)
1522 sal->callbacks.dtmf_received(op, tmp[0]);
1526 eXosip_call_build_answer(ev->tid,200,&ans);
1528 eXosip_call_send_answer(ev->tid,200,ans);
1533 static void fill_options_answer(osip_message_t *options){
1534 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1535 osip_message_set_accept(options,"application/sdp");
1538 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1539 osip_header_t *h=NULL;
1540 osip_message_t *ans=NULL;
1541 ms_message("Receiving REFER request !");
1542 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1545 osip_from_t *from=NULL;
1547 osip_from_init(&from);
1549 if (osip_from_parse(from,h->hvalue)==0){
1551 osip_uri_header_t *uh=NULL;
1552 osip_header_t *referred_by=NULL;
1553 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1554 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1555 ms_message("Found replaces in Refer-To");
1557 ms_free(op->replaces);
1559 op->replaces=ms_strdup(uh->gvalue);
1561 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1562 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1563 if (op->referred_by)
1564 ms_free(op->referred_by);
1565 op->referred_by=ms_strdup(referred_by->hvalue);
1568 osip_uri_header_freelist(&from->url->url_headers);
1569 osip_from_to_str(from,&tmp);
1570 sal->callbacks.refer_received(sal,op,tmp);
1572 osip_from_free(from);
1575 eXosip_call_build_answer(ev->tid,202,&ans);
1577 eXosip_call_send_answer(ev->tid,202,ans);
1582 ms_warning("cannot do anything with the refer without destination\n");
1586 static void process_notify(Sal *sal, eXosip_event_t *ev){
1587 osip_header_t *h=NULL;
1589 SalOp *op=find_op(sal,ev);
1590 osip_message_t *ans=NULL;
1592 ms_message("Receiving NOTIFY request !");
1593 osip_from_to_str(ev->request->from,&from);
1594 osip_message_header_get_byname(ev->request,"Event",0,&h);
1596 osip_body_t *body=NULL;
1597 //osip_content_type_t *ct=NULL;
1598 osip_message_get_body(ev->request,0,&body);
1599 //ct=osip_message_get_content_type(ev->request);
1600 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1601 /*special handling of refer events*/
1602 if (body && body->body){
1603 osip_message_t *msg;
1604 osip_message_init(&msg);
1605 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1606 int code=osip_message_get_status_code(msg);
1608 sal->callbacks.notify_refer(op,SalReferTrying);
1609 }else if (code==200){
1610 sal->callbacks.notify_refer(op,SalReferSuccess);
1611 }else if (code>=400){
1612 sal->callbacks.notify_refer(op,SalReferFailed);
1615 osip_message_free(msg);
1618 /*generic handling*/
1619 sal->callbacks.notify(op,from,h->hvalue);
1622 /*answer that we received the notify*/
1624 eXosip_call_build_answer(ev->tid,200,&ans);
1626 eXosip_call_send_answer(ev->tid,200,ans);
1631 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1632 osip_message_t *ans=NULL;
1634 if (MSG_IS_INFO(ev->request)){
1635 osip_content_type_t *ct;
1636 ct=osip_message_get_content_type(ev->request);
1637 if (ct && ct->subtype){
1638 if (strcmp(ct->subtype,"media_control+xml")==0)
1639 process_media_control_xml(sal,ev);
1640 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1641 process_dtmf_relay(sal,ev);
1643 ms_message("Unhandled SIP INFO.");
1644 /*send an "Not implemented" answer*/
1646 eXosip_call_build_answer(ev->tid,501,&ans);
1648 eXosip_call_send_answer(ev->tid,501,ans);
1652 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1654 eXosip_call_build_answer(ev->tid,200,&ans);
1656 eXosip_call_send_answer(ev->tid,200,ans);
1659 }else if(MSG_IS_MESSAGE(ev->request)){
1660 /* SIP messages could be received into call */
1661 text_received(sal, ev);
1663 eXosip_call_build_answer(ev->tid,200,&ans);
1665 eXosip_call_send_answer(ev->tid,200,ans);
1667 }else if(MSG_IS_REFER(ev->request)){
1668 SalOp *op=find_op(sal,ev);
1670 ms_message("Receiving REFER request !");
1671 process_refer(sal,op,ev);
1672 }else if(MSG_IS_NOTIFY(ev->request)){
1673 process_notify(sal,ev);
1674 }else if (MSG_IS_OPTIONS(ev->request)){
1676 eXosip_call_build_answer(ev->tid,200,&ans);
1678 fill_options_answer(ans);
1679 eXosip_call_send_answer(ev->tid,200,ans);
1683 }else ms_warning("call_message_new: No request ?");
1686 static void inc_update(Sal *sal, eXosip_event_t *ev){
1687 osip_message_t *msg=NULL;
1688 ms_message("Processing incoming UPDATE");
1690 eXosip_message_build_answer(ev->tid,200,&msg);
1692 eXosip_message_send_answer(ev->tid,200,msg);
1696 static bool_t comes_from_local_if(osip_message_t *msg){
1697 osip_via_t *via=NULL;
1698 osip_message_get_via(msg,0,&via);
1701 host=osip_via_get_host(via);
1702 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1703 osip_generic_param_t *param=NULL;
1704 osip_via_param_get_byname(via,"received",¶m);
1705 if (param==NULL) return TRUE;
1706 if (param->gvalue &&
1707 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1715 static void text_received(Sal *sal, eXosip_event_t *ev){
1716 osip_body_t *body=NULL;
1717 char *from=NULL,*msg;
1718 osip_content_type_t* content_type;
1719 osip_uri_param_t* external_body_url;
1720 char unquoted_external_body_url [256];
1721 int external_body_size=0;
1723 content_type= osip_message_get_content_type(ev->request);
1724 if (!content_type) {
1725 ms_error("Could not get message because no content type");
1728 osip_from_to_str(ev->request->from,&from);
1729 if (content_type->type
1730 && strcmp(content_type->type, "text")==0
1731 && content_type->subtype
1732 && strcmp(content_type->subtype, "plain")==0 ) {
1733 osip_message_get_body(ev->request,0,&body);
1735 ms_error("Could not get text message from SIP body");
1739 sal->callbacks.text_received(sal,from,msg);
1740 } if (content_type->type
1741 && strcmp(content_type->type, "message")==0
1742 && content_type->subtype
1743 && strcmp(content_type->subtype, "external-body")==0 ) {
1745 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1746 /*remove both first and last character*/
1747 strncpy(unquoted_external_body_url
1748 ,&external_body_url->gvalue[1]
1749 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1750 unquoted_external_body_url[external_body_size-1]='\0';
1751 sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
1754 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1761 static void other_request(Sal *sal, eXosip_event_t *ev){
1762 ms_message("in other_request");
1763 if (ev->request==NULL) return;
1764 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1765 text_received(sal,ev);
1766 eXosip_message_send_answer(ev->tid,200,NULL);
1767 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1768 osip_message_t *options=NULL;
1769 eXosip_options_build_answer(ev->tid,200,&options);
1770 fill_options_answer(options);
1771 eXosip_options_send_answer(ev->tid,200,options);
1772 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1773 ms_message("Receiving REFER request !");
1774 if (comes_from_local_if(ev->request)) {
1775 process_refer(sal,NULL,ev);
1776 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1777 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1782 osip_message_to_str(ev->request,&tmp,&msglen);
1784 ms_message("Unsupported request received:\n%s",tmp);
1787 /*answer with a 501 Not implemented*/
1788 eXosip_message_send_answer(ev->tid,501,NULL);
1792 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1793 osip_via_t *via=NULL;
1794 osip_message_get_via(msg,0,&via);
1796 osip_free(via->port);
1797 via->port=osip_strdup(port);
1798 osip_free(via->host);
1799 via->host=osip_strdup(ip);
1804 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1805 osip_contact_t *ctt=NULL;
1806 const char *received;
1808 SalTransport transport;
1811 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1812 osip_message_get_contact(request,0,&ctt);
1814 ms_warning("fix_message_contact(): no contact to update");
1817 if (expire_last_contact){
1818 osip_contact_t *oldct=NULL,*prevct;
1819 osip_generic_param_t *param=NULL;
1820 osip_contact_clone(ctt,&oldct);
1821 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1822 osip_contact_free(prevct);
1823 osip_list_remove(&request->contacts,1);
1825 osip_list_add(&request->contacts,oldct,1);
1826 osip_contact_param_get_byname(oldct,"expires",¶m);
1828 if (param->gvalue) osip_free(param->gvalue);
1829 param->gvalue=osip_strdup("0");
1831 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1834 if (ctt->url->host!=NULL){
1835 osip_free(ctt->url->host);
1837 ctt->url->host=osip_strdup(received);
1838 if (ctt->url->port!=NULL){
1839 osip_free(ctt->url->port);
1841 snprintf(port,sizeof(port),"%i",rport);
1842 ctt->url->port=osip_strdup(port);
1843 if (op->masquerade_via) masquerade_via(request,received,port);
1845 if (transport != SalTransportUDP) {
1846 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1851 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1852 osip_contact_t *ctt=NULL;
1853 SalAddress* ori_contact_address=NULL;
1854 const char *received;
1856 SalTransport transport;
1858 osip_message_t *msg=NULL;
1859 Sal* sal=op->base.root;
1861 bool_t found_valid_contact=FALSE;
1862 bool_t from_request=FALSE;
1864 if (sal->double_reg==FALSE ) return FALSE;
1866 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1869 osip_message_get_contact(last_answer,i,&ctt);
1870 if (!from_request && ctt==NULL) {
1871 osip_message_get_contact(orig_request,0,&ctt);
1875 osip_contact_to_str(ctt,&tmp);
1876 ori_contact_address = sal_address_new(tmp);
1878 /*check if contact is up to date*/
1879 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1880 && sal_address_get_port_int(ori_contact_address) == rport
1881 && sal_address_get_transport(ori_contact_address) == transport) {
1883 ms_message("Register response has up to date contact, doing nothing.");
1885 ms_warning("Register response does not have up to date contact, but last request had."
1886 "Stupid registrar detected, giving up.");
1888 found_valid_contact=TRUE;
1891 sal_address_destroy(ori_contact_address);
1894 }while(!found_valid_contact);
1895 if (!found_valid_contact)
1896 ms_message("Contact do not match, resending register.");
1900 eXosip_register_build_register(op->rid,op->expires,&msg);
1903 ms_warning("Fail to create a contact updated register.");
1906 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1907 eXosip_register_send_register(op->rid,msg);
1909 ms_message("Resending new register with updated contact");
1910 update_contact_from_response(op,last_answer);
1913 ms_warning("Fail to send updated register.");
1921 static void registration_success(Sal *sal, eXosip_event_t *ev){
1922 SalOp *op=sal_find_register(sal,ev->rid);
1923 osip_header_t *h=NULL;
1926 ms_error("Receiving register response for unknown operation");
1929 osip_message_get_expires(ev->request,0,&h);
1930 if (h!=NULL && atoi(h->hvalue)!=0){
1932 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1933 sal->callbacks.register_success(op,registered);
1936 sal->callbacks.register_success(op,FALSE);
1940 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1942 const char *reason=NULL;
1943 SalOp *op=sal_find_register(sal,ev->rid);
1944 SalReason sr=SalReasonUnknown;
1945 SalError se=SalErrorUnknown;
1948 ms_error("Receiving register failure for unknown operation");
1952 status_code=osip_message_get_status_code(ev->response);
1953 reason=osip_message_get_reason_phrase(ev->response);
1955 switch(status_code){
1958 return process_authentication(sal,ev);
1960 case 423: /*interval too brief*/
1961 {/*retry with greater interval */
1962 osip_header_t *h=NULL;
1963 osip_message_t *msg=NULL;
1964 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1965 if (h && h->hvalue && h->hvalue[0]!='\0'){
1966 int val=atoi(h->hvalue);
1967 if (val>op->expires)
1969 }else op->expires*=2;
1971 eXosip_register_build_register(op->rid,op->expires,&msg);
1972 eXosip_register_send_register(op->rid,msg);
1976 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1977 in vias, such as ekiga.net
1978 On the opposite, freephonie.net bugs when via are masqueraded.
1980 op->masquerade_via=TRUE;
1982 /* if contact is up to date, process the failure, otherwise resend a new register with
1983 updated contact first, just in case the faillure is due to incorrect contact */
1984 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1985 return TRUE; /*we are retrying with an updated contact*/
1986 if (status_code==403){
1988 sr=SalReasonForbidden;
1989 }else if (status_code==0){
1990 se=SalErrorNoResponse;
1992 sal->callbacks.register_failure(op,se,sr,reason);
1997 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1998 SalOp *op=find_op(sal,ev);
2000 ms_warning("other_request_reply(): Receiving response to unknown request.");
2004 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2005 update_contact_from_response(op,ev->response);
2006 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2007 sal->callbacks.ping_reply(op);
2009 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2010 /*out of call message acknolegment*/
2011 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2013 if (ev->response->status_code<200){
2014 status=SalTextDeliveryInProgress;
2015 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2016 status=SalTextDeliveryDone;
2019 sal->callbacks.text_delivery_update(op,status);
2023 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2024 SalOp *op=find_op(sal,ev);
2026 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2027 if (op->sipfrag_pending){
2028 send_notify_for_refer(op->did,op->sipfrag_pending);
2029 op->sipfrag_pending=NULL;
2035 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2036 ms_message("linphone process event get a message %d\n",ev->type);
2038 case EXOSIP_CALL_ANSWERED:
2039 ms_message("CALL_ANSWERED\n");
2040 call_accepted(sal,ev);
2041 authentication_ok(sal,ev);
2043 case EXOSIP_CALL_CLOSED:
2044 case EXOSIP_CALL_CANCELLED:
2045 ms_message("CALL_CLOSED or CANCELLED\n");
2046 call_terminated(sal,ev);
2048 case EXOSIP_CALL_TIMEOUT:
2049 case EXOSIP_CALL_NOANSWER:
2050 ms_message("CALL_TIMEOUT or NOANSWER\n");
2051 return call_failure(sal,ev);
2053 case EXOSIP_CALL_REQUESTFAILURE:
2054 case EXOSIP_CALL_GLOBALFAILURE:
2055 case EXOSIP_CALL_SERVERFAILURE:
2056 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2057 return call_failure(sal,ev);
2059 case EXOSIP_CALL_RELEASED:
2060 ms_message("CALL_RELEASED\n");
2061 call_released(sal, ev);
2063 case EXOSIP_CALL_INVITE:
2064 ms_message("CALL_NEW\n");
2065 inc_new_call(sal,ev);
2067 case EXOSIP_CALL_REINVITE:
2068 handle_reinvite(sal,ev);
2070 case EXOSIP_CALL_ACK:
2071 ms_message("CALL_ACK");
2074 case EXOSIP_CALL_REDIRECTED:
2075 ms_message("CALL_REDIRECTED");
2076 eXosip_default_action(ev);
2078 case EXOSIP_CALL_PROCEEDING:
2079 ms_message("CALL_PROCEEDING");
2080 call_proceeding(sal,ev);
2082 case EXOSIP_CALL_RINGING:
2083 ms_message("CALL_RINGING");
2084 call_ringing(sal,ev);
2085 authentication_ok(sal,ev);
2087 case EXOSIP_CALL_MESSAGE_NEW:
2088 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2089 call_message_new(sal,ev);
2091 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2093 (ev->response->status_code==407 || ev->response->status_code==401)){
2094 return process_authentication(sal,ev);
2097 case EXOSIP_CALL_MESSAGE_ANSWERED:
2098 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2099 process_in_call_reply(sal,ev);
2101 case EXOSIP_IN_SUBSCRIPTION_NEW:
2102 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2103 sal_exosip_subscription_recv(sal,ev);
2105 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2106 ms_message("CALL_SUBSCRIPTION_NEW ");
2107 sal_exosip_in_subscription_closed(sal,ev);
2109 case EXOSIP_SUBSCRIPTION_UPDATE:
2110 ms_message("CALL_SUBSCRIPTION_UPDATE");
2112 case EXOSIP_SUBSCRIPTION_NOTIFY:
2113 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2114 sal_exosip_notify_recv(sal,ev);
2116 case EXOSIP_SUBSCRIPTION_ANSWERED:
2117 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2118 sal_exosip_subscription_answered(sal,ev);
2120 case EXOSIP_SUBSCRIPTION_CLOSED:
2121 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2122 sal_exosip_subscription_closed(sal,ev);
2124 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2125 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2126 return process_authentication(sal,ev);
2128 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2129 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2130 sal_exosip_subscription_closed(sal,ev);
2132 case EXOSIP_REGISTRATION_FAILURE:
2133 ms_message("REGISTRATION_FAILURE\n");
2134 return registration_failure(sal,ev);
2136 case EXOSIP_REGISTRATION_SUCCESS:
2137 authentication_ok(sal,ev);
2138 registration_success(sal,ev);
2140 case EXOSIP_MESSAGE_NEW:
2141 other_request(sal,ev);
2143 case EXOSIP_MESSAGE_PROCEEDING:
2144 case EXOSIP_MESSAGE_ANSWERED:
2145 case EXOSIP_MESSAGE_REDIRECTED:
2146 case EXOSIP_MESSAGE_SERVERFAILURE:
2147 case EXOSIP_MESSAGE_GLOBALFAILURE:
2148 other_request_reply(sal,ev);
2150 case EXOSIP_MESSAGE_REQUESTFAILURE:
2151 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2153 switch (ev->response->status_code) {
2156 return process_authentication(sal,ev);
2158 eXosip_automatic_action ();
2163 other_request_reply(sal,ev);
2166 ms_message("Unhandled exosip event ! %i",ev->type);
2172 int sal_iterate(Sal *sal){
2174 while((ev=eXosip_event_wait(0,0))!=NULL){
2175 if (process_event(sal,ev))
2176 eXosip_event_free(ev);
2178 #ifdef HAVE_EXOSIP_TRYLOCK
2179 if (eXosip_trylock()==0){
2180 eXosip_automatic_refresh();
2183 ms_warning("eXosip_trylock busy.");
2187 eXosip_automatic_refresh();
2193 static void register_set_contact(osip_message_t *msg, const char *contact){
2194 osip_uri_param_t *param = NULL;
2195 osip_contact_t *ct=NULL;
2197 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2198 osip_message_get_contact(msg,0,&ct);
2200 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2201 if (param && param->gvalue)
2202 line=osip_strdup(param->gvalue);
2204 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2205 osip_message_set_contact(msg,contact);
2206 osip_message_get_contact(msg,0,&ct);
2207 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2210 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2212 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2214 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2215 osip_message_set_route(msg,tmp);
2218 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2219 osip_message_t *msg;
2220 const char *contact=sal_op_get_contact(h);
2222 sal_op_set_route(h,proxy);
2224 SalAddress *from_parsed=sal_address_new(from);
2226 char *uri, *domain_ptr = NULL;
2227 if (from_parsed==NULL) {
2228 ms_warning("sal_register() bad from %s",from);
2231 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2232 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2233 uri = sal_address_as_string_uri_only(from_parsed);
2234 if (uri) domain_ptr = strchr(uri, '@');
2236 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2238 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2240 if (uri) ms_free(uri);
2241 sal_address_destroy(from_parsed);
2243 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2245 if (contact) register_set_contact(msg,contact);
2246 sal_register_add_route(msg,proxy);
2247 sal_add_register(h->base.root,h);
2249 ms_error("Could not build initial register.");
2255 eXosip_register_build_register(h->rid,expires,&msg);
2256 sal_register_add_route(msg,proxy);
2259 eXosip_register_send_register(h->rid,msg);
2262 return (msg != NULL) ? 0 : -1;
2265 int sal_register_refresh(SalOp *op, int expires){
2266 osip_message_t *msg=NULL;
2267 const char *contact=sal_op_get_contact(op);
2270 ms_error("Unexistant registration context, not possible to refresh.");
2273 #ifdef HAVE_EXOSIP_TRYLOCK
2276 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2277 * 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
2278 * the exosip lock in a non blocking way, and give up if it takes too long*/
2279 while (eXosip_trylock()!=0){
2281 if (tries>30) {/*after 3 seconds, give up*/
2282 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2290 eXosip_register_build_register(op->rid,expires,&msg);
2292 if (contact) register_set_contact(msg,contact);
2293 sal_register_add_route(msg,sal_op_get_route(op));
2294 eXosip_register_send_register(op->rid,msg);
2295 }else ms_error("Could not build REGISTER refresh message.");
2297 return (msg != NULL) ? 0 : -1;
2301 int sal_unregister(SalOp *h){
2302 osip_message_t *msg=NULL;
2304 eXosip_register_build_register(h->rid,0,&msg);
2305 if (msg) eXosip_register_send_register(h->rid,msg);
2306 else ms_warning("Could not build unREGISTER !");
2311 SalAddress * sal_address_new(const char *uri){
2313 osip_from_init(&from);
2315 // Remove front spaces
2316 while (uri[0]==' ') {
2320 if (osip_from_parse(from,uri)!=0){
2321 osip_from_free(from);
2324 if (from->displayname!=NULL && from->displayname[0]=='"'){
2325 char *unquoted=osip_strdup_without_quote(from->displayname);
2326 osip_free(from->displayname);
2327 from->displayname=unquoted;
2329 return (SalAddress*)from;
2332 SalAddress * sal_address_clone(const SalAddress *addr){
2333 osip_from_t *ret=NULL;
2334 osip_from_clone((osip_from_t*)addr,&ret);
2335 return (SalAddress*)ret;
2338 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2340 const char *sal_address_get_scheme(const SalAddress *addr){
2341 const osip_from_t *u=(const osip_from_t*)addr;
2342 return null_if_empty(u->url->scheme);
2345 const char *sal_address_get_display_name(const SalAddress* addr){
2346 const osip_from_t *u=(const osip_from_t*)addr;
2347 return null_if_empty(u->displayname);
2350 const char *sal_address_get_username(const SalAddress *addr){
2351 const osip_from_t *u=(const osip_from_t*)addr;
2352 return null_if_empty(u->url->username);
2355 const char *sal_address_get_domain(const SalAddress *addr){
2356 const osip_from_t *u=(const osip_from_t*)addr;
2357 return null_if_empty(u->url->host);
2360 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2361 osip_from_t *u=(osip_from_t*)addr;
2362 if (u->displayname!=NULL){
2363 osip_free(u->displayname);
2364 u->displayname=NULL;
2366 if (display_name!=NULL && display_name[0]!='\0'){
2367 u->displayname=osip_strdup(display_name);
2371 void sal_address_set_username(SalAddress *addr, const char *username){
2372 osip_from_t *uri=(osip_from_t*)addr;
2373 if (uri->url->username!=NULL){
2374 osip_free(uri->url->username);
2375 uri->url->username=NULL;
2378 uri->url->username=osip_strdup(username);
2381 void sal_address_set_domain(SalAddress *addr, const char *host){
2382 osip_from_t *uri=(osip_from_t*)addr;
2383 if (uri->url->host!=NULL){
2384 osip_free(uri->url->host);
2385 uri->url->host=NULL;
2388 uri->url->host=osip_strdup(host);
2391 void sal_address_set_port(SalAddress *addr, const char *port){
2392 osip_from_t *uri=(osip_from_t*)addr;
2393 if (uri->url->port!=NULL){
2394 osip_free(uri->url->port);
2395 uri->url->port=NULL;
2398 uri->url->port=osip_strdup(port);
2401 void sal_address_set_port_int(SalAddress *uri, int port){
2404 /*this is the default, special case to leave the port field blank*/
2405 sal_address_set_port(uri,NULL);
2408 snprintf(tmp,sizeof(tmp),"%i",port);
2409 sal_address_set_port(uri,tmp);
2412 void sal_address_clean(SalAddress *addr){
2413 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2414 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2417 char *sal_address_as_string(const SalAddress *u){
2419 osip_from_t *from=(osip_from_t *)u;
2420 char *old_displayname=NULL;
2421 /* hack to force use of quotes around the displayname*/
2422 if (from->displayname!=NULL
2423 && from->displayname[0]!='"'){
2424 old_displayname=from->displayname;
2425 from->displayname=osip_enquote(from->displayname);
2427 osip_from_to_str(from,&tmp);
2428 if (old_displayname!=NULL){
2429 ms_free(from->displayname);
2430 from->displayname=old_displayname;
2437 char *sal_address_as_string_uri_only(const SalAddress *u){
2438 char *tmp=NULL,*ret;
2439 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2444 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2445 osip_uri_param_t *param=NULL;
2446 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2448 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2450 osip_free(param->gvalue);
2451 param->gvalue=value ? osip_strdup(value) : NULL;
2456 void sal_address_destroy(SalAddress *u){
2457 osip_from_free((osip_from_t*)u);
2460 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2461 ctx->keepalive_period=value;
2462 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2464 unsigned int sal_get_keepalive_period(Sal *ctx) {
2465 return ctx->keepalive_period;
2468 const char * sal_address_get_port(const SalAddress *addr) {
2469 const osip_from_t *u=(const osip_from_t*)addr;
2470 return null_if_empty(u->url->port);
2473 int sal_address_get_port_int(const SalAddress *uri) {
2474 const char* port = sal_address_get_port(uri);
2481 SalTransport sal_address_get_transport(const SalAddress* addr) {
2482 const osip_from_t *u=(const osip_from_t*)addr;
2483 osip_uri_param_t *transport_param=NULL;
2484 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2485 if (transport_param == NULL){
2486 return SalTransportUDP;
2488 return sal_transport_parse(transport_param->gvalue);
2491 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2492 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2495 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2496 int sal_call_update(SalOp *h, const char *subject){
2498 osip_message_t *reinvite=NULL;
2501 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2506 osip_message_set_subject(reinvite,subject);
2507 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2508 if (h->base.contact){
2509 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2510 osip_message_set_contact(reinvite,h->base.contact);
2512 if (h->base.root->session_expires!=0){
2513 osip_message_set_header(reinvite, "Session-expires", "200");
2514 osip_message_set_supported(reinvite, "timer");
2516 if (h->base.local_media){
2517 h->sdp_offering=TRUE;
2518 set_sdp_from_desc(reinvite,h->base.local_media);
2519 }else h->sdp_offering=FALSE;
2521 err = eXosip_call_send_request(h->did, reinvite);
2525 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2526 ctx->reuse_authorization=value;