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;
346 int sal_unlisten_ports(Sal *ctx){
355 int sal_reset_transports(Sal *ctx){
356 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
358 ms_message("Exosip transports reset.");
359 eXosip_reset_transports();
363 ms_warning("sal_reset_transports() not implemented in this version.");
369 static void set_tls_options(Sal *ctx){
371 eXosip_tls_ctx_t tlsCtx;
372 memset(&tlsCtx, 0, sizeof(tlsCtx));
373 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
374 eXosip_set_tls_ctx(&tlsCtx);
376 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
377 eXosip_tls_verify_certificate(ctx->verify_server_certs);
381 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
384 int proto=IPPROTO_UDP;
385 int keepalive = ctx->keepalive_period;
388 case SalTransportUDP:
390 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
392 case SalTransportTCP:
393 case SalTransportTLS:
396 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
397 set_tls_options(ctx);
400 ms_warning("unexpected proto, using datagram");
402 /*see if it looks like an IPv6 address*/
403 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
404 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
405 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
406 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
408 ipv6=strchr(addr,':')!=NULL;
409 eXosip_enable_ipv6(ipv6);
411 if (is_secure && tr == SalTransportUDP){
412 ms_fatal("SIP over DTLS is not supported yet.");
415 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
420 ortp_socket_t sal_get_socket(Sal *ctx){
421 #ifdef HAVE_EXOSIP_GET_SOCKET
422 return eXosip_get_socket(IPPROTO_UDP);
424 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
429 void sal_set_user_agent(Sal *ctx, const char *user_agent){
430 eXosip_set_user_agent(user_agent);
433 void sal_use_session_timers(Sal *ctx, int expires){
434 ctx->session_expires=expires;
437 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
438 ctx->one_matching_codec=one_matching_codec;
441 MSList *sal_get_pending_auths(Sal *sal){
442 return ms_list_copy(sal->pending_auths);
445 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
446 ctx->double_reg=enabled;
449 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
450 ctx->expire_old_contact=enabled;
453 void sal_use_rport(Sal *ctx, bool_t use_rports){
454 ctx->use_rports=use_rports;
456 void sal_use_101(Sal *ctx, bool_t use_101){
457 ctx->use_101=use_101;
460 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
462 ms_free(ctx->rootCa);
463 ctx->rootCa = ms_strdup(rootCa);
464 set_tls_options(ctx);
467 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
468 ctx->verify_server_certs=verify;
469 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
470 eXosip_tls_verify_certificate(verify);
474 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
475 osip_via_t *via=NULL;
476 osip_generic_param_t *param=NULL;
477 const char *rport=NULL;
481 osip_message_get_via(msg,0,&via);
483 ms_warning("extract_received_rport(): no via.");
487 *transport = sal_transport_parse(via->protocol);
489 if (via->port && via->port[0]!='\0')
490 *rportval=atoi(via->port);
492 osip_via_param_get_byname(via,"rport",¶m);
495 if (rport && rport[0]!='\0') *rportval=atoi(rport);
499 osip_via_param_get_byname(via,"received",¶m);
500 if (param) *received=param->gvalue;
502 if (rport==NULL && *received==NULL){
503 ms_warning("extract_received_rport(): no rport and no received parameters.");
509 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
513 sdp_message_to_str(msg,&sdp);
515 snprintf(clen,sizeof(clen),"%i",sdplen);
516 osip_message_set_body(sip,sdp,sdplen);
517 osip_message_set_content_type(sip,"application/sdp");
518 osip_message_set_content_length(sip,clen);
522 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
523 sdp_message_t *msg=media_description_to_sdp(desc);
525 ms_error("Fail to print sdp message !");
529 sdp_message_free(msg);
532 static void sdp_process(SalOp *h){
533 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
535 sal_media_description_unref(h->result);
537 h->result=sal_media_description_new();
538 if (h->sdp_offering){
539 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
543 sdp_message_free(h->sdp_answer);
545 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
546 h->sdp_answer=media_description_to_sdp(h->result);
547 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
548 It should contains media parameters constraint from the remote offer, not our response*/
549 strcpy(h->result->addr,h->base.remote_media->addr);
550 h->result->bandwidth=h->base.remote_media->bandwidth;
552 for(i=0;i<h->result->nstreams;++i){
553 if (h->result->streams[i].rtp_port>0){
554 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
555 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
556 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
557 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
558 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
559 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
561 if (h->result->streams[i].proto == SalProtoRtpSavp) {
562 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
570 int sal_call_is_offerer(const SalOp *h){
571 return h->sdp_offering;
574 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
576 sal_media_description_ref(desc);
577 if (h->base.local_media)
578 sal_media_description_unref(h->base.local_media);
579 h->base.local_media=desc;
580 if (h->base.remote_media){
581 /*case of an incoming call where we modify the local capabilities between the time
582 * the call is ringing and it is accepted (for example if you want to accept without video*/
583 /*reset the sdp answer so that it is computed again*/
585 sdp_message_free(h->sdp_answer);
592 int sal_call(SalOp *h, const char *from, const char *to){
595 osip_message_t *invite=NULL;
596 sal_op_set_from(h,from);
598 sal_exosip_fix_route(h);
600 h->terminated = FALSE;
602 route = sal_op_get_route(h);
603 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
605 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
606 err, from, to, route);
609 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
610 if (h->base.contact){
611 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
612 osip_message_set_contact(invite,h->base.contact);
614 if (h->base.root->session_expires!=0){
615 osip_message_set_header(invite, "Session-expires", "200");
616 osip_message_set_supported(invite, "timer");
618 if (h->base.local_media){
619 h->sdp_offering=TRUE;
620 set_sdp_from_desc(invite,h->base.local_media);
621 }else h->sdp_offering=FALSE;
623 osip_message_set_header(invite,"Replaces",h->replaces);
625 osip_message_set_header(invite,"Referred-By",h->referred_by);
629 err=eXosip_call_send_initial_invite(invite);
633 ms_error("Fail to send invite ! Error code %d", err);
636 sal_add_call(h->base.root,h);
641 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
644 /*if early media send also 180 and 183 */
648 eXosip_call_build_answer(h->tid,183,&msg);
652 set_sdp(msg,h->sdp_answer);
653 sdp_message_free(h->sdp_answer);
656 eXosip_call_send_answer(h->tid,183,msg);
661 eXosip_call_send_answer(h->tid,180,NULL);
667 int sal_call_accept(SalOp * h){
669 const char *contact=sal_op_get_contact(h);
671 int err=eXosip_call_build_answer(h->tid,200,&msg);
672 if (err<0 || msg==NULL){
673 ms_error("Fail to build answer for call: err=%i",err);
676 if (h->base.root->session_expires!=0){
677 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
681 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
682 osip_message_set_contact(msg,contact);
685 if (h->base.local_media){
686 /*this is the case where we received an invite without SDP*/
687 if (h->sdp_offering) {
688 set_sdp_from_desc(msg,h->base.local_media);
690 if (h->sdp_answer==NULL) sdp_process(h);
692 set_sdp(msg,h->sdp_answer);
693 sdp_message_free(h->sdp_answer);
698 ms_error("You are accepting a call but not defined any media capabilities !");
700 eXosip_call_send_answer(h->tid,200,msg);
704 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
705 if (reason==SalReasonBusy){
707 eXosip_call_send_answer(h->tid,486,NULL);
710 else if (reason==SalReasonTemporarilyUnavailable){
712 eXosip_call_send_answer(h->tid,480,NULL);
714 }else if (reason==SalReasonDoNotDisturb){
716 eXosip_call_send_answer(h->tid,600,NULL);
718 }else if (reason==SalReasonMedia){
720 eXosip_call_send_answer(h->tid,415,NULL);
722 }else if (redirect!=NULL && reason==SalReasonRedirect){
725 if (strstr(redirect,"sip:")!=0) code=302;
728 eXosip_call_build_answer(h->tid,code,&msg);
729 osip_message_set_contact(msg,redirect);
730 eXosip_call_send_answer(h->tid,code,msg);
732 }else sal_call_terminate(h);
736 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
737 return h->base.remote_media;
740 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
741 if (h->base.local_media && h->base.remote_media && !h->result){
747 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
748 if (refered_call->replaces)
749 h->replaces=ms_strdup(refered_call->replaces);
750 if (refered_call->referred_by)
751 h->referred_by=ms_strdup(refered_call->referred_by);
755 static int send_notify_for_refer(int did, const char *sipfrag){
758 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
761 ms_warning("Could not build NOTIFY for refer.");
764 osip_message_set_content_type(msg,"message/sipfrag");
765 osip_message_set_header(msg,"Event","refer");
766 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
767 eXosip_call_send_request(did,msg);
772 /* currently only support to notify trying and 200Ok*/
773 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
776 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
778 else if (newcall->cid!=-1){
779 if (newcall->did==-1){
780 /* not yet established*/
781 if (!newcall->terminated){
783 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
786 if (!newcall->terminated){
787 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
788 /* we need previous notify transaction to complete, so buffer the request for later*/
789 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
797 int sal_ping(SalOp *op, const char *from, const char *to){
798 osip_message_t *options=NULL;
800 sal_op_set_from(op,from);
801 sal_op_set_to(op,to);
802 sal_exosip_fix_route(op);
804 eXosip_options_build_request (&options, sal_op_get_to(op),
805 sal_op_get_from(op),sal_op_get_route(op));
807 if (op->base.root->session_expires!=0){
808 osip_message_set_header(options, "Session-expires", "200");
809 osip_message_set_supported(options, "timer");
811 sal_add_other(sal_op_get_sal(op),op,options);
812 return eXosip_options_send_request(options);
817 int sal_call_refer(SalOp *h, const char *refer_to){
818 osip_message_t *msg=NULL;
821 eXosip_call_build_refer(h->did,refer_to, &msg);
822 if (msg) err=eXosip_call_send_request(h->did, msg);
828 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
829 osip_message_t *msg=NULL;
830 char referto[256]={0};
833 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
834 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
838 eXosip_call_build_refer(h->did,referto, &msg);
839 osip_message_set_header(msg,"Referred-By",h->base.from);
840 if (msg) err=eXosip_call_send_request(h->did, msg);
846 SalOp *sal_call_get_replaces(SalOp *h){
847 if (h!=NULL && h->replaces!=NULL){
850 cid=eXosip_call_find_by_replaces(h->replaces);
853 SalOp *ret=sal_find_call(h->base.root,cid);
860 int sal_call_send_dtmf(SalOp *h, char dtmf){
861 osip_message_t *msg=NULL;
866 eXosip_call_build_info(h->did,&msg);
868 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
869 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
870 osip_message_set_content_type(msg,"application/dtmf-relay");
871 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
872 osip_message_set_content_length(msg,clen);
873 eXosip_call_send_request(h->did,msg);
879 static void push_auth_to_exosip(const SalAuthInfo *info){
881 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
882 else userid=info->userid;
883 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
884 eXosip_add_authentication_info (info->username,userid,
885 info->password, NULL,info->realm);
888 * Just for symmetry ;-)
890 static void pop_auth_from_exosip() {
891 eXosip_clear_authentication_info();
894 int sal_call_terminate(SalOp *h){
896 if (h == NULL) return -1;
897 if (h->auth_info) push_auth_to_exosip(h->auth_info);
899 err=eXosip_call_terminate(h->cid,h->did);
901 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
903 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
909 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
910 if (h->terminated) return;
911 if (h->pending_auth){
912 push_auth_to_exosip(info);
914 /*FIXME exosip does not take into account this update register message*/
916 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
920 update_contact_from_response(h,h->pending_auth->response);
922 eXosip_default_action(h->pending_auth);
924 ms_message("eXosip_default_action() done");
925 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
927 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
928 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
931 void sal_op_cancel_authentication(SalOp *h) {
933 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
934 } else if (h->cid >0) {
935 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
937 ms_warning("Auth failure not handled");
941 static void set_network_origin(SalOp *op, osip_message_t *req){
942 const char *received=NULL;
945 SalTransport transport;
946 if (extract_received_rport(req,&received,&rport,&transport)!=0){
947 osip_via_t *via=NULL;
949 osip_message_get_via(req,0,&via);
950 received=osip_via_get_host(via);
951 tmp=osip_via_get_port(via);
952 if (tmp) rport=atoi(tmp);
954 if (transport != SalTransportUDP) {
955 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
957 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
959 __sal_op_set_network_origin(op,origin);
962 static void set_remote_ua(SalOp* op, osip_message_t *req){
963 if (op->base.remote_ua==NULL){
964 osip_header_t *h=NULL;
965 osip_message_get_user_agent(req,0,&h);
967 op->base.remote_ua=ms_strdup(h->hvalue);
972 static void set_replaces(SalOp *op, osip_message_t *req){
973 osip_header_t *h=NULL;
976 ms_free(op->replaces);
979 osip_message_header_get_byname(req,"replaces",0,&h);
981 if (h->hvalue && h->hvalue[0]!='\0'){
982 op->replaces=ms_strdup(h->hvalue);
987 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
989 return sal_find_call(sal,ev->cid);
992 return sal_find_register(sal,ev->rid);
995 return sal_find_out_subscribe(sal,ev->sid);
998 return sal_find_in_subscribe(sal,ev->nid);
1000 if (ev->response) return sal_find_other(sal,ev->response);
1001 else if (ev->request) return sal_find_other(sal,ev->request);
1005 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1006 SalOp *op=sal_op_new(sal);
1007 osip_from_t *from,*to;
1008 osip_call_info_t *call_info;
1010 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1012 set_network_origin(op,ev->request);
1013 set_remote_ua(op,ev->request);
1014 set_replaces(op,ev->request);
1017 op->sdp_offering=FALSE;
1018 op->base.remote_media=sal_media_description_new();
1019 sdp_to_media_description(sdp,op->base.remote_media);
1020 sdp_message_free(sdp);
1021 }else op->sdp_offering=TRUE;
1023 from=osip_message_get_from(ev->request);
1024 to=osip_message_get_to(ev->request);
1025 osip_from_to_str(from,&tmp);
1026 sal_op_set_from(op,tmp);
1028 osip_from_to_str(to,&tmp);
1029 sal_op_set_to(op,tmp);
1032 osip_message_get_call_info(ev->request,0,&call_info);
1035 osip_call_info_to_str(call_info,&tmp);
1036 if( strstr(tmp,"answer-after=") != NULL)
1038 op->auto_answer_asked=TRUE;
1039 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1048 sal_add_call(op->base.root,op);
1049 sal->callbacks.call_received(op);
1052 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1053 SalOp *op=find_op(sal,ev);
1057 ms_warning("Reinvite for non-existing operation !");
1062 sdp=eXosip_get_sdp_info(ev->request);
1063 if (op->base.remote_media){
1064 sal_media_description_unref(op->base.remote_media);
1065 op->base.remote_media=NULL;
1068 sal_media_description_unref(op->result);
1072 op->sdp_offering=FALSE;
1073 op->base.remote_media=sal_media_description_new();
1074 sdp_to_media_description(sdp,op->base.remote_media);
1075 sdp_message_free(sdp);
1078 op->sdp_offering=TRUE;
1080 sal->callbacks.call_updating(op);
1083 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1084 SalOp *op=find_op(sal,ev);
1088 ms_warning("ack for non-existing call !");
1091 if (op->terminated) {
1092 ms_warning("ack for terminated call, ignoring");
1096 if (op->sdp_offering){
1097 sdp=eXosip_get_sdp_info(ev->ack);
1099 if (op->base.remote_media)
1100 sal_media_description_unref(op->base.remote_media);
1101 op->base.remote_media=sal_media_description_new();
1102 sdp_to_media_description(sdp,op->base.remote_media);
1104 sdp_message_free(sdp);
1110 sal->callbacks.call_ack(op);
1113 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1114 const char *received;
1116 SalTransport transport;
1117 if (extract_received_rport(response,&received,&rport,&transport)==0){
1118 const char *contact=sal_op_get_contact(op);
1120 /*no contact given yet, use from instead*/
1121 contact=sal_op_get_from(op);
1124 SalAddress *addr=sal_address_new(contact);
1126 sal_address_set_domain(addr,received);
1127 sal_address_set_port_int(addr,rport);
1128 if (transport!=SalTransportUDP)
1129 sal_address_set_transport(addr,transport);
1130 tmp=sal_address_as_string(addr);
1131 ms_message("Contact address updated to %s",tmp);
1132 sal_op_set_contact(op,tmp);
1133 sal_address_destroy(addr);
1139 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1140 SalOp *op=find_op(sal,ev);
1142 if (op==NULL || op->terminated==TRUE) {
1143 ms_warning("This call has been canceled.");
1145 eXosip_call_terminate(ev->cid,ev->did);
1153 /* update contact if received and rport are set by the server
1154 note: will only be used by remote for next INVITE, if any...*/
1155 update_contact_from_response(op,ev->response);
1159 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1161 SalOp *op=find_op(sal,ev);
1162 if (call_proceeding(sal, ev)==-1) return;
1164 set_remote_ua(op,ev->response);
1165 sdp=eXosip_get_sdp_info(ev->response);
1167 op->base.remote_media=sal_media_description_new();
1168 sdp_to_media_description(sdp,op->base.remote_media);
1169 sdp_message_free(sdp);
1170 if (op->base.local_media) sdp_process(op);
1172 sal->callbacks.call_ringing(op);
1175 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1177 osip_message_t *msg=NULL;
1178 SalOp *op=find_op(sal,ev);
1179 const char *contact;
1181 if (op==NULL || op->terminated==TRUE) {
1182 ms_warning("This call has been already terminated.");
1184 eXosip_call_terminate(ev->cid,ev->did);
1190 set_remote_ua(op,ev->response);
1192 sdp=eXosip_get_sdp_info(ev->response);
1194 op->base.remote_media=sal_media_description_new();
1195 sdp_to_media_description(sdp,op->base.remote_media);
1196 sdp_message_free(sdp);
1197 if (op->base.local_media) sdp_process(op);
1199 eXosip_call_build_ack(ev->did,&msg);
1201 ms_warning("This call has been already terminated.");
1203 eXosip_call_terminate(ev->cid,ev->did);
1207 contact=sal_op_get_contact(op);
1209 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1210 osip_message_set_contact(msg,contact);
1212 if (op->sdp_answer){
1213 set_sdp(msg,op->sdp_answer);
1214 sdp_message_free(op->sdp_answer);
1215 op->sdp_answer=NULL;
1217 eXosip_call_send_ack(ev->did,msg);
1218 sal->callbacks.call_accepted(op);
1221 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1223 SalOp *op=find_op(sal,ev);
1225 ms_warning("Call terminated for already closed call ?");
1229 osip_from_to_str(ev->request->from,&from);
1231 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1232 if (from) osip_free(from);
1233 op->terminated=TRUE;
1236 static void call_released(Sal *sal, eXosip_event_t *ev){
1237 SalOp *op=find_op(sal,ev);
1239 ms_warning("No op associated to this call_released()");
1242 if (!op->terminated){
1243 /* no response received so far */
1244 call_failure(sal,ev);
1246 sal->callbacks.call_released(op);
1249 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1250 const char *prx_realm=NULL,*www_realm=NULL;
1251 osip_proxy_authenticate_t *prx_auth;
1252 osip_www_authenticate_t *www_auth;
1254 *username=osip_uri_get_username(resp->from->url);
1255 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1256 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1258 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1260 www_realm=osip_www_authenticate_get_realm(www_auth);
1264 }else if (www_realm){
1272 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1273 osip_authorization_t *auth=NULL;
1274 osip_proxy_authorization_t *prx_auth=NULL;
1276 *username=osip_uri_get_username(msg->from->url);
1277 osip_message_get_authorization(msg, 0, &auth);
1279 *realm=osip_authorization_get_realm(auth);
1282 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1284 *realm=osip_proxy_authorization_get_realm(prx_auth);
1290 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1291 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1292 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1296 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1297 if (op->pending_auth){
1298 return get_auth_data(op->pending_auth,realm,username);
1303 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1305 const char *username,*realm;
1308 ms_warning("No operation associated with this authentication !");
1311 if (get_auth_data(ev,&realm,&username)==0){
1312 if (op->pending_auth!=NULL){
1313 eXosip_event_free(op->pending_auth);
1314 op->pending_auth=ev;
1316 op->pending_auth=ev;
1317 sal_add_pending_auth(sal,op);
1320 sal->callbacks.auth_requested(op,realm,username);
1326 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1328 const char *username,*realm;
1331 ms_warning("No operation associated with this authentication_ok!");
1334 if (op->pending_auth){
1335 eXosip_event_free(op->pending_auth);
1336 sal_remove_pending_auth(sal,op);
1337 op->pending_auth=NULL;
1339 if (get_auth_data(ev,&realm,&username)==0){
1340 sal->callbacks.auth_success(op,realm,username);
1344 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1347 char* computedReason=NULL;
1348 const char *reason=NULL;
1349 SalError error=SalErrorUnknown;
1350 SalReason sr=SalReasonUnknown;
1353 op=(SalOp*)find_op(sal,ev);
1356 ms_warning("Call failure reported for a closed call, ignored.");
1361 code=osip_message_get_status_code(ev->response);
1362 reason=osip_message_get_reason_phrase(ev->response);
1363 osip_header_t *h=NULL;
1364 if (!osip_message_header_get_byname( ev->response
1368 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1369 reason = computedReason;
1377 return process_authentication(sal,ev);
1380 error=SalErrorUnknown;
1383 error=SalErrorFailure;
1384 sr=SalReasonNotFound;
1387 error=SalErrorFailure;
1391 eXosip_default_action(ev);
1395 error=SalErrorFailure;
1396 sr=SalReasonTemporarilyUnavailable;
1398 error=SalErrorFailure;
1404 error=SalErrorFailure;
1405 sr=SalReasonDoNotDisturb;
1408 error=SalErrorFailure;
1409 sr=SalReasonDeclined;
1413 error=SalErrorFailure;
1414 sr=SalReasonUnknown;
1415 }else error=SalErrorNoResponse;
1417 op->terminated=TRUE;
1418 sal->callbacks.call_failure(op,error,sr,reason,code);
1419 if (computedReason != NULL){
1420 ms_free(computedReason);
1425 /* Request remote side to send us VFU */
1426 void sal_call_send_vfu_request(SalOp *h){
1427 osip_message_t *msg=NULL;
1429 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1433 " <picture_fast_update></picture_fast_update>"
1441 eXosip_call_build_info(h->did,&msg);
1443 osip_message_set_body(msg,info_body,strlen(info_body));
1444 osip_message_set_content_type(msg,"application/media_control+xml");
1445 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1446 osip_message_set_content_length(msg,clen);
1447 eXosip_call_send_request(h->did,msg);
1448 ms_message("Sending VFU request !");
1453 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1454 SalOp *op=find_op(sal,ev);
1455 osip_body_t *body=NULL;
1458 ms_warning("media control xml received without operation context!");
1462 osip_message_get_body(ev->request,0,&body);
1463 if (body && body->body!=NULL &&
1464 strstr(body->body,"picture_fast_update")){
1465 osip_message_t *ans=NULL;
1466 ms_message("Receiving VFU request !");
1467 if (sal->callbacks.vfu_request){
1468 sal->callbacks.vfu_request(op);
1469 eXosip_call_build_answer(ev->tid,200,&ans);
1471 eXosip_call_send_answer(ev->tid,200,ans);
1475 /*in all other cases we must say it is not implemented.*/
1477 osip_message_t *ans=NULL;
1479 eXosip_call_build_answer(ev->tid,501,&ans);
1481 eXosip_call_send_answer(ev->tid,501,ans);
1486 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1487 SalOp *op=find_op(sal,ev);
1488 osip_body_t *body=NULL;
1491 ms_warning("media dtmf relay received without operation context!");
1495 osip_message_get_body(ev->request,0,&body);
1496 if (body && body->body!=NULL){
1497 osip_message_t *ans=NULL;
1498 const char *name=strstr(body->body,"Signal");
1499 if (name==NULL) name=strstr(body->body,"signal");
1501 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1504 name+=strlen("signal");
1505 if (sscanf(name," = %1s",tmp)==1){
1506 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1507 if (sal->callbacks.dtmf_received != NULL)
1508 sal->callbacks.dtmf_received(op, tmp[0]);
1512 eXosip_call_build_answer(ev->tid,200,&ans);
1514 eXosip_call_send_answer(ev->tid,200,ans);
1519 static void fill_options_answer(osip_message_t *options){
1520 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1521 osip_message_set_accept(options,"application/sdp");
1524 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1525 osip_header_t *h=NULL;
1526 osip_message_t *ans=NULL;
1527 ms_message("Receiving REFER request !");
1528 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1531 osip_from_t *from=NULL;
1533 osip_from_init(&from);
1535 if (osip_from_parse(from,h->hvalue)==0){
1537 osip_uri_header_t *uh=NULL;
1538 osip_header_t *referred_by=NULL;
1539 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1540 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1541 ms_message("Found replaces in Refer-To");
1543 ms_free(op->replaces);
1545 op->replaces=ms_strdup(uh->gvalue);
1547 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1548 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1549 if (op->referred_by)
1550 ms_free(op->referred_by);
1551 op->referred_by=ms_strdup(referred_by->hvalue);
1554 osip_uri_header_freelist(&from->url->url_headers);
1555 osip_from_to_str(from,&tmp);
1556 sal->callbacks.refer_received(sal,op,tmp);
1558 osip_from_free(from);
1561 eXosip_call_build_answer(ev->tid,202,&ans);
1563 eXosip_call_send_answer(ev->tid,202,ans);
1568 ms_warning("cannot do anything with the refer without destination\n");
1572 static void process_notify(Sal *sal, eXosip_event_t *ev){
1573 osip_header_t *h=NULL;
1575 SalOp *op=find_op(sal,ev);
1576 osip_message_t *ans=NULL;
1578 ms_message("Receiving NOTIFY request !");
1579 osip_from_to_str(ev->request->from,&from);
1580 osip_message_header_get_byname(ev->request,"Event",0,&h);
1582 osip_body_t *body=NULL;
1583 //osip_content_type_t *ct=NULL;
1584 osip_message_get_body(ev->request,0,&body);
1585 //ct=osip_message_get_content_type(ev->request);
1586 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1587 /*special handling of refer events*/
1588 if (body && body->body){
1589 osip_message_t *msg;
1590 osip_message_init(&msg);
1591 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1592 int code=osip_message_get_status_code(msg);
1594 sal->callbacks.notify_refer(op,SalReferTrying);
1595 }else if (code==200){
1596 sal->callbacks.notify_refer(op,SalReferSuccess);
1597 }else if (code>=400){
1598 sal->callbacks.notify_refer(op,SalReferFailed);
1601 osip_message_free(msg);
1604 /*generic handling*/
1605 sal->callbacks.notify(op,from,h->hvalue);
1608 /*answer that we received the notify*/
1610 eXosip_call_build_answer(ev->tid,200,&ans);
1612 eXosip_call_send_answer(ev->tid,200,ans);
1617 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1618 osip_message_t *ans=NULL;
1620 if (MSG_IS_INFO(ev->request)){
1621 osip_content_type_t *ct;
1622 ct=osip_message_get_content_type(ev->request);
1623 if (ct && ct->subtype){
1624 if (strcmp(ct->subtype,"media_control+xml")==0)
1625 process_media_control_xml(sal,ev);
1626 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1627 process_dtmf_relay(sal,ev);
1629 ms_message("Unhandled SIP INFO.");
1630 /*send an "Not implemented" answer*/
1632 eXosip_call_build_answer(ev->tid,501,&ans);
1634 eXosip_call_send_answer(ev->tid,501,ans);
1638 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1640 eXosip_call_build_answer(ev->tid,200,&ans);
1642 eXosip_call_send_answer(ev->tid,200,ans);
1645 }else if(MSG_IS_MESSAGE(ev->request)){
1646 /* SIP messages could be received into call */
1647 text_received(sal, ev);
1649 eXosip_call_build_answer(ev->tid,200,&ans);
1651 eXosip_call_send_answer(ev->tid,200,ans);
1653 }else if(MSG_IS_REFER(ev->request)){
1654 SalOp *op=find_op(sal,ev);
1656 ms_message("Receiving REFER request !");
1657 process_refer(sal,op,ev);
1658 }else if(MSG_IS_NOTIFY(ev->request)){
1659 process_notify(sal,ev);
1660 }else if (MSG_IS_OPTIONS(ev->request)){
1662 eXosip_call_build_answer(ev->tid,200,&ans);
1664 fill_options_answer(ans);
1665 eXosip_call_send_answer(ev->tid,200,ans);
1669 }else ms_warning("call_message_new: No request ?");
1672 static void inc_update(Sal *sal, eXosip_event_t *ev){
1673 osip_message_t *msg=NULL;
1674 ms_message("Processing incoming UPDATE");
1676 eXosip_message_build_answer(ev->tid,200,&msg);
1678 eXosip_message_send_answer(ev->tid,200,msg);
1682 static bool_t comes_from_local_if(osip_message_t *msg){
1683 osip_via_t *via=NULL;
1684 osip_message_get_via(msg,0,&via);
1687 host=osip_via_get_host(via);
1688 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1689 osip_generic_param_t *param=NULL;
1690 osip_via_param_get_byname(via,"received",¶m);
1691 if (param==NULL) return TRUE;
1692 if (param->gvalue &&
1693 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1701 static void text_received(Sal *sal, eXosip_event_t *ev){
1702 osip_body_t *body=NULL;
1703 char *from=NULL,*msg;
1705 osip_message_get_body(ev->request,0,&body);
1707 ms_error("Could not get text message from SIP body");
1711 osip_from_to_str(ev->request->from,&from);
1712 sal->callbacks.text_received(sal,from,msg);
1718 static void other_request(Sal *sal, eXosip_event_t *ev){
1719 ms_message("in other_request");
1720 if (ev->request==NULL) return;
1721 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1722 text_received(sal,ev);
1723 eXosip_message_send_answer(ev->tid,200,NULL);
1724 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1725 osip_message_t *options=NULL;
1726 eXosip_options_build_answer(ev->tid,200,&options);
1727 fill_options_answer(options);
1728 eXosip_options_send_answer(ev->tid,200,options);
1729 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1730 ms_message("Receiving REFER request !");
1731 if (comes_from_local_if(ev->request)) {
1732 process_refer(sal,NULL,ev);
1733 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1734 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1739 osip_message_to_str(ev->request,&tmp,&msglen);
1741 ms_message("Unsupported request received:\n%s",tmp);
1744 /*answer with a 501 Not implemented*/
1745 eXosip_message_send_answer(ev->tid,501,NULL);
1749 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1750 osip_via_t *via=NULL;
1751 osip_message_get_via(msg,0,&via);
1753 osip_free(via->port);
1754 via->port=osip_strdup(port);
1755 osip_free(via->host);
1756 via->host=osip_strdup(ip);
1761 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1762 osip_contact_t *ctt=NULL;
1763 const char *received;
1765 SalTransport transport;
1768 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1769 osip_message_get_contact(request,0,&ctt);
1771 ms_warning("fix_message_contact(): no contact to update");
1774 if (expire_last_contact){
1775 osip_contact_t *oldct=NULL,*prevct;
1776 osip_generic_param_t *param=NULL;
1777 osip_contact_clone(ctt,&oldct);
1778 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1779 osip_contact_free(prevct);
1780 osip_list_remove(&request->contacts,1);
1782 osip_list_add(&request->contacts,oldct,1);
1783 osip_contact_param_get_byname(oldct,"expires",¶m);
1785 if (param->gvalue) osip_free(param->gvalue);
1786 param->gvalue=osip_strdup("0");
1788 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1791 if (ctt->url->host!=NULL){
1792 osip_free(ctt->url->host);
1794 ctt->url->host=osip_strdup(received);
1795 if (ctt->url->port!=NULL){
1796 osip_free(ctt->url->port);
1798 snprintf(port,sizeof(port),"%i",rport);
1799 ctt->url->port=osip_strdup(port);
1800 if (op->masquerade_via) masquerade_via(request,received,port);
1802 if (transport != SalTransportUDP) {
1803 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1808 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1809 osip_contact_t *ctt=NULL;
1810 SalAddress* ori_contact_address=NULL;
1811 const char *received;
1813 SalTransport transport;
1815 osip_message_t *msg=NULL;
1816 Sal* sal=op->base.root;
1818 bool_t found_valid_contact=FALSE;
1819 bool_t from_request=FALSE;
1821 if (sal->double_reg==FALSE ) return FALSE;
1823 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1826 osip_message_get_contact(last_answer,i,&ctt);
1827 if (!from_request && ctt==NULL) {
1828 osip_message_get_contact(orig_request,0,&ctt);
1832 osip_contact_to_str(ctt,&tmp);
1833 ori_contact_address = sal_address_new(tmp);
1835 /*check if contact is up to date*/
1836 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1837 && sal_address_get_port_int(ori_contact_address) == rport
1838 && sal_address_get_transport(ori_contact_address) == transport) {
1840 ms_message("Register response has up to date contact, doing nothing.");
1842 ms_warning("Register response does not have up to date contact, but last request had."
1843 "Stupid registrar detected, giving up.");
1845 found_valid_contact=TRUE;
1848 sal_address_destroy(ori_contact_address);
1851 }while(!found_valid_contact);
1852 if (!found_valid_contact)
1853 ms_message("Contact do not match, resending register.");
1857 eXosip_register_build_register(op->rid,op->expires,&msg);
1860 ms_warning("Fail to create a contact updated register.");
1863 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1864 eXosip_register_send_register(op->rid,msg);
1866 ms_message("Resending new register with updated contact");
1867 update_contact_from_response(op,last_answer);
1870 ms_warning("Fail to send updated register.");
1878 static void registration_success(Sal *sal, eXosip_event_t *ev){
1879 SalOp *op=sal_find_register(sal,ev->rid);
1880 osip_header_t *h=NULL;
1883 ms_error("Receiving register response for unknown operation");
1886 osip_message_get_expires(ev->request,0,&h);
1887 if (h!=NULL && atoi(h->hvalue)!=0){
1889 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1890 sal->callbacks.register_success(op,registered);
1893 sal->callbacks.register_success(op,FALSE);
1897 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1899 const char *reason=NULL;
1900 SalOp *op=sal_find_register(sal,ev->rid);
1901 SalReason sr=SalReasonUnknown;
1902 SalError se=SalErrorUnknown;
1905 ms_error("Receiving register failure for unknown operation");
1909 status_code=osip_message_get_status_code(ev->response);
1910 reason=osip_message_get_reason_phrase(ev->response);
1912 switch(status_code){
1915 return process_authentication(sal,ev);
1917 case 423: /*interval too brief*/
1918 {/*retry with greater interval */
1919 osip_header_t *h=NULL;
1920 osip_message_t *msg=NULL;
1921 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1922 if (h && h->hvalue && h->hvalue[0]!='\0'){
1923 int val=atoi(h->hvalue);
1924 if (val>op->expires)
1926 }else op->expires*=2;
1928 eXosip_register_build_register(op->rid,op->expires,&msg);
1929 eXosip_register_send_register(op->rid,msg);
1933 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1934 in vias, such as ekiga.net
1935 On the opposite, freephonie.net bugs when via are masqueraded.
1937 op->masquerade_via=TRUE;
1939 /* if contact is up to date, process the failure, otherwise resend a new register with
1940 updated contact first, just in case the faillure is due to incorrect contact */
1941 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1942 return TRUE; /*we are retrying with an updated contact*/
1943 if (status_code==403){
1945 sr=SalReasonForbidden;
1946 }else if (status_code==0){
1947 se=SalErrorNoResponse;
1949 sal->callbacks.register_failure(op,se,sr,reason);
1954 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1955 SalOp *op=find_op(sal,ev);
1957 ms_warning("other_request_reply(): Receiving response to unknown request.");
1961 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
1962 update_contact_from_response(op,ev->response);
1963 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
1964 sal->callbacks.ping_reply(op);
1966 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
1967 /*out of call message acknolegment*/
1968 SalTextDeliveryStatus status=SalTextDeliveryFailed;
1970 if (ev->response->status_code<200){
1971 status=SalTextDeliveryInProgress;
1972 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
1973 status=SalTextDeliveryDone;
1976 sal->callbacks.text_delivery_update(op,status);
1980 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
1981 SalOp *op=find_op(sal,ev);
1983 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
1984 if (op->sipfrag_pending){
1985 send_notify_for_refer(op->did,op->sipfrag_pending);
1986 op->sipfrag_pending=NULL;
1992 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
1993 ms_message("linphone process event get a message %d\n",ev->type);
1995 case EXOSIP_CALL_ANSWERED:
1996 ms_message("CALL_ANSWERED\n");
1997 call_accepted(sal,ev);
1998 authentication_ok(sal,ev);
2000 case EXOSIP_CALL_CLOSED:
2001 case EXOSIP_CALL_CANCELLED:
2002 ms_message("CALL_CLOSED or CANCELLED\n");
2003 call_terminated(sal,ev);
2005 case EXOSIP_CALL_TIMEOUT:
2006 case EXOSIP_CALL_NOANSWER:
2007 ms_message("CALL_TIMEOUT or NOANSWER\n");
2008 return call_failure(sal,ev);
2010 case EXOSIP_CALL_REQUESTFAILURE:
2011 case EXOSIP_CALL_GLOBALFAILURE:
2012 case EXOSIP_CALL_SERVERFAILURE:
2013 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2014 return call_failure(sal,ev);
2016 case EXOSIP_CALL_RELEASED:
2017 ms_message("CALL_RELEASED\n");
2018 call_released(sal, ev);
2020 case EXOSIP_CALL_INVITE:
2021 ms_message("CALL_NEW\n");
2022 inc_new_call(sal,ev);
2024 case EXOSIP_CALL_REINVITE:
2025 handle_reinvite(sal,ev);
2027 case EXOSIP_CALL_ACK:
2028 ms_message("CALL_ACK");
2031 case EXOSIP_CALL_REDIRECTED:
2032 ms_message("CALL_REDIRECTED");
2033 eXosip_default_action(ev);
2035 case EXOSIP_CALL_PROCEEDING:
2036 ms_message("CALL_PROCEEDING");
2037 call_proceeding(sal,ev);
2039 case EXOSIP_CALL_RINGING:
2040 ms_message("CALL_RINGING");
2041 call_ringing(sal,ev);
2042 authentication_ok(sal,ev);
2044 case EXOSIP_CALL_MESSAGE_NEW:
2045 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2046 call_message_new(sal,ev);
2048 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2050 (ev->response->status_code==407 || ev->response->status_code==401)){
2051 return process_authentication(sal,ev);
2054 case EXOSIP_CALL_MESSAGE_ANSWERED:
2055 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2056 process_in_call_reply(sal,ev);
2058 case EXOSIP_IN_SUBSCRIPTION_NEW:
2059 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2060 sal_exosip_subscription_recv(sal,ev);
2062 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2063 ms_message("CALL_SUBSCRIPTION_NEW ");
2064 sal_exosip_in_subscription_closed(sal,ev);
2066 case EXOSIP_SUBSCRIPTION_UPDATE:
2067 ms_message("CALL_SUBSCRIPTION_UPDATE");
2069 case EXOSIP_SUBSCRIPTION_NOTIFY:
2070 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2071 sal_exosip_notify_recv(sal,ev);
2073 case EXOSIP_SUBSCRIPTION_ANSWERED:
2074 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2075 sal_exosip_subscription_answered(sal,ev);
2077 case EXOSIP_SUBSCRIPTION_CLOSED:
2078 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2079 sal_exosip_subscription_closed(sal,ev);
2081 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2082 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2083 return process_authentication(sal,ev);
2085 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2086 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2087 sal_exosip_subscription_closed(sal,ev);
2089 case EXOSIP_REGISTRATION_FAILURE:
2090 ms_message("REGISTRATION_FAILURE\n");
2091 return registration_failure(sal,ev);
2093 case EXOSIP_REGISTRATION_SUCCESS:
2094 authentication_ok(sal,ev);
2095 registration_success(sal,ev);
2097 case EXOSIP_MESSAGE_NEW:
2098 other_request(sal,ev);
2100 case EXOSIP_MESSAGE_PROCEEDING:
2101 case EXOSIP_MESSAGE_ANSWERED:
2102 case EXOSIP_MESSAGE_REDIRECTED:
2103 case EXOSIP_MESSAGE_SERVERFAILURE:
2104 case EXOSIP_MESSAGE_GLOBALFAILURE:
2105 other_request_reply(sal,ev);
2107 case EXOSIP_MESSAGE_REQUESTFAILURE:
2108 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2110 switch (ev->response->status_code) {
2113 return process_authentication(sal,ev);
2115 eXosip_automatic_action ();
2120 other_request_reply(sal,ev);
2123 ms_message("Unhandled exosip event ! %i",ev->type);
2129 int sal_iterate(Sal *sal){
2131 while((ev=eXosip_event_wait(0,0))!=NULL){
2132 if (process_event(sal,ev))
2133 eXosip_event_free(ev);
2135 #ifdef HAVE_EXOSIP_TRYLOCK
2136 if (eXosip_trylock()==0){
2137 eXosip_automatic_refresh();
2140 ms_warning("eXosip_trylock busy.");
2144 eXosip_automatic_refresh();
2150 static void register_set_contact(osip_message_t *msg, const char *contact){
2151 osip_uri_param_t *param = NULL;
2152 osip_contact_t *ct=NULL;
2154 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2155 osip_message_get_contact(msg,0,&ct);
2157 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2158 if (param && param->gvalue)
2159 line=osip_strdup(param->gvalue);
2161 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2162 osip_message_set_contact(msg,contact);
2163 osip_message_get_contact(msg,0,&ct);
2164 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2167 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2169 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2171 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2172 osip_message_set_route(msg,tmp);
2175 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2176 osip_message_t *msg;
2177 const char *contact=sal_op_get_contact(h);
2179 sal_op_set_route(h,proxy);
2181 SalAddress *from_parsed=sal_address_new(from);
2183 char *uri, *domain_ptr = NULL;
2184 if (from_parsed==NULL) {
2185 ms_warning("sal_register() bad from %s",from);
2188 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2189 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2190 uri = sal_address_as_string_uri_only(from_parsed);
2191 if (uri) domain_ptr = strchr(uri, '@');
2193 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2195 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2197 if (uri) ms_free(uri);
2198 sal_address_destroy(from_parsed);
2200 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2202 if (contact) register_set_contact(msg,contact);
2203 sal_register_add_route(msg,proxy);
2204 sal_add_register(h->base.root,h);
2206 ms_error("Could not build initial register.");
2212 eXosip_register_build_register(h->rid,expires,&msg);
2213 sal_register_add_route(msg,proxy);
2216 eXosip_register_send_register(h->rid,msg);
2219 return (msg != NULL) ? 0 : -1;
2222 int sal_register_refresh(SalOp *op, int expires){
2223 osip_message_t *msg=NULL;
2224 const char *contact=sal_op_get_contact(op);
2227 ms_error("Unexistant registration context, not possible to refresh.");
2231 eXosip_register_build_register(op->rid,expires,&msg);
2233 if (contact) register_set_contact(msg,contact);
2234 sal_register_add_route(msg,sal_op_get_route(op));
2235 eXosip_register_send_register(op->rid,msg);
2236 }else ms_error("Could not build REGISTER refresh message.");
2238 return (msg != NULL) ? 0 : -1;
2242 int sal_unregister(SalOp *h){
2243 osip_message_t *msg=NULL;
2245 eXosip_register_build_register(h->rid,0,&msg);
2246 if (msg) eXosip_register_send_register(h->rid,msg);
2247 else ms_warning("Could not build unREGISTER !");
2252 SalAddress * sal_address_new(const char *uri){
2254 osip_from_init(&from);
2256 // Remove front spaces
2257 while (uri[0]==' ') {
2261 if (osip_from_parse(from,uri)!=0){
2262 osip_from_free(from);
2265 if (from->displayname!=NULL && from->displayname[0]=='"'){
2266 char *unquoted=osip_strdup_without_quote(from->displayname);
2267 osip_free(from->displayname);
2268 from->displayname=unquoted;
2270 return (SalAddress*)from;
2273 SalAddress * sal_address_clone(const SalAddress *addr){
2274 osip_from_t *ret=NULL;
2275 osip_from_clone((osip_from_t*)addr,&ret);
2276 return (SalAddress*)ret;
2279 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2281 const char *sal_address_get_scheme(const SalAddress *addr){
2282 const osip_from_t *u=(const osip_from_t*)addr;
2283 return null_if_empty(u->url->scheme);
2286 const char *sal_address_get_display_name(const SalAddress* addr){
2287 const osip_from_t *u=(const osip_from_t*)addr;
2288 return null_if_empty(u->displayname);
2291 const char *sal_address_get_username(const SalAddress *addr){
2292 const osip_from_t *u=(const osip_from_t*)addr;
2293 return null_if_empty(u->url->username);
2296 const char *sal_address_get_domain(const SalAddress *addr){
2297 const osip_from_t *u=(const osip_from_t*)addr;
2298 return null_if_empty(u->url->host);
2301 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2302 osip_from_t *u=(osip_from_t*)addr;
2303 if (u->displayname!=NULL){
2304 osip_free(u->displayname);
2305 u->displayname=NULL;
2307 if (display_name!=NULL && display_name[0]!='\0'){
2308 u->displayname=osip_strdup(display_name);
2312 void sal_address_set_username(SalAddress *addr, const char *username){
2313 osip_from_t *uri=(osip_from_t*)addr;
2314 if (uri->url->username!=NULL){
2315 osip_free(uri->url->username);
2316 uri->url->username=NULL;
2319 uri->url->username=osip_strdup(username);
2322 void sal_address_set_domain(SalAddress *addr, const char *host){
2323 osip_from_t *uri=(osip_from_t*)addr;
2324 if (uri->url->host!=NULL){
2325 osip_free(uri->url->host);
2326 uri->url->host=NULL;
2329 uri->url->host=osip_strdup(host);
2332 void sal_address_set_port(SalAddress *addr, const char *port){
2333 osip_from_t *uri=(osip_from_t*)addr;
2334 if (uri->url->port!=NULL){
2335 osip_free(uri->url->port);
2336 uri->url->port=NULL;
2339 uri->url->port=osip_strdup(port);
2342 void sal_address_set_port_int(SalAddress *uri, int port){
2345 /*this is the default, special case to leave the port field blank*/
2346 sal_address_set_port(uri,NULL);
2349 snprintf(tmp,sizeof(tmp),"%i",port);
2350 sal_address_set_port(uri,tmp);
2353 void sal_address_clean(SalAddress *addr){
2354 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2355 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2358 char *sal_address_as_string(const SalAddress *u){
2360 osip_from_t *from=(osip_from_t *)u;
2361 char *old_displayname=NULL;
2362 /* hack to force use of quotes around the displayname*/
2363 if (from->displayname!=NULL
2364 && from->displayname[0]!='"'){
2365 old_displayname=from->displayname;
2366 from->displayname=osip_enquote(from->displayname);
2368 osip_from_to_str(from,&tmp);
2369 if (old_displayname!=NULL){
2370 ms_free(from->displayname);
2371 from->displayname=old_displayname;
2378 char *sal_address_as_string_uri_only(const SalAddress *u){
2379 char *tmp=NULL,*ret;
2380 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2385 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2386 osip_uri_param_t *param=NULL;
2387 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2389 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2391 osip_free(param->gvalue);
2392 param->gvalue=value ? osip_strdup(value) : NULL;
2397 void sal_address_destroy(SalAddress *u){
2398 osip_from_free((osip_from_t*)u);
2401 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2402 ctx->keepalive_period=value;
2403 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2405 unsigned int sal_get_keepalive_period(Sal *ctx) {
2406 return ctx->keepalive_period;
2409 const char * sal_address_get_port(const SalAddress *addr) {
2410 const osip_from_t *u=(const osip_from_t*)addr;
2411 return null_if_empty(u->url->port);
2414 int sal_address_get_port_int(const SalAddress *uri) {
2415 const char* port = sal_address_get_port(uri);
2422 SalTransport sal_address_get_transport(const SalAddress* addr) {
2423 const osip_from_t *u=(const osip_from_t*)addr;
2424 osip_uri_param_t *transport_param=NULL;
2425 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2426 if (transport_param == NULL){
2427 return SalTransportUDP;
2429 return sal_transport_parse(transport_param->gvalue);
2432 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2433 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2436 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2437 int sal_call_update(SalOp *h, const char *subject){
2439 osip_message_t *reinvite=NULL;
2442 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2447 osip_message_set_subject(reinvite,subject);
2448 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2449 if (h->base.contact){
2450 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2451 osip_message_set_contact(reinvite,h->base.contact);
2453 if (h->base.root->session_expires!=0){
2454 osip_message_set_header(reinvite, "Session-expires", "200");
2455 osip_message_set_supported(reinvite, "timer");
2457 if (h->base.local_media){
2458 h->sdp_offering=TRUE;
2459 set_sdp_from_desc(reinvite,h->base.local_media);
2460 }else h->sdp_offering=FALSE;
2462 err = eXosip_call_send_request(h->did, reinvite);
2466 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2467 ctx->reuse_authorization=value;