forked from mirrors/linphone-iphone
Handle redirection in the CallSession class.
This commit is contained in:
parent
2e94f78c5a
commit
7969616d43
10 changed files with 66 additions and 59 deletions
|
|
@ -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();
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue