3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "sal_eXosip2.h"
24 #include "offeranswer.h"
27 // Necessary to make it linked
28 static void for_linker() { eXosip_transport_hook_register(NULL); }
30 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
32 static void text_received(Sal *sal, eXosip_event_t *ev);
34 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
35 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact);
36 static void update_contact_from_response(SalOp *op, osip_message_t *response);
38 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
40 while(!osip_list_eol(l,0)) {
41 data=osip_list_get(l,0);
42 osip_list_remove(l,0);
43 if (data) freefunc(data);
47 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
48 if (eXosip_guess_localip(address_family,ip,iplen)<0){
49 /*default to something */
50 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
51 ms_error("Could not find default routable ip address !");
56 static SalOp * sal_find_call(Sal *sal, int cid){
59 for(elem=sal->calls;elem!=NULL;elem=elem->next){
60 op=(SalOp*)elem->data;
61 if (op->cid==cid) return op;
66 static void sal_add_call(Sal *sal, SalOp *op){
67 sal->calls=ms_list_append(sal->calls,op);
70 static void sal_remove_call(Sal *sal, SalOp *op){
71 sal->calls=ms_list_remove(sal->calls, op);
74 static SalOp * sal_find_register(Sal *sal, int rid){
77 for(elem=sal->registers;elem!=NULL;elem=elem->next){
78 op=(SalOp*)elem->data;
79 if (op->rid==rid) return op;
84 static void sal_add_register(Sal *sal, SalOp *op){
85 sal->registers=ms_list_append(sal->registers,op);
88 static void sal_remove_register(Sal *sal, int rid){
91 for(elem=sal->registers;elem!=NULL;elem=elem->next){
92 op=(SalOp*)elem->data;
94 sal->registers=ms_list_remove_link(sal->registers,elem);
100 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
103 osip_call_id_t *callid=osip_message_get_call_id(message);
105 ms_error("There is no call-id in this message !");
108 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
109 op=(SalOp*)elem->data;
110 if (osip_call_id_match(callid,op->call_id)==0) return op;
115 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
116 osip_call_id_t *callid=osip_message_get_call_id(request);
118 ms_error("There is no call id in the request !");
121 osip_call_id_clone(callid,&op->call_id);
122 sal->other_transactions=ms_list_append(sal->other_transactions,op);
125 static void sal_remove_other(Sal *sal, SalOp *op){
126 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
130 static void sal_add_pending_auth(Sal *sal, SalOp *op){
131 sal->pending_auths=ms_list_append(sal->pending_auths,op);
135 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
136 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
139 void sal_exosip_fix_route(SalOp *op){
140 if (sal_op_get_route(op)!=NULL){
141 osip_route_t *rt=NULL;
142 osip_uri_param_t *lr_param=NULL;
144 osip_route_init(&rt);
145 if (osip_route_parse(rt,sal_op_get_route(op))<0){
146 ms_warning("Bad route %s!",sal_op_get_route(op));
147 sal_op_set_route(op,NULL);
149 /* check if the lr parameter is set , if not add it */
150 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
153 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
154 osip_route_to_str(rt,&tmproute);
155 sal_op_set_route(op,tmproute);
163 SalOp * sal_op_new(Sal *sal){
164 SalOp *op=ms_new0(SalOp,1);
165 __sal_op_init(op,sal);
166 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
168 op->supports_session_timers=FALSE;
169 op->sdp_offering=TRUE;
170 op->pending_auth=NULL;
175 op->referred_by=NULL;
176 op->masquerade_via=FALSE;
177 op->auto_answer_asked=FALSE;
179 op->terminated=FALSE;
183 bool_t sal_call_autoanswer_asked(SalOp *op)
185 return op->auto_answer_asked;
188 void sal_op_release(SalOp *op){
190 sdp_message_free(op->sdp_answer);
191 if (op->pending_auth)
192 eXosip_event_free(op->pending_auth);
194 sal_remove_register(op->base.root,op->rid);
195 eXosip_register_remove(op->rid);
198 ms_message("Cleaning cid %i",op->cid);
199 sal_remove_call(op->base.root,op);
202 sal_remove_out_subscribe(op->base.root,op);
205 sal_remove_in_subscribe(op->base.root,op);
207 osip_call_id_free(op->call_id);
210 if (op->pending_auth){
211 sal_remove_pending_auth(op->base.root,op);
214 sal_media_description_unref(op->result);
216 sal_remove_other(op->base.root,op);
217 osip_call_id_free(op->call_id);
220 ms_free(op->replaces);
222 if (op->referred_by){
223 ms_free(op->referred_by);
226 sal_auth_info_delete(op->auth_info);
231 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
232 int ortp_level=ORTP_DEBUG;
238 ortp_level=ORTP_MESSAGE;
241 ortp_level=ORTP_WARNING;
245 ortp_level=ORTP_ERROR;
248 ortp_level=ORTP_FATAL;
250 case END_TRACE_LEVEL:
253 if (ortp_log_level_enabled(level)){
254 int len=strlen(chfr);
255 char *chfrdup=ortp_strdup(chfr);
256 /*need to remove endline*/
258 if (chfrdup[len-1]=='\n')
260 if (chfrdup[len-2]=='\r')
263 ortp_logv(ortp_level,chfrdup,ap);
270 static bool_t firsttime=TRUE;
273 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
278 sal->keepalive_period=30;
279 sal->double_reg=TRUE;
280 sal->use_rports=TRUE;
282 sal->reuse_authorization=FALSE;
284 sal->verify_server_certs=TRUE;
285 sal->expire_old_contact=FALSE;
286 sal->add_dates=FALSE;
291 void sal_uninit(Sal* sal){
294 ms_free(sal->rootCa);
298 void sal_set_user_pointer(Sal *sal, void *user_data){
302 void *sal_get_user_pointer(const Sal *sal){
306 static void unimplemented_stub(){
307 ms_warning("Unimplemented SAL callback");
310 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
311 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
312 if (ctx->callbacks.call_received==NULL)
313 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
314 if (ctx->callbacks.call_ringing==NULL)
315 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
316 if (ctx->callbacks.call_accepted==NULL)
317 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
318 if (ctx->callbacks.call_failure==NULL)
319 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
320 if (ctx->callbacks.call_terminated==NULL)
321 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
322 if (ctx->callbacks.call_released==NULL)
323 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
324 if (ctx->callbacks.call_updating==NULL)
325 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
326 if (ctx->callbacks.auth_requested==NULL)
327 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
328 if (ctx->callbacks.auth_success==NULL)
329 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
330 if (ctx->callbacks.register_success==NULL)
331 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
332 if (ctx->callbacks.register_failure==NULL)
333 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
334 if (ctx->callbacks.dtmf_received==NULL)
335 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
336 if (ctx->callbacks.notify==NULL)
337 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
338 if (ctx->callbacks.notify_presence==NULL)
339 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
340 if (ctx->callbacks.subscribe_received==NULL)
341 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
342 if (ctx->callbacks.text_received==NULL)
343 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
344 if (ctx->callbacks.ping_reply==NULL)
345 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
348 int sal_unlisten_ports(Sal *ctx){
357 int sal_reset_transports(Sal *ctx){
358 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
360 ms_message("Exosip transports reset.");
361 eXosip_reset_transports();
365 ms_warning("sal_reset_transports() not implemented in this version.");
371 static void set_tls_options(Sal *ctx){
373 eXosip_tls_ctx_t tlsCtx;
374 memset(&tlsCtx, 0, sizeof(tlsCtx));
375 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
376 eXosip_set_tls_ctx(&tlsCtx);
378 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
379 eXosip_tls_verify_certificate(ctx->verify_server_certs);
383 void sal_set_dscp(Sal *ctx, int dscp){
386 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
389 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
392 int proto=IPPROTO_UDP;
393 int keepalive = ctx->keepalive_period;
396 case SalTransportUDP:
398 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
400 case SalTransportTCP:
401 case SalTransportTLS:
404 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
405 set_tls_options(ctx);
408 ms_warning("unexpected proto, using datagram");
410 /*see if it looks like an IPv6 address*/
411 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
412 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
413 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
414 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
415 sal_set_dscp(ctx,ctx->dscp);
416 sal_use_dates(ctx,ctx->add_dates);
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_dates(Sal *ctx, bool_t enabled){
464 ctx->add_dates=enabled;
465 #ifdef EXOSIP_OPT_REGISTER_WITH_DATE
468 eXosip_set_option(EXOSIP_OPT_REGISTER_WITH_DATE,&tmp);
471 if (enabled) ms_warning("Exosip does not support EXOSIP_OPT_REGISTER_WITH_DATE option.");
475 void sal_use_rport(Sal *ctx, bool_t use_rports){
476 ctx->use_rports=use_rports;
478 void sal_use_101(Sal *ctx, bool_t use_101){
479 ctx->use_101=use_101;
482 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
484 ms_free(ctx->rootCa);
485 ctx->rootCa = ms_strdup(rootCa);
486 set_tls_options(ctx);
489 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
490 ctx->verify_server_certs=verify;
491 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
492 eXosip_tls_verify_certificate(verify);
496 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
497 osip_via_t *via=NULL;
498 osip_generic_param_t *param=NULL;
499 const char *rport=NULL;
503 osip_message_get_via(msg,0,&via);
505 ms_warning("extract_received_rport(): no via.");
509 *transport = sal_transport_parse(via->protocol);
511 if (via->port && via->port[0]!='\0')
512 *rportval=atoi(via->port);
514 osip_via_param_get_byname(via,"rport",¶m);
517 if (rport && rport[0]!='\0') *rportval=atoi(rport);
521 osip_via_param_get_byname(via,"received",¶m);
522 if (param) *received=param->gvalue;
524 if (rport==NULL && *received==NULL){
525 ms_warning("extract_received_rport(): no rport and no received parameters.");
531 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
535 sdp_message_to_str(msg,&sdp);
537 snprintf(clen,sizeof(clen),"%i",sdplen);
538 osip_message_set_body(sip,sdp,sdplen);
539 osip_message_set_content_type(sip,"application/sdp");
540 osip_message_set_content_length(sip,clen);
544 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
545 sdp_message_t *msg=media_description_to_sdp(desc);
547 ms_error("Fail to print sdp message !");
551 sdp_message_free(msg);
554 static void sdp_process(SalOp *h){
555 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
557 sal_media_description_unref(h->result);
559 h->result=sal_media_description_new();
560 if (h->sdp_offering){
561 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
565 sdp_message_free(h->sdp_answer);
567 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
568 h->sdp_answer=media_description_to_sdp(h->result);
569 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
570 It should contains media parameters constraint from the remote offer, not our response*/
571 strcpy(h->result->addr,h->base.remote_media->addr);
572 h->result->bandwidth=h->base.remote_media->bandwidth;
574 for(i=0;i<h->result->nstreams;++i){
575 if (h->result->streams[i].rtp_port>0){
576 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
577 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
578 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
579 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
580 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
581 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
583 if (h->result->streams[i].proto == SalProtoRtpSavp) {
584 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
592 int sal_call_is_offerer(const SalOp *h){
593 return h->sdp_offering;
596 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
598 sal_media_description_ref(desc);
599 if (h->base.local_media)
600 sal_media_description_unref(h->base.local_media);
601 h->base.local_media=desc;
602 if (h->base.remote_media){
603 /*case of an incoming call where we modify the local capabilities between the time
604 * the call is ringing and it is accepted (for example if you want to accept without video*/
605 /*reset the sdp answer so that it is computed again*/
607 sdp_message_free(h->sdp_answer);
614 int sal_call(SalOp *h, const char *from, const char *to){
617 osip_message_t *invite=NULL;
618 osip_call_id_t *callid;
619 sal_op_set_from(h,from);
621 sal_exosip_fix_route(h);
623 h->terminated = FALSE;
625 route = sal_op_get_route(h);
626 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
628 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
629 err, from, to, route);
632 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
633 if (h->base.contact){
634 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
635 osip_message_set_contact(invite,h->base.contact);
637 if (h->base.root->session_expires!=0){
638 osip_message_set_header(invite, "Session-expires", "200");
639 osip_message_set_supported(invite, "timer");
641 if (h->base.local_media){
642 h->sdp_offering=TRUE;
643 set_sdp_from_desc(invite,h->base.local_media);
644 }else h->sdp_offering=FALSE;
646 osip_message_set_header(invite,"Replaces",h->replaces);
648 osip_message_set_header(invite,"Referred-By",h->referred_by);
652 err=eXosip_call_send_initial_invite(invite);
656 ms_error("Fail to send invite ! Error code %d", err);
659 callid=osip_message_get_call_id(invite);
660 osip_call_id_to_str(callid,(char **)(&h->base.call_id));
661 sal_add_call(h->base.root,h);
666 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
669 /*if early media send also 180 and 183 */
673 eXosip_call_build_answer(h->tid,183,&msg);
677 set_sdp(msg,h->sdp_answer);
678 sdp_message_free(h->sdp_answer);
681 eXosip_call_send_answer(h->tid,183,msg);
686 eXosip_call_send_answer(h->tid,180,NULL);
692 int sal_call_accept(SalOp * h){
694 const char *contact=sal_op_get_contact(h);
696 int err=eXosip_call_build_answer(h->tid,200,&msg);
697 if (err<0 || msg==NULL){
698 ms_error("Fail to build answer for call: err=%i",err);
701 if (h->base.root->session_expires!=0){
702 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
706 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
707 osip_message_set_contact(msg,contact);
710 if (h->base.local_media){
711 /*this is the case where we received an invite without SDP*/
712 if (h->sdp_offering) {
713 set_sdp_from_desc(msg,h->base.local_media);
715 if (h->sdp_answer==NULL) sdp_process(h);
717 set_sdp(msg,h->sdp_answer);
718 sdp_message_free(h->sdp_answer);
723 ms_error("You are accepting a call but not defined any media capabilities !");
725 eXosip_call_send_answer(h->tid,200,msg);
729 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
730 if (reason==SalReasonBusy){
732 eXosip_call_send_answer(h->tid,486,NULL);
735 else if (reason==SalReasonTemporarilyUnavailable){
737 eXosip_call_send_answer(h->tid,480,NULL);
739 }else if (reason==SalReasonDoNotDisturb){
741 eXosip_call_send_answer(h->tid,600,NULL);
743 }else if (reason==SalReasonMedia){
745 eXosip_call_send_answer(h->tid,415,NULL);
747 }else if (redirect!=NULL && reason==SalReasonRedirect){
750 if (strstr(redirect,"sip:")!=0) code=302;
753 eXosip_call_build_answer(h->tid,code,&msg);
754 osip_message_set_contact(msg,redirect);
755 eXosip_call_send_answer(h->tid,code,msg);
757 }else sal_call_terminate(h);
761 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
762 return h->base.remote_media;
765 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
766 if (h->base.local_media && h->base.remote_media && !h->result){
772 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
773 if (refered_call->replaces)
774 h->replaces=ms_strdup(refered_call->replaces);
775 if (refered_call->referred_by)
776 h->referred_by=ms_strdup(refered_call->referred_by);
780 static int send_notify_for_refer(int did, const char *sipfrag){
783 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
786 ms_warning("Could not build NOTIFY for refer.");
789 osip_message_set_content_type(msg,"message/sipfrag");
790 osip_message_set_header(msg,"Event","refer");
791 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
792 eXosip_call_send_request(did,msg);
797 /* currently only support to notify trying and 200Ok*/
798 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
801 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
803 else if (newcall->cid!=-1){
804 if (newcall->did==-1){
805 /* not yet established*/
806 if (!newcall->terminated){
808 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
811 if (!newcall->terminated){
812 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
813 /* we need previous notify transaction to complete, so buffer the request for later*/
814 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
822 int sal_ping(SalOp *op, const char *from, const char *to){
823 osip_message_t *options=NULL;
825 sal_op_set_from(op,from);
826 sal_op_set_to(op,to);
827 sal_exosip_fix_route(op);
829 eXosip_options_build_request (&options, sal_op_get_to(op),
830 sal_op_get_from(op),sal_op_get_route(op));
832 if (op->base.root->session_expires!=0){
833 osip_message_set_header(options, "Session-expires", "200");
834 osip_message_set_supported(options, "timer");
836 sal_add_other(sal_op_get_sal(op),op,options);
837 return eXosip_options_send_request(options);
842 int sal_call_refer(SalOp *h, const char *refer_to){
843 osip_message_t *msg=NULL;
846 eXosip_call_build_refer(h->did,refer_to, &msg);
847 if (msg) err=eXosip_call_send_request(h->did, msg);
853 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
854 osip_message_t *msg=NULL;
855 char referto[256]={0};
858 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
859 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
863 eXosip_call_build_refer(h->did,referto, &msg);
864 osip_message_set_header(msg,"Referred-By",h->base.from);
865 if (msg) err=eXosip_call_send_request(h->did, msg);
871 SalOp *sal_call_get_replaces(SalOp *h){
872 if (h!=NULL && h->replaces!=NULL){
875 cid=eXosip_call_find_by_replaces(h->replaces);
878 SalOp *ret=sal_find_call(h->base.root,cid);
885 int sal_call_send_dtmf(SalOp *h, char dtmf){
886 osip_message_t *msg=NULL;
891 eXosip_call_build_info(h->did,&msg);
893 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
894 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
895 osip_message_set_content_type(msg,"application/dtmf-relay");
896 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
897 osip_message_set_content_length(msg,clen);
898 eXosip_call_send_request(h->did,msg);
904 static void push_auth_to_exosip(const SalAuthInfo *info){
906 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
907 else userid=info->userid;
908 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
909 eXosip_add_authentication_info (info->username,userid,
910 info->password, NULL,info->realm);
913 * Just for symmetry ;-)
915 static void pop_auth_from_exosip() {
916 eXosip_clear_authentication_info();
919 int sal_call_terminate(SalOp *h){
921 if (h == NULL) return -1;
922 if (h->auth_info) push_auth_to_exosip(h->auth_info);
924 err=eXosip_call_terminate(h->cid,h->did);
926 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
928 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
934 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
935 if (h->terminated) return;
936 if (h->pending_auth){
937 push_auth_to_exosip(info);
939 /*FIXME exosip does not take into account this update register message*/
941 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
945 update_contact_from_response(h,h->pending_auth->response);
947 eXosip_default_action(h->pending_auth);
949 ms_message("eXosip_default_action() done");
950 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
952 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
953 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
956 void sal_op_cancel_authentication(SalOp *h) {
958 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
959 } else if (h->cid >0) {
960 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
962 ms_warning("Auth failure not handled");
966 static void set_network_origin(SalOp *op, osip_message_t *req){
967 const char *received=NULL;
970 SalTransport transport;
971 if (extract_received_rport(req,&received,&rport,&transport)!=0){
972 osip_via_t *via=NULL;
974 osip_message_get_via(req,0,&via);
975 received=osip_via_get_host(via);
976 tmp=osip_via_get_port(via);
977 if (tmp) rport=atoi(tmp);
979 if (transport != SalTransportUDP) {
980 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
982 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
984 __sal_op_set_network_origin(op,origin);
987 static void set_remote_ua(SalOp* op, osip_message_t *req){
988 if (op->base.remote_ua==NULL){
989 osip_header_t *h=NULL;
990 osip_message_get_user_agent(req,0,&h);
992 op->base.remote_ua=ms_strdup(h->hvalue);
997 static void set_replaces(SalOp *op, osip_message_t *req){
998 osip_header_t *h=NULL;
1001 ms_free(op->replaces);
1004 osip_message_header_get_byname(req,"replaces",0,&h);
1006 if (h->hvalue && h->hvalue[0]!='\0'){
1007 op->replaces=ms_strdup(h->hvalue);
1012 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
1014 return sal_find_call(sal,ev->cid);
1017 return sal_find_register(sal,ev->rid);
1020 return sal_find_out_subscribe(sal,ev->sid);
1023 return sal_find_in_subscribe(sal,ev->nid);
1025 if (ev->response) return sal_find_other(sal,ev->response);
1026 else if (ev->request) return sal_find_other(sal,ev->request);
1030 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1031 SalOp *op=sal_op_new(sal);
1032 osip_from_t *from,*to;
1033 osip_call_info_t *call_info;
1035 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1036 osip_call_id_t *callid=osip_message_get_call_id(ev->request);
1037 osip_call_id_to_str(callid,(char**)(&op->base.call_id));
1039 set_network_origin(op,ev->request);
1040 set_remote_ua(op,ev->request);
1041 set_replaces(op,ev->request);
1044 op->sdp_offering=FALSE;
1045 op->base.remote_media=sal_media_description_new();
1046 sdp_to_media_description(sdp,op->base.remote_media);
1047 sdp_message_free(sdp);
1048 }else op->sdp_offering=TRUE;
1050 from=osip_message_get_from(ev->request);
1051 to=osip_message_get_to(ev->request);
1052 osip_from_to_str(from,&tmp);
1053 sal_op_set_from(op,tmp);
1055 osip_from_to_str(to,&tmp);
1056 sal_op_set_to(op,tmp);
1059 osip_message_get_call_info(ev->request,0,&call_info);
1062 osip_call_info_to_str(call_info,&tmp);
1063 if( strstr(tmp,"answer-after=") != NULL)
1065 op->auto_answer_asked=TRUE;
1066 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1074 sal_add_call(op->base.root,op);
1075 sal->callbacks.call_received(op);
1078 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1079 SalOp *op=find_op(sal,ev);
1083 ms_warning("Reinvite for non-existing operation !");
1088 sdp=eXosip_get_sdp_info(ev->request);
1089 if (op->base.remote_media){
1090 sal_media_description_unref(op->base.remote_media);
1091 op->base.remote_media=NULL;
1094 sal_media_description_unref(op->result);
1098 op->sdp_offering=FALSE;
1099 op->base.remote_media=sal_media_description_new();
1100 sdp_to_media_description(sdp,op->base.remote_media);
1101 sdp_message_free(sdp);
1104 op->sdp_offering=TRUE;
1106 sal->callbacks.call_updating(op);
1109 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1110 SalOp *op=find_op(sal,ev);
1114 ms_warning("ack for non-existing call !");
1117 if (op->terminated) {
1118 ms_warning("ack for terminated call, ignoring");
1122 if (op->sdp_offering){
1123 sdp=eXosip_get_sdp_info(ev->ack);
1125 if (op->base.remote_media)
1126 sal_media_description_unref(op->base.remote_media);
1127 op->base.remote_media=sal_media_description_new();
1128 sdp_to_media_description(sdp,op->base.remote_media);
1130 sdp_message_free(sdp);
1136 sal->callbacks.call_ack(op);
1139 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1140 const char *received;
1142 SalTransport transport;
1143 if (extract_received_rport(response,&received,&rport,&transport)==0){
1144 const char *contact=sal_op_get_contact(op);
1146 /*no contact given yet, use from instead*/
1147 contact=sal_op_get_from(op);
1150 SalAddress *addr=sal_address_new(contact);
1152 sal_address_set_domain(addr,received);
1153 sal_address_set_port_int(addr,rport);
1154 if (transport!=SalTransportUDP)
1155 sal_address_set_transport(addr,transport);
1156 tmp=sal_address_as_string(addr);
1157 ms_message("Contact address updated to %s",tmp);
1158 sal_op_set_contact(op,tmp);
1159 sal_address_destroy(addr);
1165 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1166 SalOp *op=find_op(sal,ev);
1168 if (op==NULL || op->terminated==TRUE) {
1169 ms_warning("This call has been canceled.");
1171 eXosip_call_terminate(ev->cid,ev->did);
1179 /* update contact if received and rport are set by the server
1180 note: will only be used by remote for next INVITE, if any...*/
1181 update_contact_from_response(op,ev->response);
1185 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1187 SalOp *op=find_op(sal,ev);
1188 if (call_proceeding(sal, ev)==-1) return;
1190 set_remote_ua(op,ev->response);
1191 sdp=eXosip_get_sdp_info(ev->response);
1193 op->base.remote_media=sal_media_description_new();
1194 sdp_to_media_description(sdp,op->base.remote_media);
1195 sdp_message_free(sdp);
1196 if (op->base.local_media) sdp_process(op);
1198 sal->callbacks.call_ringing(op);
1201 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1203 osip_message_t *msg=NULL;
1204 SalOp *op=find_op(sal,ev);
1205 const char *contact;
1207 if (op==NULL || op->terminated==TRUE) {
1208 ms_warning("This call has been already terminated.");
1210 eXosip_call_terminate(ev->cid,ev->did);
1216 set_remote_ua(op,ev->response);
1218 sdp=eXosip_get_sdp_info(ev->response);
1220 op->base.remote_media=sal_media_description_new();
1221 sdp_to_media_description(sdp,op->base.remote_media);
1222 sdp_message_free(sdp);
1223 if (op->base.local_media) sdp_process(op);
1225 eXosip_call_build_ack(ev->did,&msg);
1227 ms_warning("This call has been already terminated.");
1229 eXosip_call_terminate(ev->cid,ev->did);
1233 contact=sal_op_get_contact(op);
1235 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1236 osip_message_set_contact(msg,contact);
1238 if (op->sdp_answer){
1239 set_sdp(msg,op->sdp_answer);
1240 sdp_message_free(op->sdp_answer);
1241 op->sdp_answer=NULL;
1243 eXosip_call_send_ack(ev->did,msg);
1244 sal->callbacks.call_accepted(op);
1247 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1249 SalOp *op=find_op(sal,ev);
1251 ms_warning("Call terminated for already closed call ?");
1255 osip_from_to_str(ev->request->from,&from);
1257 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1258 if (from) osip_free(from);
1259 op->terminated=TRUE;
1262 static void call_released(Sal *sal, eXosip_event_t *ev){
1263 SalOp *op=find_op(sal,ev);
1265 ms_warning("No op associated to this call_released()");
1268 if (!op->terminated){
1269 /* no response received so far */
1270 call_failure(sal,ev);
1272 sal->callbacks.call_released(op);
1275 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1276 const char *prx_realm=NULL,*www_realm=NULL;
1277 osip_proxy_authenticate_t *prx_auth;
1278 osip_www_authenticate_t *www_auth;
1280 *username=osip_uri_get_username(resp->from->url);
1281 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1282 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1284 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1286 www_realm=osip_www_authenticate_get_realm(www_auth);
1290 }else if (www_realm){
1298 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1299 osip_authorization_t *auth=NULL;
1300 osip_proxy_authorization_t *prx_auth=NULL;
1302 *username=osip_uri_get_username(msg->from->url);
1303 osip_message_get_authorization(msg, 0, &auth);
1305 *realm=osip_authorization_get_realm(auth);
1308 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1310 *realm=osip_proxy_authorization_get_realm(prx_auth);
1316 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1317 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1318 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1322 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1323 if (op->pending_auth){
1324 return get_auth_data(op->pending_auth,realm,username);
1329 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1331 const char *username,*realm;
1334 ms_warning("No operation associated with this authentication !");
1337 if (get_auth_data(ev,&realm,&username)==0){
1338 if (op->pending_auth!=NULL){
1339 eXosip_event_free(op->pending_auth);
1340 op->pending_auth=ev;
1342 op->pending_auth=ev;
1343 sal_add_pending_auth(sal,op);
1346 sal->callbacks.auth_requested(op,realm,username);
1352 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1354 const char *username,*realm;
1357 ms_warning("No operation associated with this authentication_ok!");
1360 if (op->pending_auth){
1361 eXosip_event_free(op->pending_auth);
1362 sal_remove_pending_auth(sal,op);
1363 op->pending_auth=NULL;
1365 if (get_auth_data(ev,&realm,&username)==0){
1366 sal->callbacks.auth_success(op,realm,username);
1370 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1373 char* computedReason=NULL;
1374 const char *reason=NULL;
1375 SalError error=SalErrorUnknown;
1376 SalReason sr=SalReasonUnknown;
1379 op=(SalOp*)find_op(sal,ev);
1382 ms_warning("Call failure reported for a closed call, ignored.");
1387 code=osip_message_get_status_code(ev->response);
1388 reason=osip_message_get_reason_phrase(ev->response);
1389 osip_header_t *h=NULL;
1390 if (!osip_message_header_get_byname( ev->response
1394 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1395 reason = computedReason;
1403 return process_authentication(sal,ev);
1406 error=SalErrorUnknown;
1409 error=SalErrorFailure;
1410 sr=SalReasonNotFound;
1413 error=SalErrorFailure;
1417 eXosip_default_action(ev);
1421 error=SalErrorFailure;
1422 sr=SalReasonTemporarilyUnavailable;
1424 error=SalErrorFailure;
1430 error=SalErrorFailure;
1431 sr=SalReasonDoNotDisturb;
1434 error=SalErrorFailure;
1435 sr=SalReasonDeclined;
1439 error=SalErrorFailure;
1440 sr=SalReasonUnknown;
1441 }else error=SalErrorNoResponse;
1443 op->terminated=TRUE;
1444 sal->callbacks.call_failure(op,error,sr,reason,code);
1445 if (computedReason != NULL){
1446 ms_free(computedReason);
1451 /* Request remote side to send us VFU */
1452 void sal_call_send_vfu_request(SalOp *h){
1453 osip_message_t *msg=NULL;
1455 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1459 " <picture_fast_update></picture_fast_update>"
1467 eXosip_call_build_info(h->did,&msg);
1469 osip_message_set_body(msg,info_body,strlen(info_body));
1470 osip_message_set_content_type(msg,"application/media_control+xml");
1471 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1472 osip_message_set_content_length(msg,clen);
1473 eXosip_call_send_request(h->did,msg);
1474 ms_message("Sending VFU request !");
1479 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1480 SalOp *op=find_op(sal,ev);
1481 osip_body_t *body=NULL;
1484 ms_warning("media control xml received without operation context!");
1488 osip_message_get_body(ev->request,0,&body);
1489 if (body && body->body!=NULL &&
1490 strstr(body->body,"picture_fast_update")){
1491 osip_message_t *ans=NULL;
1492 ms_message("Receiving VFU request !");
1493 if (sal->callbacks.vfu_request){
1494 sal->callbacks.vfu_request(op);
1495 eXosip_call_build_answer(ev->tid,200,&ans);
1497 eXosip_call_send_answer(ev->tid,200,ans);
1501 /*in all other cases we must say it is not implemented.*/
1503 osip_message_t *ans=NULL;
1505 eXosip_call_build_answer(ev->tid,501,&ans);
1507 eXosip_call_send_answer(ev->tid,501,ans);
1512 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1513 SalOp *op=find_op(sal,ev);
1514 osip_body_t *body=NULL;
1517 ms_warning("media dtmf relay received without operation context!");
1521 osip_message_get_body(ev->request,0,&body);
1522 if (body && body->body!=NULL){
1523 osip_message_t *ans=NULL;
1524 const char *name=strstr(body->body,"Signal");
1525 if (name==NULL) name=strstr(body->body,"signal");
1527 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1530 name+=strlen("signal");
1531 if (sscanf(name," = %1s",tmp)==1){
1532 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1533 if (sal->callbacks.dtmf_received != NULL)
1534 sal->callbacks.dtmf_received(op, tmp[0]);
1538 eXosip_call_build_answer(ev->tid,200,&ans);
1540 eXosip_call_send_answer(ev->tid,200,ans);
1545 static void fill_options_answer(osip_message_t *options){
1546 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1547 osip_message_set_accept(options,"application/sdp");
1550 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1551 osip_header_t *h=NULL;
1552 osip_message_t *ans=NULL;
1553 ms_message("Receiving REFER request !");
1554 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1557 osip_from_t *from=NULL;
1559 osip_from_init(&from);
1561 if (osip_from_parse(from,h->hvalue)==0){
1563 osip_uri_header_t *uh=NULL;
1564 osip_header_t *referred_by=NULL;
1565 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1566 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1567 ms_message("Found replaces in Refer-To");
1569 ms_free(op->replaces);
1571 op->replaces=ms_strdup(uh->gvalue);
1573 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1574 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1575 if (op->referred_by)
1576 ms_free(op->referred_by);
1577 op->referred_by=ms_strdup(referred_by->hvalue);
1580 osip_uri_header_freelist(&from->url->url_headers);
1581 osip_from_to_str(from,&tmp);
1582 sal->callbacks.refer_received(sal,op,tmp);
1584 osip_from_free(from);
1587 eXosip_call_build_answer(ev->tid,202,&ans);
1589 eXosip_call_send_answer(ev->tid,202,ans);
1594 ms_warning("cannot do anything with the refer without destination\n");
1598 static void process_notify(Sal *sal, eXosip_event_t *ev){
1599 osip_header_t *h=NULL;
1601 SalOp *op=find_op(sal,ev);
1602 osip_message_t *ans=NULL;
1604 ms_message("Receiving NOTIFY request !");
1605 osip_from_to_str(ev->request->from,&from);
1606 osip_message_header_get_byname(ev->request,"Event",0,&h);
1608 osip_body_t *body=NULL;
1609 //osip_content_type_t *ct=NULL;
1610 osip_message_get_body(ev->request,0,&body);
1611 //ct=osip_message_get_content_type(ev->request);
1612 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1613 /*special handling of refer events*/
1614 if (body && body->body){
1615 osip_message_t *msg;
1616 osip_message_init(&msg);
1617 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1618 int code=osip_message_get_status_code(msg);
1620 sal->callbacks.notify_refer(op,SalReferTrying);
1621 }else if (code==200){
1622 sal->callbacks.notify_refer(op,SalReferSuccess);
1623 }else if (code>=400){
1624 sal->callbacks.notify_refer(op,SalReferFailed);
1627 osip_message_free(msg);
1630 /*generic handling*/
1631 sal->callbacks.notify(op,from,h->hvalue);
1634 /*answer that we received the notify*/
1636 eXosip_call_build_answer(ev->tid,200,&ans);
1638 eXosip_call_send_answer(ev->tid,200,ans);
1643 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1644 osip_message_t *ans=NULL;
1646 if (MSG_IS_INFO(ev->request)){
1647 osip_content_type_t *ct;
1648 ct=osip_message_get_content_type(ev->request);
1649 if (ct && ct->subtype){
1650 if (strcmp(ct->subtype,"media_control+xml")==0)
1651 process_media_control_xml(sal,ev);
1652 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1653 process_dtmf_relay(sal,ev);
1655 ms_message("Unhandled SIP INFO.");
1656 /*send an "Not implemented" answer*/
1658 eXosip_call_build_answer(ev->tid,501,&ans);
1660 eXosip_call_send_answer(ev->tid,501,ans);
1664 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1666 eXosip_call_build_answer(ev->tid,200,&ans);
1668 eXosip_call_send_answer(ev->tid,200,ans);
1671 }else if(MSG_IS_MESSAGE(ev->request)){
1672 /* SIP messages could be received into call */
1673 text_received(sal, ev);
1675 eXosip_call_build_answer(ev->tid,200,&ans);
1677 eXosip_call_send_answer(ev->tid,200,ans);
1679 }else if(MSG_IS_REFER(ev->request)){
1680 SalOp *op=find_op(sal,ev);
1682 ms_message("Receiving REFER request !");
1683 process_refer(sal,op,ev);
1684 }else if(MSG_IS_NOTIFY(ev->request)){
1685 process_notify(sal,ev);
1686 }else if (MSG_IS_OPTIONS(ev->request)){
1688 eXosip_call_build_answer(ev->tid,200,&ans);
1690 fill_options_answer(ans);
1691 eXosip_call_send_answer(ev->tid,200,ans);
1695 }else ms_warning("call_message_new: No request ?");
1698 static void inc_update(Sal *sal, eXosip_event_t *ev){
1699 osip_message_t *msg=NULL;
1700 ms_message("Processing incoming UPDATE");
1702 eXosip_message_build_answer(ev->tid,200,&msg);
1704 eXosip_message_send_answer(ev->tid,200,msg);
1708 static bool_t comes_from_local_if(osip_message_t *msg){
1709 osip_via_t *via=NULL;
1710 osip_message_get_via(msg,0,&via);
1713 host=osip_via_get_host(via);
1714 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1715 osip_generic_param_t *param=NULL;
1716 osip_via_param_get_byname(via,"received",¶m);
1717 if (param==NULL) return TRUE;
1718 if (param->gvalue &&
1719 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1727 static void text_received(Sal *sal, eXosip_event_t *ev){
1728 osip_body_t *body=NULL;
1729 char *from=NULL,*msg=NULL;
1730 osip_content_type_t* content_type;
1731 osip_uri_param_t* external_body_url;
1732 char unquoted_external_body_url [256];
1733 int external_body_size=0;
1735 char message_id[256]={0};
1737 content_type= osip_message_get_content_type(ev->request);
1738 if (!content_type) {
1739 ms_error("Could not get message because no content type");
1742 osip_from_to_str(ev->request->from,&from);
1743 if (content_type->type
1744 && strcmp(content_type->type, "text")==0
1745 && content_type->subtype
1746 && strcmp(content_type->subtype, "plain")==0 ) {
1747 osip_message_get_body(ev->request,0,&body);
1749 ms_error("Could not get text message from SIP body");
1754 }else if (content_type->type
1755 && strcmp(content_type->type, "message")==0
1756 && content_type->subtype
1757 && strcmp(content_type->subtype, "external-body")==0 ) {
1759 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1760 /*remove both first and last character*/
1761 strncpy(unquoted_external_body_url
1762 ,&external_body_url->gvalue[1]
1763 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1764 unquoted_external_body_url[external_body_size-1]='\0';
1766 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1770 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1774 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1775 salmsg.message_id=message_id;
1776 sal->callbacks.text_received(sal,&salmsg);
1782 static void other_request(Sal *sal, eXosip_event_t *ev){
1783 ms_message("in other_request");
1784 if (ev->request==NULL) return;
1785 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1786 text_received(sal,ev);
1787 eXosip_message_send_answer(ev->tid,200,NULL);
1788 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1789 osip_message_t *options=NULL;
1790 eXosip_options_build_answer(ev->tid,200,&options);
1791 fill_options_answer(options);
1792 eXosip_options_send_answer(ev->tid,200,options);
1793 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1794 ms_message("Receiving REFER request !");
1795 if (comes_from_local_if(ev->request)) {
1796 process_refer(sal,NULL,ev);
1797 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1798 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1803 osip_message_to_str(ev->request,&tmp,&msglen);
1805 ms_message("Unsupported request received:\n%s",tmp);
1808 /*answer with a 501 Not implemented*/
1809 eXosip_message_send_answer(ev->tid,501,NULL);
1813 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1814 osip_via_t *via=NULL;
1815 osip_message_get_via(msg,0,&via);
1817 osip_free(via->port);
1818 via->port=osip_strdup(port);
1819 osip_free(via->host);
1820 via->host=osip_strdup(ip);
1825 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1826 osip_contact_t *ctt=NULL;
1827 const char *received;
1829 SalTransport transport;
1832 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1833 osip_message_get_contact(request,0,&ctt);
1835 ms_warning("fix_message_contact(): no contact to update");
1838 if (expire_last_contact){
1839 osip_contact_t *oldct=NULL,*prevct;
1840 osip_generic_param_t *param=NULL;
1841 osip_contact_clone(ctt,&oldct);
1842 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1843 osip_contact_free(prevct);
1844 osip_list_remove(&request->contacts,1);
1846 osip_list_add(&request->contacts,oldct,1);
1847 osip_contact_param_get_byname(oldct,"expires",¶m);
1849 if (param->gvalue) osip_free(param->gvalue);
1850 param->gvalue=osip_strdup("0");
1852 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1855 if (ctt->url->host!=NULL){
1856 osip_free(ctt->url->host);
1858 ctt->url->host=osip_strdup(received);
1859 if (ctt->url->port!=NULL){
1860 osip_free(ctt->url->port);
1862 snprintf(port,sizeof(port),"%i",rport);
1863 ctt->url->port=osip_strdup(port);
1864 if (op->masquerade_via) masquerade_via(request,received,port);
1866 if (transport != SalTransportUDP) {
1867 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1872 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1873 osip_contact_t *ctt=NULL;
1874 SalAddress* ori_contact_address=NULL;
1875 const char *received;
1877 SalTransport transport;
1879 osip_message_t *msg=NULL;
1880 Sal* sal=op->base.root;
1882 bool_t found_valid_contact=FALSE;
1883 bool_t from_request=FALSE;
1885 if (sal->double_reg==FALSE ) return FALSE;
1887 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1890 osip_message_get_contact(last_answer,i,&ctt);
1891 if (!from_request && ctt==NULL) {
1892 osip_message_get_contact(orig_request,0,&ctt);
1896 osip_contact_to_str(ctt,&tmp);
1897 ori_contact_address = sal_address_new(tmp);
1899 /*check if contact is up to date*/
1900 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1901 && sal_address_get_port_int(ori_contact_address) == rport
1902 && sal_address_get_transport(ori_contact_address) == transport) {
1904 ms_message("Register response has up to date contact, doing nothing.");
1906 ms_warning("Register response does not have up to date contact, but last request had."
1907 "Stupid registrar detected, giving up.");
1909 found_valid_contact=TRUE;
1912 sal_address_destroy(ori_contact_address);
1915 }while(!found_valid_contact);
1916 if (!found_valid_contact)
1917 ms_message("Contact do not match, resending register.");
1921 eXosip_register_build_register(op->rid,op->expires,&msg);
1924 ms_warning("Fail to create a contact updated register.");
1927 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1928 eXosip_register_send_register(op->rid,msg);
1930 ms_message("Resending new register with updated contact");
1931 update_contact_from_response(op,last_answer);
1934 ms_warning("Fail to send updated register.");
1942 static void registration_success(Sal *sal, eXosip_event_t *ev){
1943 SalOp *op=sal_find_register(sal,ev->rid);
1944 osip_header_t *h=NULL;
1947 ms_error("Receiving register response for unknown operation");
1950 osip_message_get_expires(ev->request,0,&h);
1951 if (h!=NULL && atoi(h->hvalue)!=0){
1953 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1954 sal->callbacks.register_success(op,registered);
1957 sal->callbacks.register_success(op,FALSE);
1961 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1963 const char *reason=NULL;
1964 SalOp *op=sal_find_register(sal,ev->rid);
1965 SalReason sr=SalReasonUnknown;
1966 SalError se=SalErrorUnknown;
1969 ms_error("Receiving register failure for unknown operation");
1973 status_code=osip_message_get_status_code(ev->response);
1974 reason=osip_message_get_reason_phrase(ev->response);
1976 switch(status_code){
1979 return process_authentication(sal,ev);
1981 case 423: /*interval too brief*/
1982 {/*retry with greater interval */
1983 osip_header_t *h=NULL;
1984 osip_message_t *msg=NULL;
1985 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1986 if (h && h->hvalue && h->hvalue[0]!='\0'){
1987 int val=atoi(h->hvalue);
1988 if (val>op->expires)
1990 }else op->expires*=2;
1992 eXosip_register_build_register(op->rid,op->expires,&msg);
1993 eXosip_register_send_register(op->rid,msg);
1997 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1998 in vias, such as ekiga.net
1999 On the opposite, freephonie.net bugs when via are masqueraded.
2001 op->masquerade_via=TRUE;
2003 /* if contact is up to date, process the failure, otherwise resend a new register with
2004 updated contact first, just in case the faillure is due to incorrect contact */
2005 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2006 return TRUE; /*we are retrying with an updated contact*/
2007 if (status_code==403){
2009 sr=SalReasonForbidden;
2010 }else if (status_code==0){
2011 se=SalErrorNoResponse;
2013 sal->callbacks.register_failure(op,se,sr,reason);
2018 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2019 SalOp *op=find_op(sal,ev);
2021 ms_warning("other_request_reply(): Receiving response to unknown request.");
2025 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2026 update_contact_from_response(op,ev->response);
2027 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2028 sal->callbacks.ping_reply(op);
2030 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2031 /*out of call message acknolegment*/
2032 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2034 if (ev->response->status_code<200){
2035 status=SalTextDeliveryInProgress;
2036 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2037 status=SalTextDeliveryDone;
2040 sal->callbacks.text_delivery_update(op,status);
2044 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2045 SalOp *op=find_op(sal,ev);
2047 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2048 if (op->sipfrag_pending){
2049 send_notify_for_refer(op->did,op->sipfrag_pending);
2050 op->sipfrag_pending=NULL;
2056 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2057 ms_message("linphone process event get a message %d\n",ev->type);
2059 case EXOSIP_CALL_ANSWERED:
2060 ms_message("CALL_ANSWERED\n");
2061 call_accepted(sal,ev);
2062 authentication_ok(sal,ev);
2064 case EXOSIP_CALL_CLOSED:
2065 case EXOSIP_CALL_CANCELLED:
2066 ms_message("CALL_CLOSED or CANCELLED\n");
2067 call_terminated(sal,ev);
2069 case EXOSIP_CALL_TIMEOUT:
2070 case EXOSIP_CALL_NOANSWER:
2071 ms_message("CALL_TIMEOUT or NOANSWER\n");
2072 return call_failure(sal,ev);
2074 case EXOSIP_CALL_REQUESTFAILURE:
2075 case EXOSIP_CALL_GLOBALFAILURE:
2076 case EXOSIP_CALL_SERVERFAILURE:
2077 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2078 return call_failure(sal,ev);
2080 case EXOSIP_CALL_RELEASED:
2081 ms_message("CALL_RELEASED\n");
2082 call_released(sal, ev);
2084 case EXOSIP_CALL_INVITE:
2085 ms_message("CALL_NEW\n");
2086 inc_new_call(sal,ev);
2088 case EXOSIP_CALL_REINVITE:
2089 handle_reinvite(sal,ev);
2091 case EXOSIP_CALL_ACK:
2092 ms_message("CALL_ACK");
2095 case EXOSIP_CALL_REDIRECTED:
2096 ms_message("CALL_REDIRECTED");
2097 eXosip_default_action(ev);
2099 case EXOSIP_CALL_PROCEEDING:
2100 ms_message("CALL_PROCEEDING");
2101 call_proceeding(sal,ev);
2103 case EXOSIP_CALL_RINGING:
2104 ms_message("CALL_RINGING");
2105 call_ringing(sal,ev);
2106 authentication_ok(sal,ev);
2108 case EXOSIP_CALL_MESSAGE_NEW:
2109 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2110 call_message_new(sal,ev);
2112 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2114 (ev->response->status_code==407 || ev->response->status_code==401)){
2115 return process_authentication(sal,ev);
2118 case EXOSIP_CALL_MESSAGE_ANSWERED:
2119 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2120 process_in_call_reply(sal,ev);
2122 case EXOSIP_IN_SUBSCRIPTION_NEW:
2123 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2124 sal_exosip_subscription_recv(sal,ev);
2126 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2127 ms_message("CALL_SUBSCRIPTION_NEW ");
2128 sal_exosip_in_subscription_closed(sal,ev);
2130 case EXOSIP_SUBSCRIPTION_UPDATE:
2131 ms_message("CALL_SUBSCRIPTION_UPDATE");
2133 case EXOSIP_SUBSCRIPTION_NOTIFY:
2134 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2135 sal_exosip_notify_recv(sal,ev);
2137 case EXOSIP_SUBSCRIPTION_ANSWERED:
2138 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2139 sal_exosip_subscription_answered(sal,ev);
2141 case EXOSIP_SUBSCRIPTION_CLOSED:
2142 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2143 sal_exosip_subscription_closed(sal,ev);
2145 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2146 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2147 return process_authentication(sal,ev);
2149 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2150 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2151 sal_exosip_subscription_closed(sal,ev);
2153 case EXOSIP_REGISTRATION_FAILURE:
2154 ms_message("REGISTRATION_FAILURE\n");
2155 return registration_failure(sal,ev);
2157 case EXOSIP_REGISTRATION_SUCCESS:
2158 authentication_ok(sal,ev);
2159 registration_success(sal,ev);
2161 case EXOSIP_MESSAGE_NEW:
2162 other_request(sal,ev);
2164 case EXOSIP_MESSAGE_PROCEEDING:
2165 case EXOSIP_MESSAGE_ANSWERED:
2166 case EXOSIP_MESSAGE_REDIRECTED:
2167 case EXOSIP_MESSAGE_SERVERFAILURE:
2168 case EXOSIP_MESSAGE_GLOBALFAILURE:
2169 other_request_reply(sal,ev);
2171 case EXOSIP_MESSAGE_REQUESTFAILURE:
2172 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2174 switch (ev->response->status_code) {
2177 return process_authentication(sal,ev);
2179 eXosip_automatic_action ();
2184 other_request_reply(sal,ev);
2187 ms_message("Unhandled exosip event ! %i",ev->type);
2193 int sal_iterate(Sal *sal){
2195 while((ev=eXosip_event_wait(0,0))!=NULL){
2196 if (process_event(sal,ev))
2197 eXosip_event_free(ev);
2199 #ifdef HAVE_EXOSIP_TRYLOCK
2200 if (eXosip_trylock()==0){
2201 eXosip_automatic_refresh();
2204 ms_warning("eXosip_trylock busy.");
2208 eXosip_automatic_refresh();
2214 static void register_set_contact(osip_message_t *msg, const char *contact){
2215 osip_uri_param_t *param = NULL;
2216 osip_contact_t *ct=NULL;
2218 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2219 osip_message_get_contact(msg,0,&ct);
2221 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2222 if (param && param->gvalue)
2223 line=osip_strdup(param->gvalue);
2225 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2226 osip_message_set_contact(msg,contact);
2227 osip_message_get_contact(msg,0,&ct);
2228 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2231 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2233 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2235 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2236 osip_message_set_route(msg,tmp);
2240 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2241 osip_message_t *msg;
2242 const char *contact=sal_op_get_contact(h);
2244 sal_op_set_route(h,proxy);
2246 SalAddress *from_parsed=sal_address_new(from);
2248 char *uri, *domain_ptr = NULL;
2249 if (from_parsed==NULL) {
2250 ms_warning("sal_register() bad from %s",from);
2253 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2254 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2255 uri = sal_address_as_string_uri_only(from_parsed);
2256 if (uri) domain_ptr = strchr(uri, '@');
2258 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2260 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2262 if (uri) ms_free(uri);
2263 sal_address_destroy(from_parsed);
2265 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2267 if (contact) register_set_contact(msg,contact);
2268 sal_register_add_route(msg,proxy);
2269 sal_add_register(h->base.root,h);
2271 ms_error("Could not build initial register.");
2277 eXosip_register_build_register(h->rid,expires,&msg);
2278 sal_register_add_route(msg,proxy);
2281 eXosip_register_send_register(h->rid,msg);
2285 return (msg != NULL) ? 0 : -1;
2288 int sal_register_refresh(SalOp *op, int expires){
2289 osip_message_t *msg=NULL;
2290 const char *contact=sal_op_get_contact(op);
2293 ms_error("Unexistant registration context, not possible to refresh.");
2296 #ifdef HAVE_EXOSIP_TRYLOCK
2299 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2300 * 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
2301 * the exosip lock in a non blocking way, and give up if it takes too long*/
2302 while (eXosip_trylock()!=0){
2304 if (tries>30) {/*after 3 seconds, give up*/
2305 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2313 eXosip_register_build_register(op->rid,expires,&msg);
2315 if (contact) register_set_contact(msg,contact);
2316 sal_register_add_route(msg,sal_op_get_route(op));
2317 eXosip_register_send_register(op->rid,msg);
2318 }else ms_error("Could not build REGISTER refresh message.");
2320 return (msg != NULL) ? 0 : -1;
2324 int sal_unregister(SalOp *h){
2325 osip_message_t *msg=NULL;
2327 eXosip_register_build_register(h->rid,0,&msg);
2328 if (msg) eXosip_register_send_register(h->rid,msg);
2329 else ms_warning("Could not build unREGISTER !");
2334 SalAddress * sal_address_new(const char *uri){
2336 osip_from_init(&from);
2338 // Remove front spaces
2339 while (uri[0]==' ') {
2343 if (osip_from_parse(from,uri)!=0){
2344 osip_from_free(from);
2347 if (from->displayname!=NULL && from->displayname[0]=='"'){
2348 char *unquoted=osip_strdup_without_quote(from->displayname);
2349 osip_free(from->displayname);
2350 from->displayname=unquoted;
2352 return (SalAddress*)from;
2355 SalAddress * sal_address_clone(const SalAddress *addr){
2356 osip_from_t *ret=NULL;
2357 osip_from_clone((osip_from_t*)addr,&ret);
2358 return (SalAddress*)ret;
2361 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2363 const char *sal_address_get_scheme(const SalAddress *addr){
2364 const osip_from_t *u=(const osip_from_t*)addr;
2365 return null_if_empty(u->url->scheme);
2368 const char *sal_address_get_display_name(const SalAddress* addr){
2369 const osip_from_t *u=(const osip_from_t*)addr;
2370 return null_if_empty(u->displayname);
2373 const char *sal_address_get_username(const SalAddress *addr){
2374 const osip_from_t *u=(const osip_from_t*)addr;
2375 return null_if_empty(u->url->username);
2378 const char *sal_address_get_domain(const SalAddress *addr){
2379 const osip_from_t *u=(const osip_from_t*)addr;
2380 return null_if_empty(u->url->host);
2383 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2384 osip_from_t *u=(osip_from_t*)addr;
2385 if (u->displayname!=NULL){
2386 osip_free(u->displayname);
2387 u->displayname=NULL;
2389 if (display_name!=NULL && display_name[0]!='\0'){
2390 u->displayname=osip_strdup(display_name);
2394 void sal_address_set_username(SalAddress *addr, const char *username){
2395 osip_from_t *uri=(osip_from_t*)addr;
2396 if (uri->url->username!=NULL){
2397 osip_free(uri->url->username);
2398 uri->url->username=NULL;
2401 uri->url->username=osip_strdup(username);
2404 void sal_address_set_domain(SalAddress *addr, const char *host){
2405 osip_from_t *uri=(osip_from_t*)addr;
2406 if (uri->url->host!=NULL){
2407 osip_free(uri->url->host);
2408 uri->url->host=NULL;
2411 uri->url->host=osip_strdup(host);
2414 void sal_address_set_port(SalAddress *addr, const char *port){
2415 osip_from_t *uri=(osip_from_t*)addr;
2416 if (uri->url->port!=NULL){
2417 osip_free(uri->url->port);
2418 uri->url->port=NULL;
2421 uri->url->port=osip_strdup(port);
2424 void sal_address_set_port_int(SalAddress *uri, int port){
2427 /*this is the default, special case to leave the port field blank*/
2428 sal_address_set_port(uri,NULL);
2431 snprintf(tmp,sizeof(tmp),"%i",port);
2432 sal_address_set_port(uri,tmp);
2435 void sal_address_clean(SalAddress *addr){
2436 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2437 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2440 char *sal_address_as_string(const SalAddress *u){
2442 osip_from_t *from=(osip_from_t *)u;
2443 char *old_displayname=NULL;
2444 /* hack to force use of quotes around the displayname*/
2445 if (from->displayname!=NULL
2446 && from->displayname[0]!='"'){
2447 old_displayname=from->displayname;
2448 from->displayname=osip_enquote(from->displayname);
2450 osip_from_to_str(from,&tmp);
2451 if (old_displayname!=NULL){
2452 ms_free(from->displayname);
2453 from->displayname=old_displayname;
2460 char *sal_address_as_string_uri_only(const SalAddress *u){
2461 char *tmp=NULL,*ret;
2462 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2467 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2468 osip_uri_param_t *param=NULL;
2469 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2471 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2473 osip_free(param->gvalue);
2474 param->gvalue=value ? osip_strdup(value) : NULL;
2479 void sal_address_destroy(SalAddress *u){
2480 osip_from_free((osip_from_t*)u);
2483 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2484 ctx->keepalive_period=value;
2485 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2487 unsigned int sal_get_keepalive_period(Sal *ctx) {
2488 return ctx->keepalive_period;
2491 const char * sal_address_get_port(const SalAddress *addr) {
2492 const osip_from_t *u=(const osip_from_t*)addr;
2493 return null_if_empty(u->url->port);
2496 int sal_address_get_port_int(const SalAddress *uri) {
2497 const char* port = sal_address_get_port(uri);
2504 SalTransport sal_address_get_transport(const SalAddress* addr) {
2505 const osip_from_t *u=(const osip_from_t*)addr;
2506 osip_uri_param_t *transport_param=NULL;
2507 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2508 if (transport_param == NULL){
2509 return SalTransportUDP;
2511 return sal_transport_parse(transport_param->gvalue);
2514 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2515 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2518 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2519 int sal_call_update(SalOp *h, const char *subject){
2521 osip_message_t *reinvite=NULL;
2524 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2529 osip_message_set_subject(reinvite,subject);
2530 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2531 if (h->base.contact){
2532 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2533 osip_message_set_contact(reinvite,h->base.contact);
2535 if (h->base.root->session_expires!=0){
2536 osip_message_set_header(reinvite, "Session-expires", "200");
2537 osip_message_set_supported(reinvite, "timer");
2539 if (h->base.local_media){
2540 h->sdp_offering=TRUE;
2541 set_sdp_from_desc(reinvite,h->base.local_media);
2542 }else h->sdp_offering=FALSE;
2544 err = eXosip_call_send_request(h->did, reinvite);
2548 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2549 ctx->reuse_authorization=value;