forked from mirrors/linphone-iphone
114 lines
4.5 KiB
C++
114 lines
4.5 KiB
C++
/*
|
|
Linphone library
|
|
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.
|
|
*/
|
|
|
|
#include "sal/refer-op.h"
|
|
|
|
using namespace std;
|
|
|
|
LINPHONE_BEGIN_NAMESPACE
|
|
|
|
void SalReferOp::process_error() {
|
|
this->state=State::Terminated;
|
|
}
|
|
|
|
void SalReferOp::process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event) {
|
|
SalReferOp * op = (SalReferOp *)user_ctx;
|
|
sal_error_info_set(&op->error_info,SalReasonIOError, "SIP", 503,"IO Error",NULL);
|
|
op->process_error();
|
|
}
|
|
|
|
void SalReferOp::process_response_event_cb(void *op_base, const belle_sip_response_event_t *event) {
|
|
SalReferOp * op = (SalReferOp *)op_base;
|
|
op->set_error_info_from_response(belle_sip_response_event_get_response(event));
|
|
/*the response is not notified to the app*/
|
|
/*To be done when necessary*/
|
|
}
|
|
|
|
void SalReferOp::process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event) {
|
|
SalReferOp * op=(SalReferOp *)user_ctx;
|
|
sal_error_info_set(&op->error_info,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL);
|
|
op->process_error();
|
|
}
|
|
|
|
void SalReferOp::process_request_event_cb(void *op_base, const belle_sip_request_event_t *event) {
|
|
SalReferOp * op = (SalReferOp *)op_base;
|
|
belle_sip_request_t *req = belle_sip_request_event_get_request(event);
|
|
belle_sip_header_refer_to_t *refer_to= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_refer_to_t);
|
|
belle_sip_server_transaction_t *server_transaction = belle_sip_provider_create_server_transaction(op->root->prov,belle_sip_request_event_get_request(event));
|
|
|
|
belle_sip_object_ref(server_transaction);
|
|
belle_sip_transaction_set_application_data(BELLE_SIP_TRANSACTION(server_transaction),op->ref());
|
|
op->pending_server_trans = server_transaction;
|
|
|
|
if (!refer_to){
|
|
ms_warning("cannot do anything with the refer without destination");
|
|
op->reply(SalReasonUnknown);/*is mapped on bad request*/
|
|
op->unref();
|
|
return;
|
|
}
|
|
SalAddress *referToAddr = sal_address_new(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(refer_to)));
|
|
op->root->callbacks.refer_received(op, referToAddr);
|
|
/*the app is expected to reply in the callback*/
|
|
sal_address_unref(referToAddr);
|
|
op->unref();
|
|
}
|
|
|
|
void SalReferOp::fill_cbs() {
|
|
static belle_sip_listener_callbacks_t op_refer_callbacks = {0};
|
|
if (op_refer_callbacks.process_io_error==NULL) {
|
|
op_refer_callbacks.process_io_error=process_io_error_cb;
|
|
op_refer_callbacks.process_response_event=process_response_event_cb;
|
|
op_refer_callbacks.process_timeout=process_timeout_cb;
|
|
op_refer_callbacks.process_request_event=process_request_event_cb;
|
|
}
|
|
this->callbacks=&op_refer_callbacks;
|
|
this->type=Type::Refer;
|
|
}
|
|
|
|
SalReferOp::SalReferOp(Sal *sal) : SalOp(sal){
|
|
fill_cbs();
|
|
}
|
|
|
|
int SalReferOp::send_refer(const SalAddress *refer_to) {
|
|
this->dir=Dir::Outgoing;
|
|
|
|
belle_sip_request_t* req=build_request("REFER");
|
|
if (req == NULL ) return -1;
|
|
if (get_contact_address()) belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(create_contact()));
|
|
belle_sip_header_address_t *address = BELLE_SIP_HEADER_ADDRESS(refer_to);
|
|
belle_sip_uri_t *uri = belle_sip_header_address_get_uri(address);
|
|
if (!belle_sip_uri_get_host(uri))
|
|
belle_sip_header_address_set_automatic(address, true);
|
|
belle_sip_header_refer_to_t *refer_to_header = belle_sip_header_refer_to_create(address);
|
|
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req), BELLE_SIP_HEADER(refer_to_header));
|
|
return send_request(req);
|
|
}
|
|
|
|
int SalReferOp::reply(SalReason reason){
|
|
if (this->pending_server_trans){
|
|
int code=to_sip_code(reason);
|
|
belle_sip_response_t *resp = belle_sip_response_create_from_request(
|
|
belle_sip_transaction_get_request((belle_sip_transaction_t*)this->pending_server_trans),code);
|
|
belle_sip_server_transaction_send_response(this->pending_server_trans,resp);
|
|
return 0;
|
|
}else ms_error("SalReferOp::reply: no server transaction");
|
|
return -1;
|
|
}
|
|
|
|
LINPHONE_END_NAMESPACE
|