Commit 7969616d authored by Ghislain MARY's avatar Ghislain MARY

Handle redirection in the CallSession class.

parent 2e94f78c
......@@ -438,7 +438,6 @@ void linphone_core_stop_waiting(LinphoneCore *lc);
int linphone_call_proceed_with_invite_if_ready(LinphoneCall *call, LinphoneProxyConfig *dest_proxy);
int linphone_call_start_invite(LinphoneCall *call, const LinphoneAddress *destination/* = NULL if to be taken from the call log */);
int linphone_call_restart_invite(LinphoneCall *call);
/*
* param automatic_offering aims is to take into account previous answer for video in case of automatic re-invite.
* Purpose is to avoid to re-ask video previously declined */
......
......@@ -29,6 +29,7 @@ LINPHONE_BEGIN_NAMESPACE
class AddressPrivate;
class LINPHONE_PUBLIC Address : public ClonableObject {
friend class CallSession;
friend class ClientGroupChatRoom;
public:
......
......@@ -179,19 +179,7 @@ void linphone_call_update_local_media_description_from_ice_or_upnp (LinphoneCall
void linphone_call_make_local_media_description (LinphoneCall *call) {}
void linphone_call_create_op (LinphoneCall *call) {
#if 0
if (call->op) sal_op_release(call->op);
call->op=sal_op_new(call->core->sal);
sal_op_set_user_pointer(call->op,call);
if (linphone_call_params_get_referer(call->params))
sal_call_set_referer(call->op,linphone_call_params_get_referer(call->params)->op);
linphone_configure_op(call->core,call->op,call->log->to,linphone_call_params_get_custom_headers(call->params),FALSE);
if (linphone_call_params_get_privacy(call->params) != LinphonePrivacyDefault)
sal_op_set_privacy(call->op,(SalPrivacyMask)linphone_call_params_get_privacy(call->params));
/*else privacy might be set by proxy */
#endif
}
void linphone_call_create_op (LinphoneCall *call) {}
void linphone_call_set_state (LinphoneCall *call, LinphoneCallState cstate, const char *message) {}
......@@ -884,39 +872,7 @@ LinphoneStatus linphone_call_terminate_with_error_info (LinphoneCall *call , con
}
LinphoneStatus linphone_call_redirect (LinphoneCall *call, const char *redirect_uri) {
#if 0
char *real_url = nullptr;
LinphoneCore *lc;
LinphoneAddress *real_parsed_url;
SalErrorInfo sei;
if (call->state != LinphoneCallIncomingReceived) {
ms_error("Bad state for call redirection.");
return -1;
}
lc = linphone_call_get_core(call);
real_parsed_url = linphone_core_interpret_url(lc, redirect_uri);
if (!real_parsed_url) {
/* Bad url */
ms_error("Bad redirect URI: %s", redirect_uri ? redirect_uri : "NULL");
return -1;
}
memset(&sei, 0, sizeof(sei));
real_url = linphone_address_as_string(real_parsed_url);
sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, nullptr, nullptr);
sal_call_decline_with_error_info(call->op, &sei, real_url);
ms_free(real_url);
linphone_error_info_set(call->ei, nullptr, LinphoneReasonMovedPermanently, 302, "Call redirected", nullptr);
call->non_op_error = TRUE;
terminate_call(call);
linphone_address_unref(real_parsed_url);
sal_error_info_reset(&sei);
return 0;
#else
return 0;
#endif
return L_GET_CPP_PTR_FROM_C_OBJECT(call)->redirect(redirect_uri);
}
LinphoneStatus linphone_call_decline (LinphoneCall *call, LinphoneReason reason) {
......
......@@ -267,6 +267,11 @@ LinphoneStatus Call::pause () {
return static_cast<MediaSession *>(d->getActiveSession().get())->pause();
}
LinphoneStatus Call::redirect (const std::string &redirectUri) {
L_D();
return d->getActiveSession()->redirect(redirectUri);
}
LinphoneStatus Call::resume () {
L_D();
return static_cast<MediaSession *>(d->getActiveSession().get())->resume();
......
......@@ -53,6 +53,7 @@ public:
LinphoneStatus decline (LinphoneReason reason);
LinphoneStatus decline (const LinphoneErrorInfo *ei);
LinphoneStatus pause ();
LinphoneStatus redirect (const std::string &redirectUri);
LinphoneStatus resume ();
void sendVfuRequest ();
void startRecording ();
......
......@@ -61,6 +61,7 @@ protected:
virtual void handleIncomingReceivedStateInIncomingNotification ();
virtual bool isReadyForInvite () const;
bool isUpdateAllowed (LinphoneCallState &nextState) const;
virtual int restartInvite ();
virtual void setReleased ();
virtual void setTerminated ();
virtual LinphoneStatus startAcceptUpdate (LinphoneCallState nextState, const std::string &stateInfo);
......@@ -72,6 +73,7 @@ protected:
private:
void completeLog ();
void createOp ();
void createOpTo (const LinphoneAddress *to);
LinphoneAddress * getFixedContact () const;
......
......@@ -255,9 +255,7 @@ bool CallSessionPrivate::failure () {
linphone_address_unref(log->to);
log->to = linphone_address_new(url);
ms_free(url);
#if 0
linphone_call_restart_invite(call);
#endif
restartInvite();
return true;
}
}
......@@ -514,6 +512,12 @@ bool CallSessionPrivate::isUpdateAllowed (LinphoneCallState &nextState) const {
return true;
}
int CallSessionPrivate::restartInvite () {
L_Q();
createOp();
return q->startInvite(nullptr, subject);
}
/*
* Called internally when reaching the Released state, to perform cleanups to break circular references.
**/
......@@ -617,6 +621,10 @@ void CallSessionPrivate::completeLog () {
linphone_core_report_call_log(core, log);
}
void CallSessionPrivate::createOp () {
createOpTo(log->to);
}
void CallSessionPrivate::createOpTo (const LinphoneAddress *to) {
L_Q();
if (op)
......@@ -794,6 +802,38 @@ void CallSession::iterate (time_t currentRealTime, bool oneSecondElapsed) {
}
}
LinphoneStatus CallSession::redirect (const string &redirectUri) {
L_D();
LinphoneAddress *realParsedAddr = linphone_core_interpret_url(d->core, redirectUri.c_str());
if (!realParsedAddr) {
/* Bad url */
lError() << "Bad redirect URI: " << redirectUri;
return -1;
}
char *realParsedUri = linphone_address_as_string(realParsedAddr);
Address redirectAddr(realParsedUri);
bctbx_free(realParsedUri);
linphone_address_unref(realParsedAddr);
return redirect(redirectAddr);
}
LinphoneStatus CallSession::redirect (const Address &redirectAddr) {
L_D();
if (d->state != LinphoneCallIncomingReceived) {
lError() << "Bad state for CallSession redirection";
return -1;
}
SalErrorInfo sei;
memset(&sei, 0, sizeof(sei));
sal_error_info_set(&sei, SalReasonRedirect, "SIP", 0, nullptr, nullptr);
d->op->decline_with_error_info(&sei, redirectAddr.getPrivate()->getInternalAddress());
linphone_error_info_set(d->ei, nullptr, LinphoneReasonMovedPermanently, 302, "Call redirected", nullptr);
d->nonOpError = true;
d->terminate();
sal_error_info_reset(&sei);
return 0;
}
void CallSession::startIncomingNotification () {
L_D();
if (d->listener)
......
......@@ -48,6 +48,8 @@ public:
virtual void initiateIncoming ();
virtual bool initiateOutgoing ();
virtual void iterate (time_t currentRealTime, bool oneSecondElapsed);
LinphoneStatus redirect (const std::string &redirectUri);
LinphoneStatus redirect (const Address &redirectAddr);
virtual void startIncomingNotification ();
virtual int startInvite (const Address *destination, const std::string &subject = "");
LinphoneStatus terminate (const LinphoneErrorInfo *ei = nullptr);
......
......@@ -230,6 +230,7 @@ private:
void handleIncomingReceivedStateInIncomingNotification () override;
bool isReadyForInvite () const override;
LinphoneStatus pause ();
int restartInvite () override;
void setTerminated () override;
LinphoneStatus startAcceptUpdate (LinphoneCallState nextState, const std::string &stateInfo) override;
LinphoneStatus startUpdate (const std::string &subject = "") override;
......
......@@ -264,27 +264,21 @@ bool MediaSessionPrivate::failure () {
if (i == 0)
lInfo() << "Retrying CallSession [" << q << "] with SAVP";
params->enableAvpf(false);
#if 0
linphone_call_restart_invite(call);
#endif
restartInvite();
return true;
} else if (!linphone_core_is_media_encryption_mandatory(core)) {
if (i == 0)
lInfo() << "Retrying CallSession [" << q << "] with AVP";
params->setMediaEncryption(LinphoneMediaEncryptionNone);
memset(localDesc->streams[i].crypto, 0, sizeof(localDesc->streams[i].crypto));
#if 0
linphone_call_restart_invite(call);
#endif
restartInvite();
return true;
}
} else if (params->avpfEnabled()) {
if (i == 0)
lInfo() << "Retrying CallSession [" << q << "] with AVP";
params->enableAvpf(false);
#if 0
linphone_call_restart_invite(call);
#endif
restartInvite();
return true;
}
}
......@@ -3684,6 +3678,12 @@ LinphoneStatus MediaSessionPrivate::pause () {
return 0;
}
int MediaSessionPrivate::restartInvite () {
stopStreams();
initializeStreams();
return CallSessionPrivate::restartInvite();
}
void MediaSessionPrivate::setTerminated () {
freeResources();
CallSessionPrivate::setTerminated();
......
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