Commit d20d39b2 authored by Simon Morlat's avatar Simon Morlat

add SAL api to send/recv out of dialogs refers.

parent 86161b92
......@@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "c-wrapper/internal/c-sal.h"
#include "sal/call-op.h"
#include "sal/message-op.h"
#include "sal/refer-op.h"
#include "linphone/core.h"
#include "private.h"
......@@ -385,7 +386,7 @@ static void dtmf_received(SalOp *op, char dtmf){
#endif
}
static void refer_received(Sal *sal, SalOp *op, const char *referto){
static void call_refer_received(SalOp *op, const SalAddress *referto){
#if 0
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal);
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
......@@ -713,6 +714,14 @@ static void on_notify_response(SalOp *op){
}
}
static void refer_received(SalOp *op, const SalAddress *refer_to){
/*if processing is ok*/
dynamic_cast<SalReferOp*>(op)->reply(SalReasonNone);
/*otherwise*/
//dynamic_cast<SalReferOp*>(op)->reply(SalReasonDeclined);
}
Sal::Callbacks linphone_sal_callbacks={
call_received,
call_rejected,
......@@ -725,12 +734,12 @@ Sal::Callbacks linphone_sal_callbacks={
call_failure,
call_released,
call_cancel_done,
call_refer_received,
auth_failure,
register_success,
register_failure,
vfu_request,
dtmf_received,
refer_received,
message_received,
message_delivery_update,
notify_refer,
......@@ -748,5 +757,6 @@ Sal::Callbacks linphone_sal_callbacks={
info_received,
on_publish_response,
on_expire,
on_notify_response
on_notify_response,
refer_received,
};
......@@ -172,6 +172,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
sal/presence-op.cpp
sal/register-op.cpp
sal/sal.cpp
sal/refer-op.cpp
utils/general.cpp
utils/payload-type-handler.cpp
utils/utils.cpp
......
......@@ -1438,7 +1438,6 @@ void SalCallOp::process_refer(const belle_sip_request_event_t *event, belle_sip_
belle_sip_header_referred_by_t *referred_by= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_referred_by_t);
belle_sip_response_t* resp;
belle_sip_uri_t* refer_to_uri;
char* refer_to_uri_str;
ms_message("Receiving REFER request on op [%p]", this);
if (refer_to) {
......@@ -1451,13 +1450,11 @@ void SalCallOp::process_refer(const belle_sip_request_event_t *event, belle_sip_
if (referred_by){
set_referred_by(referred_by);
}
refer_to_uri_str=belle_sip_uri_to_string(refer_to_uri);
resp = create_response_from_request(req,202);
belle_sip_server_transaction_send_response(server_transaction,resp);
this->root->callbacks.refer_received(this->root,this,refer_to_uri_str);
belle_sip_free(refer_to_uri_str);
this->root->callbacks.call_refer_received(this,(SalAddress*)BELLE_SIP_HEADER_ADDRESS(refer_to));
} else {
ms_warning("cannot do anything with the refer without destination\n");
ms_warning("cannot do anything with the refer without destination");
resp = create_response_from_request(req,400);
belle_sip_server_transaction_send_response(server_transaction,resp);
}
......
......@@ -140,7 +140,8 @@ protected:
Message,
Presence,
Publish,
Subscribe
Subscribe,
Refer /*for out of dialog refer only*/
};
static const char *to_string(const SalOp::Type type);
......
/*
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*/
return;
}
op->root->callbacks.refer_received(op, (SalAddress*)refer_to);
/*the app is expected to reply in the callback*/
}
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()));
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
/*
Linphone library
Copyright (C) 2010-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 _SAL_REFER_OP_H_
#define _SAL_REFER_OP_H_
#include "sal/op.h"
LINPHONE_BEGIN_NAMESPACE
class SalReferOp: public SalOp{
public:
SalReferOp(Sal *sal);
int send_refer(const SalAddress *refer_to);
int reply(SalReason reason);
private:
virtual void fill_cbs() override;
void process_error();
static void process_io_error_cb(void *user_ctx, const belle_sip_io_error_event_t *event);
static void process_response_event_cb(void *op_base, const belle_sip_response_event_t *event);
static void process_timeout_cb(void *user_ctx, const belle_sip_timeout_event_t *event);
static void process_request_event_cb(void *op_base, const belle_sip_request_event_t *event);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _SAL_MESSAGE_OP_H_
......@@ -20,6 +20,7 @@
#include "sal/sal.h"
#include "sal/call-op.h"
#include "sal/presence-op.h"
#include "sal/refer-op.h"
#include "sal/event-op.h"
#include "sal/message-op.h"
#include "bellesip_sal/sal_impl.h"
......@@ -104,7 +105,6 @@ void Sal::process_request_event_cb(void *ud, const belle_sip_request_event_t *ev
if (strcmp("INVITE",method)==0) {
op=new SalCallOp(sal);
op->dir=SalOp::Dir::Incoming;
op->fill_cbs();
}else if ((strcmp("SUBSCRIBE",method)==0 || strcmp("NOTIFY",method)==0) && (evh=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event"))!=NULL) {
if (strncmp(belle_sip_header_get_unparsed_value(evh),"presence",strlen("presence"))==0){
......@@ -112,11 +112,12 @@ void Sal::process_request_event_cb(void *ud, const belle_sip_request_event_t *ev
} else {
op=new SalSubscribeOp(sal);
}
op->dir=SalOp::Dir::Incoming;
op->fill_cbs();
}else if (strcmp("MESSAGE",method)==0) {
op=new SalMessageOp(sal);
op->dir=SalOp::Dir::Incoming;
op->fill_cbs();
}else if (strcmp("REFER",method)==0) {
op=new SalReferOp(sal);
op->fill_cbs();
}else if (strcmp("OPTIONS",method)==0) {
resp=belle_sip_response_create_from_request(req,200);
......@@ -147,6 +148,7 @@ void Sal::process_request_event_cb(void *ud, const belle_sip_request_event_t *ev
belle_sip_provider_send_response(sal->prov,resp);
return;
}
op->dir=SalOp::Dir::Incoming;
}
if (!op->from_address) {
......
......@@ -30,6 +30,7 @@ class SalCallOp;
class SalMessageOp;
class SalSubscribeOp;
class SalPresenceOp;
class SalReferOp;
class Sal{
public:
......@@ -50,7 +51,8 @@ public:
typedef void (*OnRegisterFailureCb)(SalOp *op);
typedef void (*OnVfuRequestCb)(SalOp *op);
typedef void (*OnDtmfReceivedCb)(SalOp *op, char dtmf);
typedef void (*OnReferCb)(Sal *sal, SalOp *op, const char *referto);
typedef void (*OnCallReferCb)(SalOp *op, const SalAddress *referto);
typedef void (*OnReferCb)(SalOp *op, const SalAddress *referto);
typedef void (*OnMessageReceivedCb)(SalOp *op, const SalMessage *msg);
typedef void (*OnMessageDeliveryUpdateCb)(SalOp *op, SalMessageDeliveryStatus);
typedef void (*OnNotifyReferCb)(SalOp *op, SalReferStatus state);
......@@ -81,12 +83,13 @@ public:
OnCallFailureCb call_failure;
OnCallReleasedCb call_released;
OnCallCancelDoneCb call_cancel_done;
OnCallReferCb call_refer_received;
OnAuthFailureCb auth_failure;
OnRegisterSuccessCb register_success;
OnRegisterFailureCb register_failure;
OnVfuRequestCb vfu_request;
OnDtmfReceivedCb dtmf_received;
OnReferCb refer_received;
OnMessageReceivedCb message_received;
OnMessageDeliveryUpdateCb message_delivery_update;
OnNotifyReferCb notify_refer;
......@@ -105,6 +108,7 @@ public:
OnPublishResponseCb on_publish_response;
OnExpireCb on_expire;
OnNotifyResponseCb on_notify_response;
OnReferCb refer_received; /*for out of dialog refer*/
};
Sal(MSFactory *factory);
......@@ -309,6 +313,7 @@ private:
friend class SalPresenceOp;
friend class SalSubscribeOp;
friend class SalPublishOp;
friend class SalReferOp;
};
int to_sip_code(SalReason r);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment