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");
1753 }else if (content_type->type
1754 && strcmp(content_type->type, "message")==0
1755 && content_type->subtype
1756 && strcmp(content_type->subtype, "external-body")==0 ) {
1758 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1759 /*remove both first and last character*/
1760 strncpy(unquoted_external_body_url
1761 ,&external_body_url->gvalue[1]
1762 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1763 unquoted_external_body_url[external_body_size-1]='\0';
1765 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1769 snprintf(message_id,sizeof(message_id)-1,"%s%s",ev->request->call_id->number,ev->request->cseq->number);
1773 salmsg.url=external_body_size>0 ? unquoted_external_body_url : NULL;
1774 salmsg.message_id=message_id;
1775 sal->callbacks.text_received(sal,&salmsg);
1781 static void other_request(Sal *sal, eXosip_event_t *ev){
1782 ms_message("in other_request");
1783 if (ev->request==NULL) return;
1784 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1785 text_received(sal,ev);
1786 eXosip_message_send_answer(ev->tid,200,NULL);
1787 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1788 osip_message_t *options=NULL;
1789 eXosip_options_build_answer(ev->tid,200,&options);
1790 fill_options_answer(options);
1791 eXosip_options_send_answer(ev->tid,200,options);
1792 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1793 ms_message("Receiving REFER request !");
1794 if (comes_from_local_if(ev->request)) {
1795 process_refer(sal,NULL,ev);
1796 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1797 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1802 osip_message_to_str(ev->request,&tmp,&msglen);
1804 ms_message("Unsupported request received:\n%s",tmp);
1807 /*answer with a 501 Not implemented*/
1808 eXosip_message_send_answer(ev->tid,501,NULL);
1812 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1813 osip_via_t *via=NULL;
1814 osip_message_get_via(msg,0,&via);
1816 osip_free(via->port);
1817 via->port=osip_strdup(port);
1818 osip_free(via->host);
1819 via->host=osip_strdup(ip);
1824 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1825 osip_contact_t *ctt=NULL;
1826 const char *received;
1828 SalTransport transport;
1831 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1832 osip_message_get_contact(request,0,&ctt);
1834 ms_warning("fix_message_contact(): no contact to update");
1837 if (expire_last_contact){
1838 osip_contact_t *oldct=NULL,*prevct;
1839 osip_generic_param_t *param=NULL;
1840 osip_contact_clone(ctt,&oldct);
1841 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1842 osip_contact_free(prevct);
1843 osip_list_remove(&request->contacts,1);
1845 osip_list_add(&request->contacts,oldct,1);
1846 osip_contact_param_get_byname(oldct,"expires",¶m);
1848 if (param->gvalue) osip_free(param->gvalue);
1849 param->gvalue=osip_strdup("0");
1851 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1854 if (ctt->url->host!=NULL){
1855 osip_free(ctt->url->host);
1857 ctt->url->host=osip_strdup(received);
1858 if (ctt->url->port!=NULL){
1859 osip_free(ctt->url->port);
1861 snprintf(port,sizeof(port),"%i",rport);
1862 ctt->url->port=osip_strdup(port);
1863 if (op->masquerade_via) masquerade_via(request,received,port);
1865 if (transport != SalTransportUDP) {
1866 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1871 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1872 osip_contact_t *ctt=NULL;
1873 SalAddress* ori_contact_address=NULL;
1874 const char *received;
1876 SalTransport transport;
1878 osip_message_t *msg=NULL;
1879 Sal* sal=op->base.root;
1881 bool_t found_valid_contact=FALSE;
1882 bool_t from_request=FALSE;
1884 if (sal->double_reg==FALSE ) return FALSE;
1886 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1889 osip_message_get_contact(last_answer,i,&ctt);
1890 if (!from_request && ctt==NULL) {
1891 osip_message_get_contact(orig_request,0,&ctt);
1895 osip_contact_to_str(ctt,&tmp);
1896 ori_contact_address = sal_address_new(tmp);
1898 /*check if contact is up to date*/
1899 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1900 && sal_address_get_port_int(ori_contact_address) == rport
1901 && sal_address_get_transport(ori_contact_address) == transport) {
1903 ms_message("Register response has up to date contact, doing nothing.");
1905 ms_warning("Register response does not have up to date contact, but last request had."
1906 "Stupid registrar detected, giving up.");
1908 found_valid_contact=TRUE;
1911 sal_address_destroy(ori_contact_address);
1914 }while(!found_valid_contact);
1915 if (!found_valid_contact)
1916 ms_message("Contact do not match, resending register.");
1920 eXosip_register_build_register(op->rid,op->expires,&msg);
1923 ms_warning("Fail to create a contact updated register.");
1926 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1927 eXosip_register_send_register(op->rid,msg);
1929 ms_message("Resending new register with updated contact");
1930 update_contact_from_response(op,last_answer);
1933 ms_warning("Fail to send updated register.");
1941 static void registration_success(Sal *sal, eXosip_event_t *ev){
1942 SalOp *op=sal_find_register(sal,ev->rid);
1943 osip_header_t *h=NULL;
1946 ms_error("Receiving register response for unknown operation");
1949 osip_message_get_expires(ev->request,0,&h);
1950 if (h!=NULL && atoi(h->hvalue)!=0){
1952 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1953 sal->callbacks.register_success(op,registered);
1956 sal->callbacks.register_success(op,FALSE);
1960 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1962 const char *reason=NULL;
1963 SalOp *op=sal_find_register(sal,ev->rid);
1964 SalReason sr=SalReasonUnknown;
1965 SalError se=SalErrorUnknown;
1968 ms_error("Receiving register failure for unknown operation");
1972 status_code=osip_message_get_status_code(ev->response);
1973 reason=osip_message_get_reason_phrase(ev->response);
1975 switch(status_code){
1978 return process_authentication(sal,ev);
1980 case 423: /*interval too brief*/
1981 {/*retry with greater interval */
1982 osip_header_t *h=NULL;
1983 osip_message_t *msg=NULL;
1984 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1985 if (h && h->hvalue && h->hvalue[0]!='\0'){
1986 int val=atoi(h->hvalue);
1987 if (val>op->expires)
1989 }else op->expires*=2;
1991 eXosip_register_build_register(op->rid,op->expires,&msg);
1992 eXosip_register_send_register(op->rid,msg);
1996 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1997 in vias, such as ekiga.net
1998 On the opposite, freephonie.net bugs when via are masqueraded.
2000 op->masquerade_via=TRUE;
2002 /* if contact is up to date, process the failure, otherwise resend a new register with
2003 updated contact first, just in case the faillure is due to incorrect contact */
2004 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
2005 return TRUE; /*we are retrying with an updated contact*/
2006 if (status_code==403){
2008 sr=SalReasonForbidden;
2009 }else if (status_code==0){
2010 se=SalErrorNoResponse;
2012 sal->callbacks.register_failure(op,se,sr,reason);
2017 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
2018 SalOp *op=find_op(sal,ev);
2020 ms_warning("other_request_reply(): Receiving response to unknown request.");
2024 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2025 update_contact_from_response(op,ev->response);
2026 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2027 sal->callbacks.ping_reply(op);
2029 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2030 /*out of call message acknolegment*/
2031 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2033 if (ev->response->status_code<200){
2034 status=SalTextDeliveryInProgress;
2035 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2036 status=SalTextDeliveryDone;
2039 sal->callbacks.text_delivery_update(op,status);
2043 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2044 SalOp *op=find_op(sal,ev);
2046 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2047 if (op->sipfrag_pending){
2048 send_notify_for_refer(op->did,op->sipfrag_pending);
2049 op->sipfrag_pending=NULL;
2055 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2056 ms_message("linphone process event get a message %d\n",ev->type);
2058 case EXOSIP_CALL_ANSWERED:
2059 ms_message("CALL_ANSWERED\n");
2060 call_accepted(sal,ev);
2061 authentication_ok(sal,ev);
2063 case EXOSIP_CALL_CLOSED:
2064 case EXOSIP_CALL_CANCELLED:
2065 ms_message("CALL_CLOSED or CANCELLED\n");
2066 call_terminated(sal,ev);
2068 case EXOSIP_CALL_TIMEOUT:
2069 case EXOSIP_CALL_NOANSWER:
2070 ms_message("CALL_TIMEOUT or NOANSWER\n");
2071 return call_failure(sal,ev);
2073 case EXOSIP_CALL_REQUESTFAILURE:
2074 case EXOSIP_CALL_GLOBALFAILURE:
2075 case EXOSIP_CALL_SERVERFAILURE:
2076 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2077 return call_failure(sal,ev);
2079 case EXOSIP_CALL_RELEASED:
2080 ms_message("CALL_RELEASED\n");
2081 call_released(sal, ev);
2083 case EXOSIP_CALL_INVITE:
2084 ms_message("CALL_NEW\n");
2085 inc_new_call(sal,ev);
2087 case EXOSIP_CALL_REINVITE:
2088 handle_reinvite(sal,ev);
2090 case EXOSIP_CALL_ACK:
2091 ms_message("CALL_ACK");
2094 case EXOSIP_CALL_REDIRECTED:
2095 ms_message("CALL_REDIRECTED");
2096 eXosip_default_action(ev);
2098 case EXOSIP_CALL_PROCEEDING:
2099 ms_message("CALL_PROCEEDING");
2100 call_proceeding(sal,ev);
2102 case EXOSIP_CALL_RINGING:
2103 ms_message("CALL_RINGING");
2104 call_ringing(sal,ev);
2105 authentication_ok(sal,ev);
2107 case EXOSIP_CALL_MESSAGE_NEW:
2108 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2109 call_message_new(sal,ev);
2111 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2113 (ev->response->status_code==407 || ev->response->status_code==401)){
2114 return process_authentication(sal,ev);
2117 case EXOSIP_CALL_MESSAGE_ANSWERED:
2118 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2119 process_in_call_reply(sal,ev);
2121 case EXOSIP_IN_SUBSCRIPTION_NEW:
2122 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2123 sal_exosip_subscription_recv(sal,ev);
2125 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2126 ms_message("CALL_SUBSCRIPTION_NEW ");
2127 sal_exosip_in_subscription_closed(sal,ev);
2129 case EXOSIP_SUBSCRIPTION_UPDATE:
2130 ms_message("CALL_SUBSCRIPTION_UPDATE");
2132 case EXOSIP_SUBSCRIPTION_NOTIFY:
2133 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2134 sal_exosip_notify_recv(sal,ev);
2136 case EXOSIP_SUBSCRIPTION_ANSWERED:
2137 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2138 sal_exosip_subscription_answered(sal,ev);
2140 case EXOSIP_SUBSCRIPTION_CLOSED:
2141 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2142 sal_exosip_subscription_closed(sal,ev);
2144 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2145 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2146 return process_authentication(sal,ev);
2148 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2149 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2150 sal_exosip_subscription_closed(sal,ev);
2152 case EXOSIP_REGISTRATION_FAILURE:
2153 ms_message("REGISTRATION_FAILURE\n");
2154 return registration_failure(sal,ev);
2156 case EXOSIP_REGISTRATION_SUCCESS:
2157 authentication_ok(sal,ev);
2158 registration_success(sal,ev);
2160 case EXOSIP_MESSAGE_NEW:
2161 other_request(sal,ev);
2163 case EXOSIP_MESSAGE_PROCEEDING:
2164 case EXOSIP_MESSAGE_ANSWERED:
2165 case EXOSIP_MESSAGE_REDIRECTED:
2166 case EXOSIP_MESSAGE_SERVERFAILURE:
2167 case EXOSIP_MESSAGE_GLOBALFAILURE:
2168 other_request_reply(sal,ev);
2170 case EXOSIP_MESSAGE_REQUESTFAILURE:
2171 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2173 switch (ev->response->status_code) {
2176 return process_authentication(sal,ev);
2178 eXosip_automatic_action ();
2183 other_request_reply(sal,ev);
2186 ms_message("Unhandled exosip event ! %i",ev->type);
2192 int sal_iterate(Sal *sal){
2194 while((ev=eXosip_event_wait(0,0))!=NULL){
2195 if (process_event(sal,ev))
2196 eXosip_event_free(ev);
2198 #ifdef HAVE_EXOSIP_TRYLOCK
2199 if (eXosip_trylock()==0){
2200 eXosip_automatic_refresh();
2203 ms_warning("eXosip_trylock busy.");
2207 eXosip_automatic_refresh();
2213 static void register_set_contact(osip_message_t *msg, const char *contact){
2214 osip_uri_param_t *param = NULL;
2215 osip_contact_t *ct=NULL;
2217 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2218 osip_message_get_contact(msg,0,&ct);
2220 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2221 if (param && param->gvalue)
2222 line=osip_strdup(param->gvalue);
2224 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2225 osip_message_set_contact(msg,contact);
2226 osip_message_get_contact(msg,0,&ct);
2227 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2230 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2232 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2234 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2235 osip_message_set_route(msg,tmp);
2239 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2240 osip_message_t *msg;
2241 const char *contact=sal_op_get_contact(h);
2243 sal_op_set_route(h,proxy);
2245 SalAddress *from_parsed=sal_address_new(from);
2247 char *uri, *domain_ptr = NULL;
2248 if (from_parsed==NULL) {
2249 ms_warning("sal_register() bad from %s",from);
2252 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2253 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2254 uri = sal_address_as_string_uri_only(from_parsed);
2255 if (uri) domain_ptr = strchr(uri, '@');
2257 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2259 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2261 if (uri) ms_free(uri);
2262 sal_address_destroy(from_parsed);
2264 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2266 if (contact) register_set_contact(msg,contact);
2267 sal_register_add_route(msg,proxy);
2268 sal_add_register(h->base.root,h);
2270 ms_error("Could not build initial register.");
2276 eXosip_register_build_register(h->rid,expires,&msg);
2277 sal_register_add_route(msg,proxy);
2280 eXosip_register_send_register(h->rid,msg);
2284 return (msg != NULL) ? 0 : -1;
2287 int sal_register_refresh(SalOp *op, int expires){
2288 osip_message_t *msg=NULL;
2289 const char *contact=sal_op_get_contact(op);
2292 ms_error("Unexistant registration context, not possible to refresh.");
2295 #ifdef HAVE_EXOSIP_TRYLOCK
2298 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2299 * 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
2300 * the exosip lock in a non blocking way, and give up if it takes too long*/
2301 while (eXosip_trylock()!=0){
2303 if (tries>30) {/*after 3 seconds, give up*/
2304 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2312 eXosip_register_build_register(op->rid,expires,&msg);
2314 if (contact) register_set_contact(msg,contact);
2315 sal_register_add_route(msg,sal_op_get_route(op));
2316 eXosip_register_send_register(op->rid,msg);
2317 }else ms_error("Could not build REGISTER refresh message.");
2319 return (msg != NULL) ? 0 : -1;
2323 int sal_unregister(SalOp *h){
2324 osip_message_t *msg=NULL;
2326 eXosip_register_build_register(h->rid,0,&msg);
2327 if (msg) eXosip_register_send_register(h->rid,msg);
2328 else ms_warning("Could not build unREGISTER !");
2333 SalAddress * sal_address_new(const char *uri){
2335 osip_from_init(&from);
2337 // Remove front spaces
2338 while (uri[0]==' ') {
2342 if (osip_from_parse(from,uri)!=0){
2343 osip_from_free(from);
2346 if (from->displayname!=NULL && from->displayname[0]=='"'){
2347 char *unquoted=osip_strdup_without_quote(from->displayname);
2348 osip_free(from->displayname);
2349 from->displayname=unquoted;
2351 return (SalAddress*)from;
2354 SalAddress * sal_address_clone(const SalAddress *addr){
2355 osip_from_t *ret=NULL;
2356 osip_from_clone((osip_from_t*)addr,&ret);
2357 return (SalAddress*)ret;
2360 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2362 const char *sal_address_get_scheme(const SalAddress *addr){
2363 const osip_from_t *u=(const osip_from_t*)addr;
2364 return null_if_empty(u->url->scheme);
2367 const char *sal_address_get_display_name(const SalAddress* addr){
2368 const osip_from_t *u=(const osip_from_t*)addr;
2369 return null_if_empty(u->displayname);
2372 const char *sal_address_get_username(const SalAddress *addr){
2373 const osip_from_t *u=(const osip_from_t*)addr;
2374 return null_if_empty(u->url->username);
2377 const char *sal_address_get_domain(const SalAddress *addr){
2378 const osip_from_t *u=(const osip_from_t*)addr;
2379 return null_if_empty(u->url->host);
2382 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2383 osip_from_t *u=(osip_from_t*)addr;
2384 if (u->displayname!=NULL){
2385 osip_free(u->displayname);
2386 u->displayname=NULL;
2388 if (display_name!=NULL && display_name[0]!='\0'){
2389 u->displayname=osip_strdup(display_name);
2393 void sal_address_set_username(SalAddress *addr, const char *username){
2394 osip_from_t *uri=(osip_from_t*)addr;
2395 if (uri->url->username!=NULL){
2396 osip_free(uri->url->username);
2397 uri->url->username=NULL;
2400 uri->url->username=osip_strdup(username);
2403 void sal_address_set_domain(SalAddress *addr, const char *host){
2404 osip_from_t *uri=(osip_from_t*)addr;
2405 if (uri->url->host!=NULL){
2406 osip_free(uri->url->host);
2407 uri->url->host=NULL;
2410 uri->url->host=osip_strdup(host);
2413 void sal_address_set_port(SalAddress *addr, const char *port){
2414 osip_from_t *uri=(osip_from_t*)addr;
2415 if (uri->url->port!=NULL){
2416 osip_free(uri->url->port);
2417 uri->url->port=NULL;
2420 uri->url->port=osip_strdup(port);
2423 void sal_address_set_port_int(SalAddress *uri, int port){
2426 /*this is the default, special case to leave the port field blank*/
2427 sal_address_set_port(uri,NULL);
2430 snprintf(tmp,sizeof(tmp),"%i",port);
2431 sal_address_set_port(uri,tmp);
2434 void sal_address_clean(SalAddress *addr){
2435 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2436 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2439 char *sal_address_as_string(const SalAddress *u){
2441 osip_from_t *from=(osip_from_t *)u;
2442 char *old_displayname=NULL;
2443 /* hack to force use of quotes around the displayname*/
2444 if (from->displayname!=NULL
2445 && from->displayname[0]!='"'){
2446 old_displayname=from->displayname;
2447 from->displayname=osip_enquote(from->displayname);
2449 osip_from_to_str(from,&tmp);
2450 if (old_displayname!=NULL){
2451 ms_free(from->displayname);
2452 from->displayname=old_displayname;
2459 char *sal_address_as_string_uri_only(const SalAddress *u){
2460 char *tmp=NULL,*ret;
2461 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2466 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2467 osip_uri_param_t *param=NULL;
2468 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2470 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2472 osip_free(param->gvalue);
2473 param->gvalue=value ? osip_strdup(value) : NULL;
2478 void sal_address_destroy(SalAddress *u){
2479 osip_from_free((osip_from_t*)u);
2482 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2483 ctx->keepalive_period=value;
2484 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2486 unsigned int sal_get_keepalive_period(Sal *ctx) {
2487 return ctx->keepalive_period;
2490 const char * sal_address_get_port(const SalAddress *addr) {
2491 const osip_from_t *u=(const osip_from_t*)addr;
2492 return null_if_empty(u->url->port);
2495 int sal_address_get_port_int(const SalAddress *uri) {
2496 const char* port = sal_address_get_port(uri);
2503 SalTransport sal_address_get_transport(const SalAddress* addr) {
2504 const osip_from_t *u=(const osip_from_t*)addr;
2505 osip_uri_param_t *transport_param=NULL;
2506 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2507 if (transport_param == NULL){
2508 return SalTransportUDP;
2510 return sal_transport_parse(transport_param->gvalue);
2513 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2514 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2517 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2518 int sal_call_update(SalOp *h, const char *subject){
2520 osip_message_t *reinvite=NULL;
2523 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2528 osip_message_set_subject(reinvite,subject);
2529 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2530 if (h->base.contact){
2531 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2532 osip_message_set_contact(reinvite,h->base.contact);
2534 if (h->base.root->session_expires!=0){
2535 osip_message_set_header(reinvite, "Session-expires", "200");
2536 osip_message_set_supported(reinvite, "timer");
2538 if (h->base.local_media){
2539 h->sdp_offering=TRUE;
2540 set_sdp_from_desc(reinvite,h->base.local_media);
2541 }else h->sdp_offering=FALSE;
2543 err = eXosip_call_send_request(h->did, reinvite);
2547 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2548 ctx->reuse_authorization=value;