3 Copyright (C) 2010 Simon MORLAT (simon.morlat@free.fr)
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License
7 as published by the Free Software Foundation; either version 2
8 of the License, or (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23 #include "sal_eXosip2.h"
24 #include "offeranswer.h"
27 // Necessary to make it linked
28 static void for_linker() { eXosip_transport_hook_register(NULL); }
30 static bool_t call_failure(Sal *sal, eXosip_event_t *ev);
32 static void text_received(Sal *sal, eXosip_event_t *ev);
34 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port);
35 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact);
36 static void update_contact_from_response(SalOp *op, osip_message_t *response);
38 void _osip_list_set_empty(osip_list_t *l, void (*freefunc)(void*)){
40 while(!osip_list_eol(l,0)) {
41 data=osip_list_get(l,0);
42 osip_list_remove(l,0);
43 if (data) freefunc(data);
47 void sal_get_default_local_ip(Sal *sal, int address_family,char *ip, size_t iplen){
48 if (eXosip_guess_localip(address_family,ip,iplen)<0){
49 /*default to something */
50 strncpy(ip,address_family==AF_INET6 ? "::1" : "127.0.0.1",iplen);
51 ms_error("Could not find default routable ip address !");
56 static SalOp * sal_find_call(Sal *sal, int cid){
59 for(elem=sal->calls;elem!=NULL;elem=elem->next){
60 op=(SalOp*)elem->data;
61 if (op->cid==cid) return op;
66 static void sal_add_call(Sal *sal, SalOp *op){
67 sal->calls=ms_list_append(sal->calls,op);
70 static void sal_remove_call(Sal *sal, SalOp *op){
71 sal->calls=ms_list_remove(sal->calls, op);
74 static SalOp * sal_find_register(Sal *sal, int rid){
77 for(elem=sal->registers;elem!=NULL;elem=elem->next){
78 op=(SalOp*)elem->data;
79 if (op->rid==rid) return op;
84 static void sal_add_register(Sal *sal, SalOp *op){
85 sal->registers=ms_list_append(sal->registers,op);
88 static void sal_remove_register(Sal *sal, int rid){
91 for(elem=sal->registers;elem!=NULL;elem=elem->next){
92 op=(SalOp*)elem->data;
94 sal->registers=ms_list_remove_link(sal->registers,elem);
100 static SalOp * sal_find_other(Sal *sal, osip_message_t *message){
103 osip_call_id_t *callid=osip_message_get_call_id(message);
105 ms_error("There is no call-id in this message !");
108 for(elem=sal->other_transactions;elem!=NULL;elem=elem->next){
109 op=(SalOp*)elem->data;
110 if (osip_call_id_match(callid,op->call_id)==0) return op;
115 void sal_add_other(Sal *sal, SalOp *op, osip_message_t *request){
116 osip_call_id_t *callid=osip_message_get_call_id(request);
118 ms_error("There is no call id in the request !");
121 osip_call_id_clone(callid,&op->call_id);
122 sal->other_transactions=ms_list_append(sal->other_transactions,op);
125 static void sal_remove_other(Sal *sal, SalOp *op){
126 sal->other_transactions=ms_list_remove(sal->other_transactions,op);
130 static void sal_add_pending_auth(Sal *sal, SalOp *op){
131 sal->pending_auths=ms_list_append(sal->pending_auths,op);
135 static void sal_remove_pending_auth(Sal *sal, SalOp *op){
136 sal->pending_auths=ms_list_remove(sal->pending_auths,op);
139 void sal_exosip_fix_route(SalOp *op){
140 if (sal_op_get_route(op)!=NULL){
141 osip_route_t *rt=NULL;
142 osip_uri_param_t *lr_param=NULL;
144 osip_route_init(&rt);
145 if (osip_route_parse(rt,sal_op_get_route(op))<0){
146 ms_warning("Bad route %s!",sal_op_get_route(op));
147 sal_op_set_route(op,NULL);
149 /* check if the lr parameter is set , if not add it */
150 osip_uri_uparam_get_byname(rt->url, "lr", &lr_param);
153 osip_uri_uparam_add(rt->url,osip_strdup("lr"),NULL);
154 osip_route_to_str(rt,&tmproute);
155 sal_op_set_route(op,tmproute);
163 SalOp * sal_op_new(Sal *sal){
164 SalOp *op=ms_new0(SalOp,1);
165 __sal_op_init(op,sal);
166 op->cid=op->did=op->tid=op->rid=op->nid=op->sid=-1;
168 op->supports_session_timers=FALSE;
169 op->sdp_offering=TRUE;
170 op->pending_auth=NULL;
175 op->referred_by=NULL;
176 op->masquerade_via=FALSE;
177 op->auto_answer_asked=FALSE;
179 op->terminated=FALSE;
183 bool_t sal_call_autoanswer_asked(SalOp *op)
185 return op->auto_answer_asked;
188 void sal_op_release(SalOp *op){
190 sdp_message_free(op->sdp_answer);
191 if (op->pending_auth)
192 eXosip_event_free(op->pending_auth);
194 sal_remove_register(op->base.root,op->rid);
195 eXosip_register_remove(op->rid);
198 ms_message("Cleaning cid %i",op->cid);
199 sal_remove_call(op->base.root,op);
202 sal_remove_out_subscribe(op->base.root,op);
205 sal_remove_in_subscribe(op->base.root,op);
207 osip_call_id_free(op->call_id);
210 if (op->pending_auth){
211 sal_remove_pending_auth(op->base.root,op);
214 sal_media_description_unref(op->result);
216 sal_remove_other(op->base.root,op);
217 osip_call_id_free(op->call_id);
220 ms_free(op->replaces);
222 if (op->referred_by){
223 ms_free(op->referred_by);
226 sal_auth_info_delete(op->auth_info);
231 static void _osip_trace_func(char *fi, int li, osip_trace_level_t level, char *chfr, va_list ap){
232 int ortp_level=ORTP_DEBUG;
238 ortp_level=ORTP_MESSAGE;
241 ortp_level=ORTP_WARNING;
245 ortp_level=ORTP_ERROR;
248 ortp_level=ORTP_FATAL;
250 case END_TRACE_LEVEL:
253 if (ortp_log_level_enabled(level)){
254 int len=strlen(chfr);
255 char *chfrdup=ortp_strdup(chfr);
256 /*need to remove endline*/
258 if (chfrdup[len-1]=='\n')
260 if (chfrdup[len-2]=='\r')
263 ortp_logv(ortp_level,chfrdup,ap);
270 static bool_t firsttime=TRUE;
273 osip_trace_initialize_func (OSIP_INFO4,&_osip_trace_func);
278 sal->keepalive_period=30;
279 sal->double_reg=TRUE;
280 sal->use_rports=TRUE;
282 sal->reuse_authorization=FALSE;
284 sal->verify_server_certs=TRUE;
285 sal->expire_old_contact=FALSE;
290 void sal_uninit(Sal* sal){
293 ms_free(sal->rootCa);
297 void sal_set_user_pointer(Sal *sal, void *user_data){
301 void *sal_get_user_pointer(const Sal *sal){
305 static void unimplemented_stub(){
306 ms_warning("Unimplemented SAL callback");
309 void sal_set_callbacks(Sal *ctx, const SalCallbacks *cbs){
310 memcpy(&ctx->callbacks,cbs,sizeof(*cbs));
311 if (ctx->callbacks.call_received==NULL)
312 ctx->callbacks.call_received=(SalOnCallReceived)unimplemented_stub;
313 if (ctx->callbacks.call_ringing==NULL)
314 ctx->callbacks.call_ringing=(SalOnCallRinging)unimplemented_stub;
315 if (ctx->callbacks.call_accepted==NULL)
316 ctx->callbacks.call_accepted=(SalOnCallAccepted)unimplemented_stub;
317 if (ctx->callbacks.call_failure==NULL)
318 ctx->callbacks.call_failure=(SalOnCallFailure)unimplemented_stub;
319 if (ctx->callbacks.call_terminated==NULL)
320 ctx->callbacks.call_terminated=(SalOnCallTerminated)unimplemented_stub;
321 if (ctx->callbacks.call_released==NULL)
322 ctx->callbacks.call_released=(SalOnCallReleased)unimplemented_stub;
323 if (ctx->callbacks.call_updating==NULL)
324 ctx->callbacks.call_updating=(SalOnCallUpdating)unimplemented_stub;
325 if (ctx->callbacks.auth_requested==NULL)
326 ctx->callbacks.auth_requested=(SalOnAuthRequested)unimplemented_stub;
327 if (ctx->callbacks.auth_success==NULL)
328 ctx->callbacks.auth_success=(SalOnAuthSuccess)unimplemented_stub;
329 if (ctx->callbacks.register_success==NULL)
330 ctx->callbacks.register_success=(SalOnRegisterSuccess)unimplemented_stub;
331 if (ctx->callbacks.register_failure==NULL)
332 ctx->callbacks.register_failure=(SalOnRegisterFailure)unimplemented_stub;
333 if (ctx->callbacks.dtmf_received==NULL)
334 ctx->callbacks.dtmf_received=(SalOnDtmfReceived)unimplemented_stub;
335 if (ctx->callbacks.notify==NULL)
336 ctx->callbacks.notify=(SalOnNotify)unimplemented_stub;
337 if (ctx->callbacks.notify_presence==NULL)
338 ctx->callbacks.notify_presence=(SalOnNotifyPresence)unimplemented_stub;
339 if (ctx->callbacks.subscribe_received==NULL)
340 ctx->callbacks.subscribe_received=(SalOnSubscribeReceived)unimplemented_stub;
341 if (ctx->callbacks.text_received==NULL)
342 ctx->callbacks.text_received=(SalOnTextReceived)unimplemented_stub;
343 if (ctx->callbacks.ping_reply==NULL)
344 ctx->callbacks.ping_reply=(SalOnPingReply)unimplemented_stub;
345 if (ctx->callbacks.message_external_body==NULL)
346 ctx->callbacks.message_external_body=(SalOnMessageExternalBodyReceived)unimplemented_stub;
349 int sal_unlisten_ports(Sal *ctx){
358 int sal_reset_transports(Sal *ctx){
359 #ifdef HAVE_EXOSIP_RESET_TRANSPORTS
361 ms_message("Exosip transports reset.");
362 eXosip_reset_transports();
366 ms_warning("sal_reset_transports() not implemented in this version.");
372 static void set_tls_options(Sal *ctx){
374 eXosip_tls_ctx_t tlsCtx;
375 memset(&tlsCtx, 0, sizeof(tlsCtx));
376 snprintf(tlsCtx.root_ca_cert, sizeof(tlsCtx.client.cert), "%s", ctx->rootCa);
377 eXosip_set_tls_ctx(&tlsCtx);
379 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
380 eXosip_tls_verify_certificate(ctx->verify_server_certs);
384 void sal_set_dscp(Sal *ctx, int dscp){
387 eXosip_set_option(EXOSIP_OPT_SET_DSCP,&ctx->dscp);
390 int sal_listen_port(Sal *ctx, const char *addr, int port, SalTransport tr, int is_secure){
393 int proto=IPPROTO_UDP;
394 int keepalive = ctx->keepalive_period;
397 case SalTransportUDP:
399 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &keepalive);
401 case SalTransportTCP:
402 case SalTransportTLS:
405 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE,&keepalive);
406 set_tls_options(ctx);
409 ms_warning("unexpected proto, using datagram");
411 /*see if it looks like an IPv6 address*/
412 int use_rports = ctx->use_rports; // Copy char to int to avoid bad alignment
413 eXosip_set_option(EXOSIP_OPT_USE_RPORT,&use_rports);
414 int dont_use_101 = !ctx->use_101; // Copy char to int to avoid bad alignment
415 eXosip_set_option(EXOSIP_OPT_DONT_SEND_101,&dont_use_101);
416 sal_set_dscp(ctx,ctx->dscp);
418 ipv6=strchr(addr,':')!=NULL;
419 eXosip_enable_ipv6(ipv6);
421 if (is_secure && tr == SalTransportUDP){
422 ms_fatal("SIP over DTLS is not supported yet.");
425 err=eXosip_listen_addr(proto, addr, port, ipv6 ? PF_INET6 : PF_INET, is_secure);
430 ortp_socket_t sal_get_socket(Sal *ctx){
431 #ifdef HAVE_EXOSIP_GET_SOCKET
432 return eXosip_get_socket(IPPROTO_UDP);
434 ms_warning("Sorry, eXosip does not have eXosip_get_socket() method");
439 void sal_set_user_agent(Sal *ctx, const char *user_agent){
440 eXosip_set_user_agent(user_agent);
443 void sal_use_session_timers(Sal *ctx, int expires){
444 ctx->session_expires=expires;
447 void sal_use_one_matching_codec_policy(Sal *ctx, bool_t one_matching_codec){
448 ctx->one_matching_codec=one_matching_codec;
451 MSList *sal_get_pending_auths(Sal *sal){
452 return ms_list_copy(sal->pending_auths);
455 void sal_use_double_registrations(Sal *ctx, bool_t enabled){
456 ctx->double_reg=enabled;
459 void sal_expire_old_registration_contacts(Sal *ctx, bool_t enabled){
460 ctx->expire_old_contact=enabled;
463 void sal_use_rport(Sal *ctx, bool_t use_rports){
464 ctx->use_rports=use_rports;
466 void sal_use_101(Sal *ctx, bool_t use_101){
467 ctx->use_101=use_101;
470 void sal_set_root_ca(Sal* ctx, const char* rootCa) {
472 ms_free(ctx->rootCa);
473 ctx->rootCa = ms_strdup(rootCa);
474 set_tls_options(ctx);
477 void sal_verify_server_certificates(Sal *ctx, bool_t verify){
478 ctx->verify_server_certs=verify;
479 #ifdef HAVE_EXOSIP_TLS_VERIFY_CERTIFICATE
480 eXosip_tls_verify_certificate(verify);
484 static int extract_received_rport(osip_message_t *msg, const char **received, int *rportval,SalTransport* transport){
485 osip_via_t *via=NULL;
486 osip_generic_param_t *param=NULL;
487 const char *rport=NULL;
491 osip_message_get_via(msg,0,&via);
493 ms_warning("extract_received_rport(): no via.");
497 *transport = sal_transport_parse(via->protocol);
499 if (via->port && via->port[0]!='\0')
500 *rportval=atoi(via->port);
502 osip_via_param_get_byname(via,"rport",¶m);
505 if (rport && rport[0]!='\0') *rportval=atoi(rport);
509 osip_via_param_get_byname(via,"received",¶m);
510 if (param) *received=param->gvalue;
512 if (rport==NULL && *received==NULL){
513 ms_warning("extract_received_rport(): no rport and no received parameters.");
519 static void set_sdp(osip_message_t *sip,sdp_message_t *msg){
523 sdp_message_to_str(msg,&sdp);
525 snprintf(clen,sizeof(clen),"%i",sdplen);
526 osip_message_set_body(sip,sdp,sdplen);
527 osip_message_set_content_type(sip,"application/sdp");
528 osip_message_set_content_length(sip,clen);
532 static void set_sdp_from_desc(osip_message_t *sip, const SalMediaDescription *desc){
533 sdp_message_t *msg=media_description_to_sdp(desc);
535 ms_error("Fail to print sdp message !");
539 sdp_message_free(msg);
542 static void sdp_process(SalOp *h){
543 ms_message("Doing SDP offer/answer process of type %s",h->sdp_offering ? "outgoing" : "incoming");
545 sal_media_description_unref(h->result);
547 h->result=sal_media_description_new();
548 if (h->sdp_offering){
549 offer_answer_initiate_outgoing(h->base.local_media,h->base.remote_media,h->result);
553 sdp_message_free(h->sdp_answer);
555 offer_answer_initiate_incoming(h->base.local_media,h->base.remote_media,h->result,h->base.root->one_matching_codec);
556 h->sdp_answer=media_description_to_sdp(h->result);
557 /*once we have generated the SDP answer, we modify the result description for processing by the upper layer.
558 It should contains media parameters constraint from the remote offer, not our response*/
559 strcpy(h->result->addr,h->base.remote_media->addr);
560 h->result->bandwidth=h->base.remote_media->bandwidth;
562 for(i=0;i<h->result->nstreams;++i){
563 if (h->result->streams[i].rtp_port>0){
564 strcpy(h->result->streams[i].rtp_addr,h->base.remote_media->streams[i].rtp_addr);
565 strcpy(h->result->streams[i].rtcp_addr,h->base.remote_media->streams[i].rtcp_addr);
566 h->result->streams[i].ptime=h->base.remote_media->streams[i].ptime;
567 h->result->streams[i].bandwidth=h->base.remote_media->streams[i].bandwidth;
568 h->result->streams[i].rtp_port=h->base.remote_media->streams[i].rtp_port;
569 h->result->streams[i].rtcp_port=h->base.remote_media->streams[i].rtcp_port;
571 if (h->result->streams[i].proto == SalProtoRtpSavp) {
572 h->result->streams[i].crypto[0] = h->base.remote_media->streams[i].crypto[0];
580 int sal_call_is_offerer(const SalOp *h){
581 return h->sdp_offering;
584 int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc){
586 sal_media_description_ref(desc);
587 if (h->base.local_media)
588 sal_media_description_unref(h->base.local_media);
589 h->base.local_media=desc;
590 if (h->base.remote_media){
591 /*case of an incoming call where we modify the local capabilities between the time
592 * the call is ringing and it is accepted (for example if you want to accept without video*/
593 /*reset the sdp answer so that it is computed again*/
595 sdp_message_free(h->sdp_answer);
602 int sal_call(SalOp *h, const char *from, const char *to){
605 osip_message_t *invite=NULL;
606 sal_op_set_from(h,from);
608 sal_exosip_fix_route(h);
610 h->terminated = FALSE;
612 route = sal_op_get_route(h);
613 err=eXosip_call_build_initial_invite(&invite,to,from,route,"Phone call");
615 ms_error("Could not create call. Error %d (from=%s to=%s route=%s)",
616 err, from, to, route);
619 osip_message_set_allow(invite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
620 if (h->base.contact){
621 _osip_list_set_empty(&invite->contacts,(void (*)(void*))osip_contact_free);
622 osip_message_set_contact(invite,h->base.contact);
624 if (h->base.root->session_expires!=0){
625 osip_message_set_header(invite, "Session-expires", "200");
626 osip_message_set_supported(invite, "timer");
628 if (h->base.local_media){
629 h->sdp_offering=TRUE;
630 set_sdp_from_desc(invite,h->base.local_media);
631 }else h->sdp_offering=FALSE;
633 osip_message_set_header(invite,"Replaces",h->replaces);
635 osip_message_set_header(invite,"Referred-By",h->referred_by);
639 err=eXosip_call_send_initial_invite(invite);
643 ms_error("Fail to send invite ! Error code %d", err);
646 sal_add_call(h->base.root,h);
651 int sal_call_notify_ringing(SalOp *h, bool_t early_media){
654 /*if early media send also 180 and 183 */
658 eXosip_call_build_answer(h->tid,183,&msg);
662 set_sdp(msg,h->sdp_answer);
663 sdp_message_free(h->sdp_answer);
666 eXosip_call_send_answer(h->tid,183,msg);
671 eXosip_call_send_answer(h->tid,180,NULL);
677 int sal_call_accept(SalOp * h){
679 const char *contact=sal_op_get_contact(h);
681 int err=eXosip_call_build_answer(h->tid,200,&msg);
682 if (err<0 || msg==NULL){
683 ms_error("Fail to build answer for call: err=%i",err);
686 if (h->base.root->session_expires!=0){
687 if (h->supports_session_timers) osip_message_set_supported(msg, "timer");
691 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
692 osip_message_set_contact(msg,contact);
695 if (h->base.local_media){
696 /*this is the case where we received an invite without SDP*/
697 if (h->sdp_offering) {
698 set_sdp_from_desc(msg,h->base.local_media);
700 if (h->sdp_answer==NULL) sdp_process(h);
702 set_sdp(msg,h->sdp_answer);
703 sdp_message_free(h->sdp_answer);
708 ms_error("You are accepting a call but not defined any media capabilities !");
710 eXosip_call_send_answer(h->tid,200,msg);
714 int sal_call_decline(SalOp *h, SalReason reason, const char *redirect){
715 if (reason==SalReasonBusy){
717 eXosip_call_send_answer(h->tid,486,NULL);
720 else if (reason==SalReasonTemporarilyUnavailable){
722 eXosip_call_send_answer(h->tid,480,NULL);
724 }else if (reason==SalReasonDoNotDisturb){
726 eXosip_call_send_answer(h->tid,600,NULL);
728 }else if (reason==SalReasonMedia){
730 eXosip_call_send_answer(h->tid,415,NULL);
732 }else if (redirect!=NULL && reason==SalReasonRedirect){
735 if (strstr(redirect,"sip:")!=0) code=302;
738 eXosip_call_build_answer(h->tid,code,&msg);
739 osip_message_set_contact(msg,redirect);
740 eXosip_call_send_answer(h->tid,code,msg);
742 }else sal_call_terminate(h);
746 SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
747 return h->base.remote_media;
750 SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
751 if (h->base.local_media && h->base.remote_media && !h->result){
757 int sal_call_set_referer(SalOp *h, SalOp *refered_call){
758 if (refered_call->replaces)
759 h->replaces=ms_strdup(refered_call->replaces);
760 if (refered_call->referred_by)
761 h->referred_by=ms_strdup(refered_call->referred_by);
765 static int send_notify_for_refer(int did, const char *sipfrag){
768 eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg);
771 ms_warning("Could not build NOTIFY for refer.");
774 osip_message_set_content_type(msg,"message/sipfrag");
775 osip_message_set_header(msg,"Event","refer");
776 osip_message_set_body(msg,sipfrag,strlen(sipfrag));
777 eXosip_call_send_request(did,msg);
782 /* currently only support to notify trying and 200Ok*/
783 int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){
786 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
788 else if (newcall->cid!=-1){
789 if (newcall->did==-1){
790 /* not yet established*/
791 if (!newcall->terminated){
793 send_notify_for_refer(h->did,"SIP/2.0 100 Trying\r\n");
796 if (!newcall->terminated){
797 if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){
798 /* we need previous notify transaction to complete, so buffer the request for later*/
799 h->sipfrag_pending="SIP/2.0 200 Ok\r\n";
807 int sal_ping(SalOp *op, const char *from, const char *to){
808 osip_message_t *options=NULL;
810 sal_op_set_from(op,from);
811 sal_op_set_to(op,to);
812 sal_exosip_fix_route(op);
814 eXosip_options_build_request (&options, sal_op_get_to(op),
815 sal_op_get_from(op),sal_op_get_route(op));
817 if (op->base.root->session_expires!=0){
818 osip_message_set_header(options, "Session-expires", "200");
819 osip_message_set_supported(options, "timer");
821 sal_add_other(sal_op_get_sal(op),op,options);
822 return eXosip_options_send_request(options);
827 int sal_call_refer(SalOp *h, const char *refer_to){
828 osip_message_t *msg=NULL;
831 eXosip_call_build_refer(h->did,refer_to, &msg);
832 if (msg) err=eXosip_call_send_request(h->did, msg);
838 int sal_call_refer_with_replaces(SalOp *h, SalOp *other_call_h){
839 osip_message_t *msg=NULL;
840 char referto[256]={0};
843 if (eXosip_call_get_referto(other_call_h->did,referto,sizeof(referto)-1)!=0){
844 ms_error("eXosip_call_get_referto() failed for did=%i",other_call_h->did);
848 eXosip_call_build_refer(h->did,referto, &msg);
849 osip_message_set_header(msg,"Referred-By",h->base.from);
850 if (msg) err=eXosip_call_send_request(h->did, msg);
856 SalOp *sal_call_get_replaces(SalOp *h){
857 if (h!=NULL && h->replaces!=NULL){
860 cid=eXosip_call_find_by_replaces(h->replaces);
863 SalOp *ret=sal_find_call(h->base.root,cid);
870 int sal_call_send_dtmf(SalOp *h, char dtmf){
871 osip_message_t *msg=NULL;
876 eXosip_call_build_info(h->did,&msg);
878 snprintf(dtmf_body, sizeof(dtmf_body), "Signal=%c\r\nDuration=250\r\n", dtmf);
879 osip_message_set_body(msg,dtmf_body,strlen(dtmf_body));
880 osip_message_set_content_type(msg,"application/dtmf-relay");
881 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(dtmf_body));
882 osip_message_set_content_length(msg,clen);
883 eXosip_call_send_request(h->did,msg);
889 static void push_auth_to_exosip(const SalAuthInfo *info){
891 if (info->userid==NULL || info->userid[0]=='\0') userid=info->username;
892 else userid=info->userid;
893 ms_message("Authentication info for username [%s], id[%s], realm [%s] added to eXosip", info->username,userid, info->realm);
894 eXosip_add_authentication_info (info->username,userid,
895 info->password, NULL,info->realm);
898 * Just for symmetry ;-)
900 static void pop_auth_from_exosip() {
901 eXosip_clear_authentication_info();
904 int sal_call_terminate(SalOp *h){
906 if (h == NULL) return -1;
907 if (h->auth_info) push_auth_to_exosip(h->auth_info);
909 err=eXosip_call_terminate(h->cid,h->did);
911 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
913 ms_warning("Exosip could not terminate the call: cid=%i did=%i", h->cid,h->did);
919 void sal_op_authenticate(SalOp *h, const SalAuthInfo *info){
920 if (h->terminated) return;
921 if (h->pending_auth){
922 push_auth_to_exosip(info);
924 /*FIXME exosip does not take into account this update register message*/
926 if (fix_message_contact(h, h->pending_auth->request,h->pending_auth->response)) {
930 update_contact_from_response(h,h->pending_auth->response);
932 eXosip_default_action(h->pending_auth);
934 ms_message("eXosip_default_action() done");
935 if (!h->base.root->reuse_authorization) pop_auth_from_exosip();
937 if (h->auth_info) sal_auth_info_delete(h->auth_info); /*if already exist*/
938 h->auth_info=sal_auth_info_clone(info); /*store auth info for subsequent request*/
941 void sal_op_cancel_authentication(SalOp *h) {
943 sal_op_get_sal(h)->callbacks.register_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure");
944 } else if (h->cid >0) {
945 sal_op_get_sal(h)->callbacks.call_failure(h,SalErrorFailure, SalReasonForbidden,"Authentication failure",0);
947 ms_warning("Auth failure not handled");
951 static void set_network_origin(SalOp *op, osip_message_t *req){
952 const char *received=NULL;
955 SalTransport transport;
956 if (extract_received_rport(req,&received,&rport,&transport)!=0){
957 osip_via_t *via=NULL;
959 osip_message_get_via(req,0,&via);
960 received=osip_via_get_host(via);
961 tmp=osip_via_get_port(via);
962 if (tmp) rport=atoi(tmp);
964 if (transport != SalTransportUDP) {
965 snprintf(origin,sizeof(origin)-1,"sip:%s:%i",received,rport);
967 snprintf(origin,sizeof(origin)-1,"sip:%s:%i;transport=%s",received,rport,sal_transport_to_string(transport));
969 __sal_op_set_network_origin(op,origin);
972 static void set_remote_ua(SalOp* op, osip_message_t *req){
973 if (op->base.remote_ua==NULL){
974 osip_header_t *h=NULL;
975 osip_message_get_user_agent(req,0,&h);
977 op->base.remote_ua=ms_strdup(h->hvalue);
982 static void set_replaces(SalOp *op, osip_message_t *req){
983 osip_header_t *h=NULL;
986 ms_free(op->replaces);
989 osip_message_header_get_byname(req,"replaces",0,&h);
991 if (h->hvalue && h->hvalue[0]!='\0'){
992 op->replaces=ms_strdup(h->hvalue);
997 static SalOp *find_op(Sal *sal, eXosip_event_t *ev){
999 return sal_find_call(sal,ev->cid);
1002 return sal_find_register(sal,ev->rid);
1005 return sal_find_out_subscribe(sal,ev->sid);
1008 return sal_find_in_subscribe(sal,ev->nid);
1010 if (ev->response) return sal_find_other(sal,ev->response);
1011 else if (ev->request) return sal_find_other(sal,ev->request);
1015 static void inc_new_call(Sal *sal, eXosip_event_t *ev){
1016 SalOp *op=sal_op_new(sal);
1017 osip_from_t *from,*to;
1018 osip_call_info_t *call_info;
1020 sdp_message_t *sdp=eXosip_get_sdp_info(ev->request);
1022 set_network_origin(op,ev->request);
1023 set_remote_ua(op,ev->request);
1024 set_replaces(op,ev->request);
1027 op->sdp_offering=FALSE;
1028 op->base.remote_media=sal_media_description_new();
1029 sdp_to_media_description(sdp,op->base.remote_media);
1030 sdp_message_free(sdp);
1031 }else op->sdp_offering=TRUE;
1033 from=osip_message_get_from(ev->request);
1034 to=osip_message_get_to(ev->request);
1035 osip_from_to_str(from,&tmp);
1036 sal_op_set_from(op,tmp);
1038 osip_from_to_str(to,&tmp);
1039 sal_op_set_to(op,tmp);
1042 osip_message_get_call_info(ev->request,0,&call_info);
1045 osip_call_info_to_str(call_info,&tmp);
1046 if( strstr(tmp,"answer-after=") != NULL)
1048 op->auto_answer_asked=TRUE;
1049 ms_message("The caller asked to automatically answer the call(Emergency?)\n");
1058 sal_add_call(op->base.root,op);
1059 sal->callbacks.call_received(op);
1062 static void handle_reinvite(Sal *sal, eXosip_event_t *ev){
1063 SalOp *op=find_op(sal,ev);
1067 ms_warning("Reinvite for non-existing operation !");
1072 sdp=eXosip_get_sdp_info(ev->request);
1073 if (op->base.remote_media){
1074 sal_media_description_unref(op->base.remote_media);
1075 op->base.remote_media=NULL;
1078 sal_media_description_unref(op->result);
1082 op->sdp_offering=FALSE;
1083 op->base.remote_media=sal_media_description_new();
1084 sdp_to_media_description(sdp,op->base.remote_media);
1085 sdp_message_free(sdp);
1088 op->sdp_offering=TRUE;
1090 sal->callbacks.call_updating(op);
1093 static void handle_ack(Sal *sal, eXosip_event_t *ev){
1094 SalOp *op=find_op(sal,ev);
1098 ms_warning("ack for non-existing call !");
1101 if (op->terminated) {
1102 ms_warning("ack for terminated call, ignoring");
1106 if (op->sdp_offering){
1107 sdp=eXosip_get_sdp_info(ev->ack);
1109 if (op->base.remote_media)
1110 sal_media_description_unref(op->base.remote_media);
1111 op->base.remote_media=sal_media_description_new();
1112 sdp_to_media_description(sdp,op->base.remote_media);
1114 sdp_message_free(sdp);
1120 sal->callbacks.call_ack(op);
1123 static void update_contact_from_response(SalOp *op, osip_message_t *response){
1124 const char *received;
1126 SalTransport transport;
1127 if (extract_received_rport(response,&received,&rport,&transport)==0){
1128 const char *contact=sal_op_get_contact(op);
1130 /*no contact given yet, use from instead*/
1131 contact=sal_op_get_from(op);
1134 SalAddress *addr=sal_address_new(contact);
1136 sal_address_set_domain(addr,received);
1137 sal_address_set_port_int(addr,rport);
1138 if (transport!=SalTransportUDP)
1139 sal_address_set_transport(addr,transport);
1140 tmp=sal_address_as_string(addr);
1141 ms_message("Contact address updated to %s",tmp);
1142 sal_op_set_contact(op,tmp);
1143 sal_address_destroy(addr);
1149 static int call_proceeding(Sal *sal, eXosip_event_t *ev){
1150 SalOp *op=find_op(sal,ev);
1152 if (op==NULL || op->terminated==TRUE) {
1153 ms_warning("This call has been canceled.");
1155 eXosip_call_terminate(ev->cid,ev->did);
1163 /* update contact if received and rport are set by the server
1164 note: will only be used by remote for next INVITE, if any...*/
1165 update_contact_from_response(op,ev->response);
1169 static void call_ringing(Sal *sal, eXosip_event_t *ev){
1171 SalOp *op=find_op(sal,ev);
1172 if (call_proceeding(sal, ev)==-1) return;
1174 set_remote_ua(op,ev->response);
1175 sdp=eXosip_get_sdp_info(ev->response);
1177 op->base.remote_media=sal_media_description_new();
1178 sdp_to_media_description(sdp,op->base.remote_media);
1179 sdp_message_free(sdp);
1180 if (op->base.local_media) sdp_process(op);
1182 sal->callbacks.call_ringing(op);
1185 static void call_accepted(Sal *sal, eXosip_event_t *ev){
1187 osip_message_t *msg=NULL;
1188 SalOp *op=find_op(sal,ev);
1189 const char *contact;
1191 if (op==NULL || op->terminated==TRUE) {
1192 ms_warning("This call has been already terminated.");
1194 eXosip_call_terminate(ev->cid,ev->did);
1200 set_remote_ua(op,ev->response);
1202 sdp=eXosip_get_sdp_info(ev->response);
1204 op->base.remote_media=sal_media_description_new();
1205 sdp_to_media_description(sdp,op->base.remote_media);
1206 sdp_message_free(sdp);
1207 if (op->base.local_media) sdp_process(op);
1209 eXosip_call_build_ack(ev->did,&msg);
1211 ms_warning("This call has been already terminated.");
1213 eXosip_call_terminate(ev->cid,ev->did);
1217 contact=sal_op_get_contact(op);
1219 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
1220 osip_message_set_contact(msg,contact);
1222 if (op->sdp_answer){
1223 set_sdp(msg,op->sdp_answer);
1224 sdp_message_free(op->sdp_answer);
1225 op->sdp_answer=NULL;
1227 eXosip_call_send_ack(ev->did,msg);
1228 sal->callbacks.call_accepted(op);
1231 static void call_terminated(Sal *sal, eXosip_event_t *ev){
1233 SalOp *op=find_op(sal,ev);
1235 ms_warning("Call terminated for already closed call ?");
1239 osip_from_to_str(ev->request->from,&from);
1241 sal->callbacks.call_terminated(op,from!=NULL ? from : sal_op_get_from(op));
1242 if (from) osip_free(from);
1243 op->terminated=TRUE;
1246 static void call_released(Sal *sal, eXosip_event_t *ev){
1247 SalOp *op=find_op(sal,ev);
1249 ms_warning("No op associated to this call_released()");
1252 if (!op->terminated){
1253 /* no response received so far */
1254 call_failure(sal,ev);
1256 sal->callbacks.call_released(op);
1259 static int get_auth_data_from_response(osip_message_t *resp, const char **realm, const char **username){
1260 const char *prx_realm=NULL,*www_realm=NULL;
1261 osip_proxy_authenticate_t *prx_auth;
1262 osip_www_authenticate_t *www_auth;
1264 *username=osip_uri_get_username(resp->from->url);
1265 prx_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->proxy_authenticates,0);
1266 www_auth=(osip_proxy_authenticate_t*)osip_list_get(&resp->www_authenticates,0);
1268 prx_realm=osip_proxy_authenticate_get_realm(prx_auth);
1270 www_realm=osip_www_authenticate_get_realm(www_auth);
1274 }else if (www_realm){
1282 static int get_auth_data_from_request(osip_message_t *msg, const char **realm, const char **username){
1283 osip_authorization_t *auth=NULL;
1284 osip_proxy_authorization_t *prx_auth=NULL;
1286 *username=osip_uri_get_username(msg->from->url);
1287 osip_message_get_authorization(msg, 0, &auth);
1289 *realm=osip_authorization_get_realm(auth);
1292 osip_message_get_proxy_authorization(msg,0,&prx_auth);
1294 *realm=osip_proxy_authorization_get_realm(prx_auth);
1300 static int get_auth_data(eXosip_event_t *ev, const char **realm, const char **username){
1301 if (ev->response && get_auth_data_from_response(ev->response,realm,username)==0) return 0;
1302 if (ev->request && get_auth_data_from_request(ev->request,realm,username)==0) return 0;
1306 int sal_op_get_auth_requested(SalOp *op, const char **realm, const char **username){
1307 if (op->pending_auth){
1308 return get_auth_data(op->pending_auth,realm,username);
1313 static bool_t process_authentication(Sal *sal, eXosip_event_t *ev){
1315 const char *username,*realm;
1318 ms_warning("No operation associated with this authentication !");
1321 if (get_auth_data(ev,&realm,&username)==0){
1322 if (op->pending_auth!=NULL){
1323 eXosip_event_free(op->pending_auth);
1324 op->pending_auth=ev;
1326 op->pending_auth=ev;
1327 sal_add_pending_auth(sal,op);
1330 sal->callbacks.auth_requested(op,realm,username);
1336 static void authentication_ok(Sal *sal, eXosip_event_t *ev){
1338 const char *username,*realm;
1341 ms_warning("No operation associated with this authentication_ok!");
1344 if (op->pending_auth){
1345 eXosip_event_free(op->pending_auth);
1346 sal_remove_pending_auth(sal,op);
1347 op->pending_auth=NULL;
1349 if (get_auth_data(ev,&realm,&username)==0){
1350 sal->callbacks.auth_success(op,realm,username);
1354 static bool_t call_failure(Sal *sal, eXosip_event_t *ev){
1357 char* computedReason=NULL;
1358 const char *reason=NULL;
1359 SalError error=SalErrorUnknown;
1360 SalReason sr=SalReasonUnknown;
1363 op=(SalOp*)find_op(sal,ev);
1366 ms_warning("Call failure reported for a closed call, ignored.");
1371 code=osip_message_get_status_code(ev->response);
1372 reason=osip_message_get_reason_phrase(ev->response);
1373 osip_header_t *h=NULL;
1374 if (!osip_message_header_get_byname( ev->response
1378 computedReason = ms_strdup_printf("%s %s",reason,osip_header_get_value(h));
1379 reason = computedReason;
1387 return process_authentication(sal,ev);
1390 error=SalErrorUnknown;
1393 error=SalErrorFailure;
1394 sr=SalReasonNotFound;
1397 error=SalErrorFailure;
1401 eXosip_default_action(ev);
1405 error=SalErrorFailure;
1406 sr=SalReasonTemporarilyUnavailable;
1408 error=SalErrorFailure;
1414 error=SalErrorFailure;
1415 sr=SalReasonDoNotDisturb;
1418 error=SalErrorFailure;
1419 sr=SalReasonDeclined;
1423 error=SalErrorFailure;
1424 sr=SalReasonUnknown;
1425 }else error=SalErrorNoResponse;
1427 op->terminated=TRUE;
1428 sal->callbacks.call_failure(op,error,sr,reason,code);
1429 if (computedReason != NULL){
1430 ms_free(computedReason);
1435 /* Request remote side to send us VFU */
1436 void sal_call_send_vfu_request(SalOp *h){
1437 osip_message_t *msg=NULL;
1439 "<?xml version=\"1.0\" encoding=\"utf-8\" ?>"
1443 " <picture_fast_update></picture_fast_update>"
1451 eXosip_call_build_info(h->did,&msg);
1453 osip_message_set_body(msg,info_body,strlen(info_body));
1454 osip_message_set_content_type(msg,"application/media_control+xml");
1455 snprintf(clen,sizeof(clen),"%lu",(unsigned long)strlen(info_body));
1456 osip_message_set_content_length(msg,clen);
1457 eXosip_call_send_request(h->did,msg);
1458 ms_message("Sending VFU request !");
1463 static void process_media_control_xml(Sal *sal, eXosip_event_t *ev){
1464 SalOp *op=find_op(sal,ev);
1465 osip_body_t *body=NULL;
1468 ms_warning("media control xml received without operation context!");
1472 osip_message_get_body(ev->request,0,&body);
1473 if (body && body->body!=NULL &&
1474 strstr(body->body,"picture_fast_update")){
1475 osip_message_t *ans=NULL;
1476 ms_message("Receiving VFU request !");
1477 if (sal->callbacks.vfu_request){
1478 sal->callbacks.vfu_request(op);
1479 eXosip_call_build_answer(ev->tid,200,&ans);
1481 eXosip_call_send_answer(ev->tid,200,ans);
1485 /*in all other cases we must say it is not implemented.*/
1487 osip_message_t *ans=NULL;
1489 eXosip_call_build_answer(ev->tid,501,&ans);
1491 eXosip_call_send_answer(ev->tid,501,ans);
1496 static void process_dtmf_relay(Sal *sal, eXosip_event_t *ev){
1497 SalOp *op=find_op(sal,ev);
1498 osip_body_t *body=NULL;
1501 ms_warning("media dtmf relay received without operation context!");
1505 osip_message_get_body(ev->request,0,&body);
1506 if (body && body->body!=NULL){
1507 osip_message_t *ans=NULL;
1508 const char *name=strstr(body->body,"Signal");
1509 if (name==NULL) name=strstr(body->body,"signal");
1511 ms_warning("Could not extract the dtmf name from the SIP INFO.");
1514 name+=strlen("signal");
1515 if (sscanf(name," = %1s",tmp)==1){
1516 ms_message("Receiving dtmf %s via SIP INFO.",tmp);
1517 if (sal->callbacks.dtmf_received != NULL)
1518 sal->callbacks.dtmf_received(op, tmp[0]);
1522 eXosip_call_build_answer(ev->tid,200,&ans);
1524 eXosip_call_send_answer(ev->tid,200,ans);
1529 static void fill_options_answer(osip_message_t *options){
1530 osip_message_set_allow(options,"INVITE, ACK, BYE, CANCEL, OPTIONS, MESSAGE, SUBSCRIBE, NOTIFY, INFO");
1531 osip_message_set_accept(options,"application/sdp");
1534 static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){
1535 osip_header_t *h=NULL;
1536 osip_message_t *ans=NULL;
1537 ms_message("Receiving REFER request !");
1538 osip_message_header_get_byname(ev->request,"Refer-To",0,&h);
1541 osip_from_t *from=NULL;
1543 osip_from_init(&from);
1545 if (osip_from_parse(from,h->hvalue)==0){
1547 osip_uri_header_t *uh=NULL;
1548 osip_header_t *referred_by=NULL;
1549 osip_uri_header_get_byname(&from->url->url_headers,(char*)"Replaces",&uh);
1550 if (uh!=NULL && uh->gvalue && uh->gvalue[0]!='\0'){
1551 ms_message("Found replaces in Refer-To");
1553 ms_free(op->replaces);
1555 op->replaces=ms_strdup(uh->gvalue);
1557 osip_message_header_get_byname(ev->request,"Referred-By",0,&referred_by);
1558 if (referred_by && referred_by->hvalue && referred_by->hvalue[0]!='\0'){
1559 if (op->referred_by)
1560 ms_free(op->referred_by);
1561 op->referred_by=ms_strdup(referred_by->hvalue);
1564 osip_uri_header_freelist(&from->url->url_headers);
1565 osip_from_to_str(from,&tmp);
1566 sal->callbacks.refer_received(sal,op,tmp);
1568 osip_from_free(from);
1571 eXosip_call_build_answer(ev->tid,202,&ans);
1573 eXosip_call_send_answer(ev->tid,202,ans);
1578 ms_warning("cannot do anything with the refer without destination\n");
1582 static void process_notify(Sal *sal, eXosip_event_t *ev){
1583 osip_header_t *h=NULL;
1585 SalOp *op=find_op(sal,ev);
1586 osip_message_t *ans=NULL;
1588 ms_message("Receiving NOTIFY request !");
1589 osip_from_to_str(ev->request->from,&from);
1590 osip_message_header_get_byname(ev->request,"Event",0,&h);
1592 osip_body_t *body=NULL;
1593 //osip_content_type_t *ct=NULL;
1594 osip_message_get_body(ev->request,0,&body);
1595 //ct=osip_message_get_content_type(ev->request);
1596 if (h->hvalue && strcasecmp(h->hvalue,"refer")==0){
1597 /*special handling of refer events*/
1598 if (body && body->body){
1599 osip_message_t *msg;
1600 osip_message_init(&msg);
1601 if (osip_message_parse_sipfrag(msg,body->body,strlen(body->body))==0){
1602 int code=osip_message_get_status_code(msg);
1604 sal->callbacks.notify_refer(op,SalReferTrying);
1605 }else if (code==200){
1606 sal->callbacks.notify_refer(op,SalReferSuccess);
1607 }else if (code>=400){
1608 sal->callbacks.notify_refer(op,SalReferFailed);
1611 osip_message_free(msg);
1614 /*generic handling*/
1615 sal->callbacks.notify(op,from,h->hvalue);
1618 /*answer that we received the notify*/
1620 eXosip_call_build_answer(ev->tid,200,&ans);
1622 eXosip_call_send_answer(ev->tid,200,ans);
1627 static void call_message_new(Sal *sal, eXosip_event_t *ev){
1628 osip_message_t *ans=NULL;
1630 if (MSG_IS_INFO(ev->request)){
1631 osip_content_type_t *ct;
1632 ct=osip_message_get_content_type(ev->request);
1633 if (ct && ct->subtype){
1634 if (strcmp(ct->subtype,"media_control+xml")==0)
1635 process_media_control_xml(sal,ev);
1636 else if (strcmp(ct->subtype,"dtmf-relay")==0)
1637 process_dtmf_relay(sal,ev);
1639 ms_message("Unhandled SIP INFO.");
1640 /*send an "Not implemented" answer*/
1642 eXosip_call_build_answer(ev->tid,501,&ans);
1644 eXosip_call_send_answer(ev->tid,501,ans);
1648 /*empty SIP INFO, probably to test we are alive. Send an empty answer*/
1650 eXosip_call_build_answer(ev->tid,200,&ans);
1652 eXosip_call_send_answer(ev->tid,200,ans);
1655 }else if(MSG_IS_MESSAGE(ev->request)){
1656 /* SIP messages could be received into call */
1657 text_received(sal, ev);
1659 eXosip_call_build_answer(ev->tid,200,&ans);
1661 eXosip_call_send_answer(ev->tid,200,ans);
1663 }else if(MSG_IS_REFER(ev->request)){
1664 SalOp *op=find_op(sal,ev);
1666 ms_message("Receiving REFER request !");
1667 process_refer(sal,op,ev);
1668 }else if(MSG_IS_NOTIFY(ev->request)){
1669 process_notify(sal,ev);
1670 }else if (MSG_IS_OPTIONS(ev->request)){
1672 eXosip_call_build_answer(ev->tid,200,&ans);
1674 fill_options_answer(ans);
1675 eXosip_call_send_answer(ev->tid,200,ans);
1679 }else ms_warning("call_message_new: No request ?");
1682 static void inc_update(Sal *sal, eXosip_event_t *ev){
1683 osip_message_t *msg=NULL;
1684 ms_message("Processing incoming UPDATE");
1686 eXosip_message_build_answer(ev->tid,200,&msg);
1688 eXosip_message_send_answer(ev->tid,200,msg);
1692 static bool_t comes_from_local_if(osip_message_t *msg){
1693 osip_via_t *via=NULL;
1694 osip_message_get_via(msg,0,&via);
1697 host=osip_via_get_host(via);
1698 if (strcmp(host,"127.0.0.1")==0 || strcmp(host,"::1")==0){
1699 osip_generic_param_t *param=NULL;
1700 osip_via_param_get_byname(via,"received",¶m);
1701 if (param==NULL) return TRUE;
1702 if (param->gvalue &&
1703 (strcmp(param->gvalue,"127.0.0.1")==0 || strcmp(param->gvalue,"::1")==0)){
1711 static void text_received(Sal *sal, eXosip_event_t *ev){
1712 osip_body_t *body=NULL;
1713 char *from=NULL,*msg;
1714 osip_content_type_t* content_type;
1715 osip_uri_param_t* external_body_url;
1716 char unquoted_external_body_url [256];
1717 int external_body_size=0;
1719 content_type= osip_message_get_content_type(ev->request);
1720 if (!content_type) {
1721 ms_error("Could not get message because no content type");
1724 osip_from_to_str(ev->request->from,&from);
1725 if (content_type->type
1726 && strcmp(content_type->type, "text")==0
1727 && content_type->subtype
1728 && strcmp(content_type->subtype, "plain")==0 ) {
1729 osip_message_get_body(ev->request,0,&body);
1731 ms_error("Could not get text message from SIP body");
1735 sal->callbacks.text_received(sal,from,msg);
1736 } if (content_type->type
1737 && strcmp(content_type->type, "message")==0
1738 && content_type->subtype
1739 && strcmp(content_type->subtype, "external-body")==0 ) {
1741 osip_content_type_param_get_byname(content_type, "URL", &external_body_url);
1742 /*remove both first and last character*/
1743 strncpy(unquoted_external_body_url
1744 ,&external_body_url->gvalue[1]
1745 ,external_body_size=MIN(strlen(external_body_url->gvalue)-1,sizeof(unquoted_external_body_url)));
1746 unquoted_external_body_url[external_body_size-1]='\0';
1747 sal->callbacks.message_external_body(sal,from,unquoted_external_body_url);
1750 ms_warning("Unsupported content type [%s/%s]",content_type->type,content_type->subtype);
1757 static void other_request(Sal *sal, eXosip_event_t *ev){
1758 ms_message("in other_request");
1759 if (ev->request==NULL) return;
1760 if (strcmp(ev->request->sip_method,"MESSAGE")==0){
1761 text_received(sal,ev);
1762 eXosip_message_send_answer(ev->tid,200,NULL);
1763 }else if (strcmp(ev->request->sip_method,"OPTIONS")==0){
1764 osip_message_t *options=NULL;
1765 eXosip_options_build_answer(ev->tid,200,&options);
1766 fill_options_answer(options);
1767 eXosip_options_send_answer(ev->tid,200,options);
1768 }else if (strncmp(ev->request->sip_method, "REFER", 5) == 0){
1769 ms_message("Receiving REFER request !");
1770 if (comes_from_local_if(ev->request)) {
1771 process_refer(sal,NULL,ev);
1772 }else ms_warning("Ignored REFER not coming from this local loopback interface.");
1773 }else if (strncmp(ev->request->sip_method, "UPDATE", 6) == 0){
1778 osip_message_to_str(ev->request,&tmp,&msglen);
1780 ms_message("Unsupported request received:\n%s",tmp);
1783 /*answer with a 501 Not implemented*/
1784 eXosip_message_send_answer(ev->tid,501,NULL);
1788 static void masquerade_via(osip_message_t *msg, const char *ip, const char *port){
1789 osip_via_t *via=NULL;
1790 osip_message_get_via(msg,0,&via);
1792 osip_free(via->port);
1793 via->port=osip_strdup(port);
1794 osip_free(via->host);
1795 via->host=osip_strdup(ip);
1800 static bool_t fix_message_contact(SalOp *op, osip_message_t *request,osip_message_t *last_answer, bool_t expire_last_contact) {
1801 osip_contact_t *ctt=NULL;
1802 const char *received;
1804 SalTransport transport;
1807 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1808 osip_message_get_contact(request,0,&ctt);
1810 ms_warning("fix_message_contact(): no contact to update");
1813 if (expire_last_contact){
1814 osip_contact_t *oldct=NULL,*prevct;
1815 osip_generic_param_t *param=NULL;
1816 osip_contact_clone(ctt,&oldct);
1817 while ((prevct=(osip_contact_t*)osip_list_get(&request->contacts,1))!=NULL){
1818 osip_contact_free(prevct);
1819 osip_list_remove(&request->contacts,1);
1821 osip_list_add(&request->contacts,oldct,1);
1822 osip_contact_param_get_byname(oldct,"expires",¶m);
1824 if (param->gvalue) osip_free(param->gvalue);
1825 param->gvalue=osip_strdup("0");
1827 osip_contact_param_add(oldct,osip_strdup("expires"),osip_strdup("0"));
1830 if (ctt->url->host!=NULL){
1831 osip_free(ctt->url->host);
1833 ctt->url->host=osip_strdup(received);
1834 if (ctt->url->port!=NULL){
1835 osip_free(ctt->url->port);
1837 snprintf(port,sizeof(port),"%i",rport);
1838 ctt->url->port=osip_strdup(port);
1839 if (op->masquerade_via) masquerade_via(request,received,port);
1841 if (transport != SalTransportUDP) {
1842 sal_address_set_param((SalAddress *)ctt, "transport", sal_transport_to_string(transport));
1847 static bool_t register_again_with_updated_contact(SalOp *op, osip_message_t *orig_request, osip_message_t *last_answer){
1848 osip_contact_t *ctt=NULL;
1849 SalAddress* ori_contact_address=NULL;
1850 const char *received;
1852 SalTransport transport;
1854 osip_message_t *msg=NULL;
1855 Sal* sal=op->base.root;
1857 bool_t found_valid_contact=FALSE;
1858 bool_t from_request=FALSE;
1860 if (sal->double_reg==FALSE ) return FALSE;
1862 if (extract_received_rport(last_answer,&received,&rport,&transport)==-1) return FALSE;
1865 osip_message_get_contact(last_answer,i,&ctt);
1866 if (!from_request && ctt==NULL) {
1867 osip_message_get_contact(orig_request,0,&ctt);
1871 osip_contact_to_str(ctt,&tmp);
1872 ori_contact_address = sal_address_new(tmp);
1874 /*check if contact is up to date*/
1875 if (strcmp(sal_address_get_domain(ori_contact_address),received) ==0
1876 && sal_address_get_port_int(ori_contact_address) == rport
1877 && sal_address_get_transport(ori_contact_address) == transport) {
1879 ms_message("Register response has up to date contact, doing nothing.");
1881 ms_warning("Register response does not have up to date contact, but last request had."
1882 "Stupid registrar detected, giving up.");
1884 found_valid_contact=TRUE;
1887 sal_address_destroy(ori_contact_address);
1890 }while(!found_valid_contact);
1891 if (!found_valid_contact)
1892 ms_message("Contact do not match, resending register.");
1896 eXosip_register_build_register(op->rid,op->expires,&msg);
1899 ms_warning("Fail to create a contact updated register.");
1902 if (fix_message_contact(op,msg,last_answer,op->base.root->expire_old_contact)) {
1903 eXosip_register_send_register(op->rid,msg);
1905 ms_message("Resending new register with updated contact");
1906 update_contact_from_response(op,last_answer);
1909 ms_warning("Fail to send updated register.");
1917 static void registration_success(Sal *sal, eXosip_event_t *ev){
1918 SalOp *op=sal_find_register(sal,ev->rid);
1919 osip_header_t *h=NULL;
1922 ms_error("Receiving register response for unknown operation");
1925 osip_message_get_expires(ev->request,0,&h);
1926 if (h!=NULL && atoi(h->hvalue)!=0){
1928 if (!register_again_with_updated_contact(op,ev->request,ev->response)){
1929 sal->callbacks.register_success(op,registered);
1932 sal->callbacks.register_success(op,FALSE);
1936 static bool_t registration_failure(Sal *sal, eXosip_event_t *ev){
1938 const char *reason=NULL;
1939 SalOp *op=sal_find_register(sal,ev->rid);
1940 SalReason sr=SalReasonUnknown;
1941 SalError se=SalErrorUnknown;
1944 ms_error("Receiving register failure for unknown operation");
1948 status_code=osip_message_get_status_code(ev->response);
1949 reason=osip_message_get_reason_phrase(ev->response);
1951 switch(status_code){
1954 return process_authentication(sal,ev);
1956 case 423: /*interval too brief*/
1957 {/*retry with greater interval */
1958 osip_header_t *h=NULL;
1959 osip_message_t *msg=NULL;
1960 osip_message_header_get_byname(ev->response,"min-expires",0,&h);
1961 if (h && h->hvalue && h->hvalue[0]!='\0'){
1962 int val=atoi(h->hvalue);
1963 if (val>op->expires)
1965 }else op->expires*=2;
1967 eXosip_register_build_register(op->rid,op->expires,&msg);
1968 eXosip_register_send_register(op->rid,msg);
1972 case 606: /*Not acceptable, workaround for proxies that don't like private addresses
1973 in vias, such as ekiga.net
1974 On the opposite, freephonie.net bugs when via are masqueraded.
1976 op->masquerade_via=TRUE;
1978 /* if contact is up to date, process the failure, otherwise resend a new register with
1979 updated contact first, just in case the faillure is due to incorrect contact */
1980 if (ev->response && register_again_with_updated_contact(op,ev->request,ev->response))
1981 return TRUE; /*we are retrying with an updated contact*/
1982 if (status_code==403){
1984 sr=SalReasonForbidden;
1985 }else if (status_code==0){
1986 se=SalErrorNoResponse;
1988 sal->callbacks.register_failure(op,se,sr,reason);
1993 static void other_request_reply(Sal *sal,eXosip_event_t *ev){
1994 SalOp *op=find_op(sal,ev);
1996 ms_warning("other_request_reply(): Receiving response to unknown request.");
2000 ms_message("Processing reponse status [%i] for method [%s]",ev->response->status_code,osip_message_get_method(ev->request));
2001 update_contact_from_response(op,ev->response);
2002 if (ev->request && strcmp(osip_message_get_method(ev->request),"OPTIONS")==0)
2003 sal->callbacks.ping_reply(op);
2005 if (ev->request && strcmp(osip_message_get_method(ev->request),"MESSAGE")==0) {
2006 /*out of call message acknolegment*/
2007 SalTextDeliveryStatus status=SalTextDeliveryFailed;
2009 if (ev->response->status_code<200){
2010 status=SalTextDeliveryInProgress;
2011 }else if (ev->response->status_code<300 && ev->response->status_code>=200){
2012 status=SalTextDeliveryDone;
2015 sal->callbacks.text_delivery_update(op,status);
2019 static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){
2020 SalOp *op=find_op(sal,ev);
2022 if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){
2023 if (op->sipfrag_pending){
2024 send_notify_for_refer(op->did,op->sipfrag_pending);
2025 op->sipfrag_pending=NULL;
2031 static bool_t process_event(Sal *sal, eXosip_event_t *ev){
2032 ms_message("linphone process event get a message %d\n",ev->type);
2034 case EXOSIP_CALL_ANSWERED:
2035 ms_message("CALL_ANSWERED\n");
2036 call_accepted(sal,ev);
2037 authentication_ok(sal,ev);
2039 case EXOSIP_CALL_CLOSED:
2040 case EXOSIP_CALL_CANCELLED:
2041 ms_message("CALL_CLOSED or CANCELLED\n");
2042 call_terminated(sal,ev);
2044 case EXOSIP_CALL_TIMEOUT:
2045 case EXOSIP_CALL_NOANSWER:
2046 ms_message("CALL_TIMEOUT or NOANSWER\n");
2047 return call_failure(sal,ev);
2049 case EXOSIP_CALL_REQUESTFAILURE:
2050 case EXOSIP_CALL_GLOBALFAILURE:
2051 case EXOSIP_CALL_SERVERFAILURE:
2052 ms_message("CALL_REQUESTFAILURE or GLOBALFAILURE or SERVERFAILURE\n");
2053 return call_failure(sal,ev);
2055 case EXOSIP_CALL_RELEASED:
2056 ms_message("CALL_RELEASED\n");
2057 call_released(sal, ev);
2059 case EXOSIP_CALL_INVITE:
2060 ms_message("CALL_NEW\n");
2061 inc_new_call(sal,ev);
2063 case EXOSIP_CALL_REINVITE:
2064 handle_reinvite(sal,ev);
2066 case EXOSIP_CALL_ACK:
2067 ms_message("CALL_ACK");
2070 case EXOSIP_CALL_REDIRECTED:
2071 ms_message("CALL_REDIRECTED");
2072 eXosip_default_action(ev);
2074 case EXOSIP_CALL_PROCEEDING:
2075 ms_message("CALL_PROCEEDING");
2076 call_proceeding(sal,ev);
2078 case EXOSIP_CALL_RINGING:
2079 ms_message("CALL_RINGING");
2080 call_ringing(sal,ev);
2081 authentication_ok(sal,ev);
2083 case EXOSIP_CALL_MESSAGE_NEW:
2084 ms_message("EXOSIP_CALL_MESSAGE_NEW");
2085 call_message_new(sal,ev);
2087 case EXOSIP_CALL_MESSAGE_REQUESTFAILURE:
2089 (ev->response->status_code==407 || ev->response->status_code==401)){
2090 return process_authentication(sal,ev);
2093 case EXOSIP_CALL_MESSAGE_ANSWERED:
2094 ms_message("EXOSIP_CALL_MESSAGE_ANSWERED ");
2095 process_in_call_reply(sal,ev);
2097 case EXOSIP_IN_SUBSCRIPTION_NEW:
2098 ms_message("CALL_IN_SUBSCRIPTION_NEW ");
2099 sal_exosip_subscription_recv(sal,ev);
2101 case EXOSIP_IN_SUBSCRIPTION_RELEASED:
2102 ms_message("CALL_SUBSCRIPTION_NEW ");
2103 sal_exosip_in_subscription_closed(sal,ev);
2105 case EXOSIP_SUBSCRIPTION_UPDATE:
2106 ms_message("CALL_SUBSCRIPTION_UPDATE");
2108 case EXOSIP_SUBSCRIPTION_NOTIFY:
2109 ms_message("CALL_SUBSCRIPTION_NOTIFY");
2110 sal_exosip_notify_recv(sal,ev);
2112 case EXOSIP_SUBSCRIPTION_ANSWERED:
2113 ms_message("EXOSIP_SUBSCRIPTION_ANSWERED, ev->sid=%i, ev->did=%i\n",ev->sid,ev->did);
2114 sal_exosip_subscription_answered(sal,ev);
2116 case EXOSIP_SUBSCRIPTION_CLOSED:
2117 ms_message("EXOSIP_SUBSCRIPTION_CLOSED\n");
2118 sal_exosip_subscription_closed(sal,ev);
2120 case EXOSIP_SUBSCRIPTION_REQUESTFAILURE: /**< announce a request failure */
2121 if (ev->response && (ev->response->status_code == 407 || ev->response->status_code == 401)){
2122 return process_authentication(sal,ev);
2124 case EXOSIP_SUBSCRIPTION_SERVERFAILURE:
2125 case EXOSIP_SUBSCRIPTION_GLOBALFAILURE:
2126 sal_exosip_subscription_closed(sal,ev);
2128 case EXOSIP_REGISTRATION_FAILURE:
2129 ms_message("REGISTRATION_FAILURE\n");
2130 return registration_failure(sal,ev);
2132 case EXOSIP_REGISTRATION_SUCCESS:
2133 authentication_ok(sal,ev);
2134 registration_success(sal,ev);
2136 case EXOSIP_MESSAGE_NEW:
2137 other_request(sal,ev);
2139 case EXOSIP_MESSAGE_PROCEEDING:
2140 case EXOSIP_MESSAGE_ANSWERED:
2141 case EXOSIP_MESSAGE_REDIRECTED:
2142 case EXOSIP_MESSAGE_SERVERFAILURE:
2143 case EXOSIP_MESSAGE_GLOBALFAILURE:
2144 other_request_reply(sal,ev);
2146 case EXOSIP_MESSAGE_REQUESTFAILURE:
2147 case EXOSIP_NOTIFICATION_REQUESTFAILURE:
2149 switch (ev->response->status_code) {
2152 return process_authentication(sal,ev);
2154 eXosip_automatic_action ();
2159 other_request_reply(sal,ev);
2162 ms_message("Unhandled exosip event ! %i",ev->type);
2168 int sal_iterate(Sal *sal){
2170 while((ev=eXosip_event_wait(0,0))!=NULL){
2171 if (process_event(sal,ev))
2172 eXosip_event_free(ev);
2174 #ifdef HAVE_EXOSIP_TRYLOCK
2175 if (eXosip_trylock()==0){
2176 eXosip_automatic_refresh();
2179 ms_warning("eXosip_trylock busy.");
2183 eXosip_automatic_refresh();
2189 static void register_set_contact(osip_message_t *msg, const char *contact){
2190 osip_uri_param_t *param = NULL;
2191 osip_contact_t *ct=NULL;
2193 /*we get the line parameter choosed by exosip, and add it to our own contact*/
2194 osip_message_get_contact(msg,0,&ct);
2196 osip_uri_uparam_get_byname(ct->url, "line", ¶m);
2197 if (param && param->gvalue)
2198 line=osip_strdup(param->gvalue);
2200 _osip_list_set_empty(&msg->contacts,(void (*)(void*))osip_contact_free);
2201 osip_message_set_contact(msg,contact);
2202 osip_message_get_contact(msg,0,&ct);
2203 osip_uri_uparam_add(ct->url,osip_strdup("line"),line);
2206 static void sal_register_add_route(osip_message_t *msg, const char *proxy){
2208 snprintf(tmp,sizeof(tmp)-1,"<%s;lr>",proxy);
2210 osip_list_special_free(&msg->routes,(void (*)(void*))osip_route_free);
2211 osip_message_set_route(msg,tmp);
2214 int sal_register(SalOp *h, const char *proxy, const char *from, int expires){
2215 osip_message_t *msg;
2216 const char *contact=sal_op_get_contact(h);
2218 sal_op_set_route(h,proxy);
2220 SalAddress *from_parsed=sal_address_new(from);
2222 char *uri, *domain_ptr = NULL;
2223 if (from_parsed==NULL) {
2224 ms_warning("sal_register() bad from %s",from);
2227 /* Get domain using sal_address_as_string_uri_only() and stripping the username part instead of
2228 using sal_address_get_domain() because to have a properly formatted domain with IPv6 proxy addresses. */
2229 uri = sal_address_as_string_uri_only(from_parsed);
2230 if (uri) domain_ptr = strchr(uri, '@');
2232 snprintf(domain,sizeof(domain),"sip:%s",domain_ptr+1);
2234 snprintf(domain,sizeof(domain),"sip:%s",sal_address_get_domain(from_parsed));
2236 if (uri) ms_free(uri);
2237 sal_address_destroy(from_parsed);
2239 h->rid=eXosip_register_build_initial_register(from,domain,NULL,expires,&msg);
2241 if (contact) register_set_contact(msg,contact);
2242 sal_register_add_route(msg,proxy);
2243 sal_add_register(h->base.root,h);
2245 ms_error("Could not build initial register.");
2251 eXosip_register_build_register(h->rid,expires,&msg);
2252 sal_register_add_route(msg,proxy);
2255 eXosip_register_send_register(h->rid,msg);
2258 return (msg != NULL) ? 0 : -1;
2261 int sal_register_refresh(SalOp *op, int expires){
2262 osip_message_t *msg=NULL;
2263 const char *contact=sal_op_get_contact(op);
2267 ms_error("Unexistant registration context, not possible to refresh.");
2270 #ifdef HAVE_EXOSIP_TRYLOCK
2271 /*iOS hack: in the keep alive handler, we have no more than 10 seconds to refresh registers, otherwise the application is suspended forever.
2272 * 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
2273 * the exosip lock in a non blocking way, and give up if it takes too long*/
2274 while (eXosip_trylock()!=0){
2276 if (tries>30) {/*after 3 seconds, give up*/
2277 ms_warning("Could not obtain exosip lock in a reasonable time, giving up.");
2284 eXosip_register_build_register(op->rid,expires,&msg);
2286 if (contact) register_set_contact(msg,contact);
2287 sal_register_add_route(msg,sal_op_get_route(op));
2288 eXosip_register_send_register(op->rid,msg);
2289 }else ms_error("Could not build REGISTER refresh message.");
2291 return (msg != NULL) ? 0 : -1;
2295 int sal_unregister(SalOp *h){
2296 osip_message_t *msg=NULL;
2298 eXosip_register_build_register(h->rid,0,&msg);
2299 if (msg) eXosip_register_send_register(h->rid,msg);
2300 else ms_warning("Could not build unREGISTER !");
2305 SalAddress * sal_address_new(const char *uri){
2307 osip_from_init(&from);
2309 // Remove front spaces
2310 while (uri[0]==' ') {
2314 if (osip_from_parse(from,uri)!=0){
2315 osip_from_free(from);
2318 if (from->displayname!=NULL && from->displayname[0]=='"'){
2319 char *unquoted=osip_strdup_without_quote(from->displayname);
2320 osip_free(from->displayname);
2321 from->displayname=unquoted;
2323 return (SalAddress*)from;
2326 SalAddress * sal_address_clone(const SalAddress *addr){
2327 osip_from_t *ret=NULL;
2328 osip_from_clone((osip_from_t*)addr,&ret);
2329 return (SalAddress*)ret;
2332 #define null_if_empty(s) (((s)!=NULL && (s)[0]!='\0') ? (s) : NULL )
2334 const char *sal_address_get_scheme(const SalAddress *addr){
2335 const osip_from_t *u=(const osip_from_t*)addr;
2336 return null_if_empty(u->url->scheme);
2339 const char *sal_address_get_display_name(const SalAddress* addr){
2340 const osip_from_t *u=(const osip_from_t*)addr;
2341 return null_if_empty(u->displayname);
2344 const char *sal_address_get_username(const SalAddress *addr){
2345 const osip_from_t *u=(const osip_from_t*)addr;
2346 return null_if_empty(u->url->username);
2349 const char *sal_address_get_domain(const SalAddress *addr){
2350 const osip_from_t *u=(const osip_from_t*)addr;
2351 return null_if_empty(u->url->host);
2354 void sal_address_set_display_name(SalAddress *addr, const char *display_name){
2355 osip_from_t *u=(osip_from_t*)addr;
2356 if (u->displayname!=NULL){
2357 osip_free(u->displayname);
2358 u->displayname=NULL;
2360 if (display_name!=NULL && display_name[0]!='\0'){
2361 u->displayname=osip_strdup(display_name);
2365 void sal_address_set_username(SalAddress *addr, const char *username){
2366 osip_from_t *uri=(osip_from_t*)addr;
2367 if (uri->url->username!=NULL){
2368 osip_free(uri->url->username);
2369 uri->url->username=NULL;
2372 uri->url->username=osip_strdup(username);
2375 void sal_address_set_domain(SalAddress *addr, const char *host){
2376 osip_from_t *uri=(osip_from_t*)addr;
2377 if (uri->url->host!=NULL){
2378 osip_free(uri->url->host);
2379 uri->url->host=NULL;
2382 uri->url->host=osip_strdup(host);
2385 void sal_address_set_port(SalAddress *addr, const char *port){
2386 osip_from_t *uri=(osip_from_t*)addr;
2387 if (uri->url->port!=NULL){
2388 osip_free(uri->url->port);
2389 uri->url->port=NULL;
2392 uri->url->port=osip_strdup(port);
2395 void sal_address_set_port_int(SalAddress *uri, int port){
2398 /*this is the default, special case to leave the port field blank*/
2399 sal_address_set_port(uri,NULL);
2402 snprintf(tmp,sizeof(tmp),"%i",port);
2403 sal_address_set_port(uri,tmp);
2406 void sal_address_clean(SalAddress *addr){
2407 osip_generic_param_freelist(& ((osip_from_t*)addr)->gen_params);
2408 osip_uri_param_freelist(& ((osip_from_t*)addr)->url->url_params);
2411 char *sal_address_as_string(const SalAddress *u){
2413 osip_from_t *from=(osip_from_t *)u;
2414 char *old_displayname=NULL;
2415 /* hack to force use of quotes around the displayname*/
2416 if (from->displayname!=NULL
2417 && from->displayname[0]!='"'){
2418 old_displayname=from->displayname;
2419 from->displayname=osip_enquote(from->displayname);
2421 osip_from_to_str(from,&tmp);
2422 if (old_displayname!=NULL){
2423 ms_free(from->displayname);
2424 from->displayname=old_displayname;
2431 char *sal_address_as_string_uri_only(const SalAddress *u){
2432 char *tmp=NULL,*ret;
2433 osip_uri_to_str(((osip_from_t*)u)->url,&tmp);
2438 void sal_address_set_param(SalAddress *u,const char* name,const char* value) {
2439 osip_uri_param_t *param=NULL;
2440 osip_uri_uparam_get_byname(((osip_from_t*)u)->url,(char*)name,¶m);
2442 osip_uri_uparam_add (((osip_from_t*)u)->url,ms_strdup(name),value ? ms_strdup(value) : NULL);
2444 osip_free(param->gvalue);
2445 param->gvalue=value ? osip_strdup(value) : NULL;
2450 void sal_address_destroy(SalAddress *u){
2451 osip_from_free((osip_from_t*)u);
2454 void sal_set_keepalive_period(Sal *ctx,unsigned int value) {
2455 ctx->keepalive_period=value;
2456 eXosip_set_option (EXOSIP_OPT_UDP_KEEP_ALIVE, &value);
2458 unsigned int sal_get_keepalive_period(Sal *ctx) {
2459 return ctx->keepalive_period;
2462 const char * sal_address_get_port(const SalAddress *addr) {
2463 const osip_from_t *u=(const osip_from_t*)addr;
2464 return null_if_empty(u->url->port);
2467 int sal_address_get_port_int(const SalAddress *uri) {
2468 const char* port = sal_address_get_port(uri);
2475 SalTransport sal_address_get_transport(const SalAddress* addr) {
2476 const osip_from_t *u=(const osip_from_t*)addr;
2477 osip_uri_param_t *transport_param=NULL;
2478 osip_uri_uparam_get_byname(u->url,"transport",&transport_param);
2479 if (transport_param == NULL){
2480 return SalTransportUDP;
2482 return sal_transport_parse(transport_param->gvalue);
2485 void sal_address_set_transport(SalAddress* addr,SalTransport transport) {
2486 sal_address_set_param(addr, "transport", sal_transport_to_string(transport));
2489 /* sends a reinvite. Local media description may have changed by application since call establishment*/
2490 int sal_call_update(SalOp *h, const char *subject){
2492 osip_message_t *reinvite=NULL;
2495 if(eXosip_call_build_request(h->did,"INVITE",&reinvite) != 0 || reinvite==NULL){
2500 osip_message_set_subject(reinvite,subject);
2501 osip_message_set_allow(reinvite, "INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
2502 if (h->base.contact){
2503 _osip_list_set_empty(&reinvite->contacts,(void (*)(void*))osip_contact_free);
2504 osip_message_set_contact(reinvite,h->base.contact);
2506 if (h->base.root->session_expires!=0){
2507 osip_message_set_header(reinvite, "Session-expires", "200");
2508 osip_message_set_supported(reinvite, "timer");
2510 if (h->base.local_media){
2511 h->sdp_offering=TRUE;
2512 set_sdp_from_desc(reinvite,h->base.local_media);
2513 }else h->sdp_offering=FALSE;
2515 err = eXosip_call_send_request(h->did, reinvite);
2519 void sal_reuse_authorization(Sal *ctx, bool_t value) {
2520 ctx->reuse_authorization=value;