Commit 86b626d3 authored by François Grisez's avatar François Grisez

Migration of Sal and SalOp into C++ classes

parent 70219e4c
......@@ -28,7 +28,6 @@
#include <sys/types.h>
#include <errno.h>
#include <signal.h>
#include "private.h" /*coreapi/private.h, needed for LINPHONE_VERSION */
#endif /*_WIN32_WCE*/
#include <limits.h>
#include <ctype.h>
......@@ -790,7 +789,7 @@ linphonec_prompt_for_auth_final(LinphoneCore *lc)
pending_auth=auth_stack.elem[auth_stack.nitems-1];
snprintf(auth_prompt, 256, "Password for %s on %s: ",
pending_auth->username, pending_auth->realm);
linphone_auth_info_get_username(pending_auth), linphone_auth_info_get_realm(pending_auth));
printf("\n");
#ifdef HAVE_READLINE
......
......@@ -56,15 +56,7 @@ set(LINPHONE_SOURCE_FILES_C
authentication.c
bellesip_sal/sal_address_impl.c
bellesip_sal/sal_impl.c
bellesip_sal/sal_op_call.c
bellesip_sal/sal_op_call_transfer.c
bellesip_sal/sal_op_events.c
bellesip_sal/sal_op_impl.c
bellesip_sal/sal_op_info.c
bellesip_sal/sal_op_message.c
bellesip_sal/sal_op_presence.c
bellesip_sal/sal_op_publish.c
bellesip_sal/sal_op_registration.c
bellesip_sal/sal_sdp.c
buffer.c
callbacks.c
......@@ -119,6 +111,14 @@ set(LINPHONE_SOURCE_FILES_C
)
set(LINPHONE_SOURCE_FILES_CXX
conference.cc
sal/call_op.cpp
sal/event_op.cpp
sal/message_op.cpp
sal/presence_op.cpp
sal/register_op.cpp
sal/sal.cpp
sal/sal_op.cpp
tester_utils.cpp
)
set(LINPHONE_INCLUDE_DIRS ${LINPHONE_INCLUDE_DIRS})
if(ANDROID)
......
/*
account_creator.h
Copyright (C) 2017 Belledonne Communications SARL
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _ACCOUNT_CREATOR_PRIVATE_H_
#define _ACCOUNT_CREATOR_PRIVATE_H_
#include "linphone/defs.h"
#include <belle-sip/object.h>
#include "linphone/account_creator_service.h"
#include "linphone/account_creator.h"
struct _LinphoneAccountCreatorService {
belle_sip_object_t base;
void *user_data;
LinphoneAccountCreatorRequestFunc account_creator_service_constructor_cb; /**< Constructor */
LinphoneAccountCreatorRequestFunc account_creator_service_destructor_cb; /**< Destructor */
LinphoneAccountCreatorRequestFunc create_account_request_cb; /**< Request to create account */
LinphoneAccountCreatorRequestFunc is_account_exist_request_cb; /**< Request to know if account exist */
LinphoneAccountCreatorRequestFunc activate_account_request_cb; /**< Request to activate account */
LinphoneAccountCreatorRequestFunc is_account_activated_request_cb; /**< Request to know if account is activated */
LinphoneAccountCreatorRequestFunc link_account_request_cb; /**< Request to link account with an alias */
LinphoneAccountCreatorRequestFunc activate_alias_request_cb; /**< Request to activate the link of alias */
LinphoneAccountCreatorRequestFunc is_alias_used_request_cb; /**< Request to know if alias is used */
LinphoneAccountCreatorRequestFunc is_account_linked_request_cb; /**< Request to know if account is linked with an alias */
LinphoneAccountCreatorRequestFunc recover_account_request_cb; /**< Request to recover account */
LinphoneAccountCreatorRequestFunc update_account_request_cb; /**< Request to update account */
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreatorService);
struct _LinphoneAccountCreatorCbs {
belle_sip_object_t base;
void *user_data;
LinphoneAccountCreatorCbsStatusCb create_account_response_cb; /**< Response of create_account request */
LinphoneAccountCreatorCbsStatusCb is_account_exist_response_cb; /**< Response of is_account_exist request */
LinphoneAccountCreatorCbsStatusCb activate_account_response_cb; /**< Response of activate_account request */
LinphoneAccountCreatorCbsStatusCb is_account_activated_response_cb; /**< Response of is_account_activated request */
LinphoneAccountCreatorCbsStatusCb link_account_response_cb; /**< Response of link_account request */
LinphoneAccountCreatorCbsStatusCb activate_alias_response_cb; /**< Response of activation alias */
LinphoneAccountCreatorCbsStatusCb is_alias_used_response_cb; /**< Response of is_alias_used request */
LinphoneAccountCreatorCbsStatusCb is_account_linked_response_cb; /**< Response of is_account_linked request */
LinphoneAccountCreatorCbsStatusCb recover_account_response_cb; /**< Response of recover_account request */
LinphoneAccountCreatorCbsStatusCb update_account_response_cb; /**< Response of update_account request */
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreatorCbs);
struct _LinphoneAccountCreator {
belle_sip_object_t base;
void *user_data;
LinphoneCore *core;
/* AccountCreator */
LinphoneAccountCreatorService *service; /**< Account creator service */
LinphoneAccountCreatorCbs *cbs; /**< Account creator cbs */
LinphoneXmlRpcSession *xmlrpc_session; /**< XML-RPC session */
LinphoneProxyConfig *proxy_cfg; /**< Default proxy config */
/* User */
char *username; /**< Username */
char *display_name; /**< Display name */
/* Password */
char *password; /**< Plain text password */
char *ha1; /**< Hash password */
/* Phone Number(Alias) */
char *phone_number; /**< User phone number*/
char *phone_country_code; /**< User phone number country code */
/* Email(Alias) */
char *email; /**< User email */
/* Misc */
char *language; /**< User language */
char *activation_code; /**< Account validation code */
char *domain; /**< Domain */
LinphoneTransportType transport; /**< Transport used */
/* Deprecated */
char *route;
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreator);
#ifdef __cplusplus
extern "C" {
#endif
/**
* Account creator custom to set Linphone default values
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_constructor_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to test the existence of a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_exist_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to create a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_create_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to activate a Linphone account with phone number.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to activate a Linphone account with email.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_email_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to test the validation of a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_activated_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to test the existence a phone number with a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_phone_number_used_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to link a phone number with a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_link_phone_number_with_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to activate the link of a phone number with a Linphone account.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_phone_number_link_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to a Linphone account with the phone number.
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_recover_phone_account_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to ask if an account is linked with a phone number
* @param[in] creator LinphoneAccountCreator object
* @return if this account is linked with a phone number
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account_linked_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to ask if an account is linked with a phone number
* @param[in] creator LinphoneAccountCreator object
* @param[in] new_pwd const char * : new password for the account creator
* @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise.
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_update_password_linphone(LinphoneAccountCreator *creator);
#ifdef __cplusplus
}
#endif
#endif // _ACCOUNT_CREATOR_PRIVATE_H_
......@@ -24,9 +24,12 @@
#include "linphone/core.h"
#include "linphone/lpconfig.h"
#include "sal/sal.hpp"
#include "c-wrapper/c-wrapper.h"
using namespace LINPHONE_NAMESPACE;
static void _linphone_auth_info_uninit(LinphoneAuthInfo *obj);
static void _linphone_auth_info_copy(LinphoneAuthInfo *dst, const LinphoneAuthInfo *src);
......@@ -434,10 +437,10 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
lc->auth_info=bctbx_list_append(lc->auth_info,linphone_auth_info_clone(info));
/* retry pending authentication operations */
for(l=elem=sal_get_pending_auths(lc->sal);elem!=NULL;elem=elem->next){
for(l=elem=lc->sal->get_pending_auths();elem!=NULL;elem=elem->next){
SalOp *op=(SalOp*)elem->data;
LinphoneAuthInfo *ai;
const SalAuthInfo *req_sai=sal_op_get_auth_requested(op);
const SalAuthInfo *req_sai=op->get_auth_requested();
ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,req_sai->realm,req_sai->username,req_sai->domain, FALSE);
if (ai){
SalAuthInfo sai;
......@@ -456,12 +459,12 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
}
/*proxy case*/
for (proxy=(bctbx_list_t*)linphone_core_get_proxy_config_list(lc);proxy!=NULL;proxy=proxy->next) {
if (proxy->data == sal_op_get_user_pointer(op)) {
if (proxy->data == op->get_user_pointer()) {
linphone_proxy_config_set_state((LinphoneProxyConfig*)(proxy->data),LinphoneRegistrationProgress,"Authentication...");
break;
}
}
sal_op_authenticate(op,&sai);
op->authenticate(&sai);
restarted_op_count++;
}
}
......
This diff is collapsed.
......@@ -24,161 +24,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "belle-sip/belle-sip.h"
#include "belle-sip/belle-sdp.h"
struct Sal{
MSFactory *factory;
SalCallbacks callbacks;
MSList *pending_auths;/*MSList of SalOp */
belle_sip_stack_t* stack;
belle_sip_provider_t *prov;
belle_sip_header_user_agent_t* user_agent;
belle_sip_listener_t *listener;
void *tunnel_client;
void *up; /*user pointer*/
int session_expires;
unsigned int keep_alive;
char *root_ca;
char *root_ca_data;
char *uuid;
int refresher_retry_after; /*retry after value for refresher*/
MSList *supported_tags;/*list of char * */
belle_sip_header_t *supported;
bool_t one_matching_codec;
bool_t use_tcp_tls_keep_alive;
bool_t nat_helper_enabled;
bool_t tls_verify;
bool_t tls_verify_cn;
bool_t use_dates;
bool_t auto_contacts;
bool_t enable_test_features;
bool_t no_initial_route;
bool_t enable_sip_update; /*true by default*/
SalOpSDPHandling default_sdp_handling;
bool_t pending_trans_checking; /*testing purpose*/
void *ssl_config;
bctbx_list_t *supported_content_types; /* list of char* */
};
typedef enum SalOpState {
SalOpStateEarly=0
,SalOpStateActive
,SalOpStateTerminating /*this state is used to wait until a proceeding state, so we can send the cancel*/
,SalOpStateTerminated
}SalOpState;
const char* sal_op_state_to_string(SalOpState value);
typedef enum SalOpDir {
SalOpDirIncoming=0
,SalOpDirOutgoing
}SalOpDir;
typedef enum SalOpType {
SalOpUnknown,
SalOpRegister,
SalOpCall,
SalOpMessage,
SalOpPresence,
SalOpPublish,
SalOpSubscribe
}SalOpType;
const char* sal_op_type_to_string(SalOpType type);
struct SalOp{
SalOpBase base;
const belle_sip_listener_callbacks_t *callbacks;
SalErrorInfo error_info;
SalErrorInfo reason_error_info;
belle_sip_client_transaction_t *pending_auth_transaction;
belle_sip_server_transaction_t* pending_server_trans;
belle_sip_server_transaction_t* pending_update_server_trans;
belle_sip_client_transaction_t* pending_client_trans;
SalAuthInfo* auth_info;
belle_sip_dialog_t* dialog;
belle_sip_header_replaces_t *replaces;
belle_sip_header_referred_by_t *referred_by;
SalMediaDescription *result;
belle_sdp_session_description_t *sdp_answer;
SalOpState state;
SalOpDir dir;
belle_sip_refresher_t* refresher;
int ref;
SalOpType type;
SalPrivacyMask privacy;
belle_sip_header_event_t *event; /*used by SalOpSubscribe kinds*/
SalOpSDPHandling sdp_handling;
int auth_requests; /*number of auth requested for this op*/
bool_t cnx_ip_to_0000_if_sendonly_enabled;
bool_t auto_answer_asked;
bool_t sdp_offering;
bool_t call_released;
bool_t manual_refresher;
bool_t has_auth_pending;
bool_t supports_session_timers;
bool_t op_released;
};
belle_sdp_session_description_t * media_description_to_sdp(const SalMediaDescription *sal);
belle_sdp_session_description_t * media_description_to_sdp(const SalMediaDescription *desc);
int sdp_to_media_description(belle_sdp_session_description_t *sdp, SalMediaDescription *desc);
belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method);
void sal_op_call_fill_cbs(SalOp*op);
void set_or_update_dialog(SalOp* op, belle_sip_dialog_t* dialog);
/*return reffed op*/
SalOp* sal_op_ref(SalOp* op);
/*return null, destroy op if ref count =0*/
void* sal_op_unref(SalOp* op);
void sal_op_release_impl(SalOp *op);
void sal_op_set_replaces(SalOp* op,belle_sip_header_replaces_t* replaces);
void sal_op_set_remote_ua(SalOp*op,belle_sip_message_t* message);
int sal_op_send_request(SalOp* op, belle_sip_request_t* request);
int sal_op_send_request_with_expires(SalOp* op, belle_sip_request_t* request,int expires);
void sal_op_resend_request(SalOp* op, belle_sip_request_t* request);
int sal_op_send_and_create_refresher(SalOp* op,belle_sip_request_t* req, int expires,belle_sip_refresher_listener_t listener );
belle_sip_response_t *sal_op_create_response_from_request(SalOp *op, belle_sip_request_t *req, int code);
/*
* return true if both from and to uri are sips
* */
bool_t sal_op_is_secure(const SalOp* op);
void sal_process_authentication(SalOp *op);
belle_sip_header_contact_t* sal_op_create_contact(SalOp *op) ;
bool_t _sal_compute_sal_errors(belle_sip_response_t* response, SalReason* sal_reason, char* reason, size_t reason_size);
SalReason _sal_reason_from_sip_code(int code);
void sal_op_set_reason_error_info(SalOp *op, belle_sip_message_t *msg);
void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response);
/*presence*/
void sal_op_presence_fill_cbs(SalOp*op);
/*messaging*/
void sal_op_message_fill_cbs(SalOp*op);
void sal_process_incoming_message(SalOp *op,const belle_sip_request_event_t *event);
void sal_op_subscribe_fill_cbs(SalOp*op);
/*call transfer*/
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr);
void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr);
/*create SalAuthInfo by copying username and realm from suth event*/
SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) ;
void sal_add_pending_auth(Sal *sal, SalOp *op);
void sal_remove_pending_auth(Sal *sal, SalOp *op);
void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceModel *presence);
belle_sip_response_t *sal_create_response_from_request(Sal *sal, belle_sip_request_t *req, int code);
void sal_op_assign_recv_headers(SalOp *op, belle_sip_message_t *incoming);
SalBodyHandler * sal_op_get_body_handler(SalOp *op, belle_sip_message_t *msg);
int sal_reason_to_sip_code(SalReason r);
void _sal_op_add_custom_headers(SalOp *op, belle_sip_message_t *msg);
SalSubscribeStatus belle_sip_message_get_subscription_state(const belle_sip_message_t *msg);
#endif /* SAL_IMPL_H_ */
/*
linphone
Copyright (C) 2012 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "sal_impl.h"
#include "offeranswer.h"
/*call transfer*/
static void sal_op_set_referred_by(SalOp* op,belle_sip_header_referred_by_t* referred_by) {
if (op->referred_by){
belle_sip_object_unref(op->referred_by);
}
op->referred_by=referred_by;
belle_sip_object_ref(op->referred_by);
}
int sal_call_refer_to(SalOp *op, belle_sip_header_refer_to_t* refer_to, belle_sip_header_referred_by_t* referred_by){
char* tmp;
belle_sip_request_t* req=op->dialog?belle_sip_dialog_create_request(op->dialog,"REFER"):sal_op_build_request(op, "REFER");
if (!req) {
tmp=belle_sip_uri_to_string(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to)));
ms_error("Cannot refer to [%s] for op [%p]",tmp,op);
belle_sip_free(tmp);
return -1;
}
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(refer_to));
if (referred_by) belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(referred_by));
return sal_op_send_request(op,req);
}
int sal_call_refer(SalOp *op, const char *refer_to){
belle_sip_header_address_t *referred_by;
belle_sip_header_refer_to_t* refer_to_header;
if (op->dialog) {
referred_by=(belle_sip_header_address_t*)belle_sip_object_clone(BELLE_SIP_OBJECT(belle_sip_dialog_get_local_party(op->dialog)));
}else{
referred_by=BELLE_SIP_HEADER_ADDRESS(sal_op_get_from_address(op));
}
refer_to_header=belle_sip_header_refer_to_create(belle_sip_header_address_parse(refer_to));
return sal_call_refer_to(op,refer_to_header,belle_sip_header_referred_by_create(referred_by));
}
int sal_call_refer_with_replaces(SalOp *op, SalOp *other_call_op){
belle_sip_dialog_state_t other_call_dialog_state=other_call_op->dialog?belle_sip_dialog_get_state(other_call_op->dialog):BELLE_SIP_DIALOG_NULL;
belle_sip_dialog_state_t op_dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL;
belle_sip_header_replaces_t* replaces;
belle_sip_header_refer_to_t* refer_to;
belle_sip_header_referred_by_t* referred_by;
const char* from_tag;
const char* to_tag;
char* escaped_replaces;
/*first, build refer to*/
if ((other_call_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) && (other_call_dialog_state!=BELLE_SIP_DIALOG_EARLY)) {
ms_error("wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED or BELE_SIP_DIALOG_EARLY",
belle_sip_dialog_state_to_string(other_call_dialog_state),
other_call_op);
return -1;
}
if (op_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) {
ms_error("wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED",
belle_sip_dialog_state_to_string(op_dialog_state),
op);
return -1;
}
refer_to=belle_sip_header_refer_to_create(belle_sip_dialog_get_remote_party(other_call_op->dialog));
belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(refer_to));
/*rfc3891
...
4. User Agent Client Behavior: Sending a Replaces Header
A User Agent that wishes to replace a single existing early or
confirmed dialog with a new dialog of its own, MAY send the target
User Agent an INVITE request containing a Replaces header field. The
User Agent Client (UAC) places the Call-ID, to-tag, and from-tag
information for the target dialog in a single Replaces header field
and sends the new INVITE to the target.*/
from_tag=belle_sip_dialog_get_local_tag(other_call_op->dialog);
to_tag=belle_sip_dialog_get_remote_tag(other_call_op->dialog);
replaces=belle_sip_header_replaces_create(belle_sip_header_call_id_get_call_id(belle_sip_dialog_get_call_id(other_call_op->dialog))
,from_tag,to_tag);
escaped_replaces=belle_sip_header_replaces_value_to_escaped_string(replaces);
belle_sip_uri_set_header(belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to)),"Replaces",escaped_replaces);
belle_sip_free(escaped_replaces);
referred_by=belle_sip_header_referred_by_create(belle_sip_dialog_get_local_party(op->dialog));
belle_sip_parameters_clean(BELLE_SIP_PARAMETERS(referred_by));
return sal_call_refer_to(op,refer_to,referred_by);
}
/*
int sal_call_accept_refer(SalOp *h){
ms_fatal("sal_call_accept_refer not implemented yet");
return -1;
}*/
/*informs this call is consecutive to an incoming refer */
int sal_call_set_referer(SalOp *h, SalOp *refered_call){
if (refered_call->replaces)
sal_op_set_replaces(h,refered_call->replaces);
if (refered_call->referred_by)
sal_op_set_referred_by(h,refered_call->referred_by);
return 0;
}
/* returns the SalOp of a call that should be replaced by h, if any */
SalOp *sal_call_get_replaces(SalOp *op){