Convert call transfer handling to C++.

This commit is contained in:
Ghislain MARY 2017-12-11 14:50:51 +01:00
parent bf2a9ade1b
commit 382c22a80f
16 changed files with 361 additions and 231 deletions

View file

@ -181,12 +181,6 @@ static void call_ringing(SalOp *h) {
L_GET_PRIVATE(session)->remoteRinging();
}
#if 0
static void start_pending_refer(LinphoneCall *call){
linphone_core_start_refered_call(call->core, call,NULL);
}
#endif
/*
* could be reach :
* - when the call is accepted
@ -363,30 +357,20 @@ static void dtmf_received(SalOp *op, char dtmf) {
L_GET_PRIVATE(mediaSession)->dtmfReceived(dtmf);
}
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);
LinphoneAddress *refer_to_addr = linphone_address_new(referto);
char method[20] = "";
if(refer_to_addr) {
const char *tmp = linphone_address_get_method_param(refer_to_addr);
if(tmp) strncpy(method, tmp, sizeof(method));
linphone_address_unref(refer_to_addr);
static void call_refer_received(SalOp *op, const SalAddress *referTo) {
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
char *addrStr = sal_address_as_string_uri_only(referTo);
Address referToAddr(addrStr);
string method;
if (referToAddr.isValid())
method = referToAddr.getMethodParam();
if (session && (method.empty() || (method == "INVITE"))) {
L_GET_PRIVATE(session)->referred(referToAddr);
} else {
LinphoneCore *lc = reinterpret_cast<LinphoneCore *>(op->get_sal()->get_user_pointer());
linphone_core_notify_refer_received(lc, addrStr);
}
if (call && (strlen(method) == 0 || strcmp(method, "INVITE") == 0)) {
if (call->refer_to!=NULL){
ms_free(call->refer_to);
}
call->refer_to=ms_strdup(referto);
call->refer_pending=TRUE;
linphone_call_set_state(call,LinphoneCallRefered,"Refered");
if (call->refer_pending) linphone_core_start_refered_call(lc,call,NULL);
}else {
linphone_core_notify_refer_received(lc,referto);
}
#endif
bctbx_free(addrStr);
}
static void message_received(SalOp *op, const SalMessage *msg){
@ -534,31 +518,30 @@ static bool_t auth_requested(Sal* sal, SalAuthInfo* sai) {
}
}
static void notify_refer(SalOp *op, SalReferStatus status){
LinphoneCall *call=(LinphoneCall*) op->get_user_pointer();
static void notify_refer(SalOp *op, SalReferStatus status) {
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
if (!session) {
ms_warning("Receiving notify_refer for unknown CallSession");
return;
}
LinphoneCallState cstate;
if (call==NULL) {
ms_warning("Receiving notify_refer for unknown call.");
return ;
}
switch(status){
switch (status) {
case SalReferTrying:
cstate=LinphoneCallOutgoingProgress;
break;
cstate = LinphoneCallOutgoingProgress;
break;
case SalReferSuccess:
cstate=LinphoneCallConnected;
break;
cstate = LinphoneCallConnected;
break;
case SalReferFailed:
cstate=LinphoneCallError;
break;
cstate = LinphoneCallError;
break;
default:
cstate=LinphoneCallError;
}
linphone_call_set_transfer_state(call, cstate);
if (cstate==LinphoneCallConnected){
/*automatically terminate the call as the transfer is complete.*/
linphone_call_terminate(call);
cstate = LinphoneCallError;
break;
}
L_GET_PRIVATE(session)->setTransferState(cstate);
if (cstate == LinphoneCallConnected)
session->terminate(); // Automatically terminate the call as the transfer is complete
}
static LinphoneChatMessageState chatStatusSal2Linphone(SalMessageDeliveryStatus status){

View file

@ -3372,42 +3372,10 @@ const char * linphone_core_get_route(LinphoneCore *lc){
return route;
}
LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
#if 0
LinphoneCallParams *cp=params ? linphone_call_params_copy(params) : linphone_core_create_call_params(lc, NULL);
LinphoneCall *newcall;
if (call->state!=LinphoneCallPaused){
ms_message("Automatically pausing current call to accept transfer.");
_linphone_call_pause(call);
call->was_automatically_paused=TRUE;
}
if (!params){
linphone_call_params_enable_audio(cp, linphone_call_params_audio_enabled(call->current_params));
linphone_call_params_enable_video(cp, linphone_call_params_video_enabled(call->current_params)); /*start the call to refer-target with video enabled if original call had video*/
}
linphone_call_params_set_referer(cp, call);
ms_message("Starting new call to refered address %s",call->refer_to);
call->refer_pending=FALSE;
newcall=linphone_core_invite_with_params(lc,call->refer_to,cp);
linphone_call_params_unref(cp);
if (newcall) {
call->transfer_target=linphone_call_ref(newcall);
linphone_core_notify_refer_state(lc,call,newcall);
}
return newcall;
#else
return nullptr;
#endif
}
void linphone_core_notify_refer_state(LinphoneCore *lc, LinphoneCall *referer, LinphoneCall *newcall){
#if 0
if (referer->op!=NULL){
sal_call_notify_refer_state(referer->op,newcall ? newcall->op : NULL);
}
#endif
LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params) {
shared_ptr<LinphonePrivate::Call> referredCall = L_GET_PRIVATE_FROM_C_OBJECT(call)->startReferredCall(params
? L_GET_CPP_PTR_FROM_C_OBJECT(params) : nullptr);
return L_GET_C_BACK_PTR(referredCall);
}
/*
@ -3786,7 +3754,7 @@ int linphone_core_preempt_sound_resources(LinphoneCore *lc){
current_call=linphone_core_get_current_call(lc);
if(current_call != NULL){
ms_message("Pausing automatically the current call.");
err = _linphone_call_pause(current_call);
err = L_GET_CPP_PTR_FROM_C_OBJECT(current_call)->pause();
}
if (lc->ringstream){
linphone_core_stop_ringing(lc);

View file

@ -51,7 +51,6 @@ LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, const Linpho
void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message);
/* private: */
LinphoneCallLog * linphone_call_log_new(LinphoneCallDir dir, LinphoneAddress *from, LinphoneAddress * to);
void linphone_call_set_transfer_state(LinphoneCall* call, LinphoneCallState state);
LinphonePlayer *linphone_call_build_player(LinphoneCall*call);
LinphonePrivate::SalCallOp *linphone_call_get_op(const LinphoneCall *call);
@ -327,7 +326,6 @@ int _linphone_call_pause(LinphoneCall *call);
/*conferencing subsystem*/
void _post_configure_audio_stream(AudioStream *st, LinphoneCore *lc, bool_t muted);
bool_t linphone_core_sound_resources_available(LinphoneCore *lc);
void linphone_core_notify_refer_state(LinphoneCore *lc, LinphoneCall *referer, LinphoneCall *newcall);
LINPHONE_PUBLIC unsigned int linphone_core_get_audio_features(LinphoneCore *lc);
void _linphone_core_codec_config_write(LinphoneCore *lc);

View file

@ -18,9 +18,11 @@
*/
#include "c-wrapper/c-wrapper.h"
#include "call/call-p.h"
#include "core/core.h"
#include "conference/params/call-session-params-p.h"
#include "conference/params/media-session-params-p.h"
#include "conference/session/call-session.h"
#include "linphone/call_params.h"
@ -437,11 +439,18 @@ SalCustomSdpAttribute *linphone_call_params_get_custom_sdp_media_attributes (con
}
LinphoneCall *linphone_call_params_get_referer (const LinphoneCallParams *params) {
return L_GET_PRIVATE_FROM_C_OBJECT(params)->getReferer();
shared_ptr<LinphonePrivate::CallSession> session = L_GET_PRIVATE_FROM_C_OBJECT(params)->getReferer();
if (!session)
return nullptr;
for (const auto &call : session->getCore()->getCalls()) {
if (L_GET_PRIVATE(call)->getActiveSession() == session)
return L_GET_C_BACK_PTR(call);
}
return nullptr;
}
void linphone_call_params_set_referer (LinphoneCallParams *params, LinphoneCall *referer) {
L_GET_PRIVATE_FROM_C_OBJECT(params)->setReferer(referer);
L_GET_PRIVATE_FROM_C_OBJECT(params)->setReferer(L_GET_PRIVATE_FROM_C_OBJECT(referer)->getActiveSession());
}
bool_t linphone_call_params_get_update_call_when_ice_completed (const LinphoneCallParams *params) {

View file

@ -48,6 +48,7 @@ L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(Call,
LinphoneAddress *diversionAddressCache;
LinphoneAddress *remoteAddressCache;
LinphoneAddress *toAddressCache;
mutable char *referToCache;
char *remoteContactCache;
char *remoteUserAgentCache;
mutable char *toHeaderCache;
@ -56,12 +57,10 @@ L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(Call,
LinphonePrivate::SalOp *op;
LinphoneCallState transfer_state; /*idle if no transfer*/
MSAudioEndpoint *endpoint; /*used for conferencing*/
char *refer_to;
LinphoneCall *referer; /*when this call is the result of a transfer, referer is set to the original call that caused the transfer*/
LinphoneCall *transfer_target;/*if this call received a transfer request, then transfer_target points to the new call created to the refer target */
LinphoneChatRoom *chat_room;
LinphoneConference *conf_ref; /**> Point on the associated conference if this call is part of a conference. NULL instead. */
bool_t refer_pending;
)
static void _linphone_call_constructor (LinphoneCall *call) {
@ -86,6 +85,8 @@ static void _linphone_call_destructor (LinphoneCall *call) {
linphone_address_unref(call->remoteAddressCache);
if (call->toAddressCache)
linphone_address_unref(call->toAddressCache);
if (call->referToCache)
bctbx_free(call->referToCache);
if (call->remoteContactCache)
bctbx_free(call->remoteContactCache);
if (call->remoteUserAgentCache)
@ -97,10 +98,6 @@ static void _linphone_call_destructor (LinphoneCall *call) {
call->op->release();
call->op=nullptr;
}
if (call->refer_to){
ms_free(call->refer_to);
call->refer_to=nullptr;
}
if (call->referer){
linphone_call_unref(call->referer);
call->referer=nullptr;
@ -142,18 +139,6 @@ static bool_t linphone_call_sound_resources_available (LinphoneCall *call) {
void linphone_call_stop_media_streams (LinphoneCall *call) {}
void linphone_call_set_transfer_state (LinphoneCall *call, LinphoneCallState state) {
#if 0
if (state != call->transfer_state) {
ms_message("Transfer state for call [%p] changed from [%s] to [%s]",call
,linphone_call_state_to_string(call->transfer_state)
,linphone_call_state_to_string(state));
call->transfer_state = state;
linphone_call_notify_transfer_state_changed(call, state);
}
#endif
}
/* Internal version that does not play tone indication*/
int _linphone_call_pause (LinphoneCall *call) {
return 0;
@ -299,35 +284,31 @@ LinphoneCallLog *linphone_call_get_call_log (const LinphoneCall *call) {
}
const char *linphone_call_get_refer_to (const LinphoneCall *call) {
#if 0
return call->refer_to;
#else
return nullptr;
#endif
string referTo = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getReferTo();
if (referTo.empty())
return nullptr;
if (call->referToCache)
bctbx_free(call->referToCache);
call->referToCache = bctbx_strdup(referTo.c_str());
return call->referToCache;
}
bool_t linphone_call_has_transfer_pending (const LinphoneCall *call) {
#if 0
return call->refer_pending;
#else
return FALSE;
#endif
return L_GET_CPP_PTR_FROM_C_OBJECT(call)->hasTransferPending();
}
LinphoneCall *linphone_call_get_transferer_call (const LinphoneCall *call) {
#if 0
return call->referer;
#else
return nullptr;
#endif
shared_ptr<LinphonePrivate::Call> referer = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getReferer();
if (!referer)
return nullptr;
return L_GET_C_BACK_PTR(referer);
}
LinphoneCall *linphone_call_get_transfer_target_call (const LinphoneCall *call) {
#if 0
return call->transfer_target;
#else
return nullptr;
#endif
shared_ptr<LinphonePrivate::Call> transferTarget = L_GET_CPP_PTR_FROM_C_OBJECT(call)->getTransferTarget();
if (!transferTarget)
return nullptr;
return L_GET_C_BACK_PTR(transferTarget);
}
LinphoneCall *linphone_call_get_replaced_call (LinphoneCall *call) {
@ -430,11 +411,7 @@ void linphone_call_set_next_video_frame_decoded_callback (LinphoneCall *call, Li
}
LinphoneCallState linphone_call_get_transfer_state (LinphoneCall *call) {
#if 0
return call->transfer_state;
#else
return LinphoneCallIdle;
#endif
return L_GET_CPP_PTR_FROM_C_OBJECT(call)->getTransferState();
}
void linphone_call_zoom_video (LinphoneCall* call, float zoom_factor, float* cx, float* cy) {
@ -559,36 +536,12 @@ LinphoneStatus linphone_call_accept_update (LinphoneCall *call, const LinphoneCa
return L_GET_CPP_PTR_FROM_C_OBJECT(call)->acceptUpdate(params ? L_GET_CPP_PTR_FROM_C_OBJECT(params) : nullptr);
}
LinphoneStatus linphone_call_transfer (LinphoneCall *call, const char *refer_to) {
#if 0
char *real_url = nullptr;
LinphoneCore *lc = linphone_call_get_core(call);
LinphoneAddress *real_parsed_url = linphone_core_interpret_url(lc, refer_to);
if (!real_parsed_url) {
/* bad url */
return -1;
}
//lc->call = nullptr; // Do not do that you will lose the call afterward...
real_url = linphone_address_as_string(real_parsed_url);
sal_call_refer(call->op, real_url);
ms_free(real_url);
linphone_address_unref(real_parsed_url);
linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit);
return 0;
#else
return 0;
#endif
LinphoneStatus linphone_call_transfer (LinphoneCall *call, const char *referTo) {
return L_GET_CPP_PTR_FROM_C_OBJECT(call)->transfer(referTo);
}
LinphoneStatus linphone_call_transfer_to_another (LinphoneCall *call, LinphoneCall *dest) {
#if 0
int result = sal_call_refer_with_replaces (call->op, dest->op);
linphone_call_set_transfer_state(call, LinphoneCallOutgoingInit);
return result;
#else
return 0;
#endif
return L_GET_CPP_PTR_FROM_C_OBJECT(call)->transfer(L_GET_CPP_PTR_FROM_C_OBJECT(dest));
}
void *linphone_call_get_native_video_window_id (const LinphoneCall *call) {

View file

@ -44,7 +44,9 @@ public:
void iterate (time_t currentRealTime, bool oneSecondElapsed);
void startIncomingNotification ();
void pauseForTransfer ();
int startInvite (const Address *destination);
std::shared_ptr<Call> startReferredCall (const MediaSessionParams *params);
virtual std::shared_ptr<CallSession> getActiveSession () const { return nullptr; }
bool getAudioMuted () const;
@ -71,7 +73,9 @@ private:
bool onCallSessionAccepted (const std::shared_ptr<const CallSession> &session) override;
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override;
void onCallSessionSetTerminated (const std::shared_ptr<const CallSession> &session) override;
void onCallSessionStartReferred (const std::shared_ptr<const CallSession> &session) override;
void onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state, const std::string &message) override;
void onCallSessionTransferStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state) override;
void onCheckForAcceptation (const std::shared_ptr<const CallSession> &session) override;
void onDtmfReceived (const std::shared_ptr<const CallSession> &session, char dtmf) override;
void onIncomingCallSessionNotified (const std::shared_ptr<const CallSession> &session) override;

View file

@ -19,6 +19,7 @@
#include "c-wrapper/c-wrapper.h"
#include "call-p.h"
#include "conference/params/media-session-params-p.h"
#include "conference/session/call-session-p.h"
#include "conference/session/media-session-p.h"
#include "core/core-p.h"
@ -76,10 +77,39 @@ void CallPrivate::startIncomingNotification () {
getActiveSession()->startIncomingNotification();
}
void CallPrivate::pauseForTransfer () {
static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->pauseForTransfer();
}
int CallPrivate::startInvite (const Address *destination) {
return getActiveSession()->startInvite(destination, "");
}
shared_ptr<Call> CallPrivate::startReferredCall (const MediaSessionParams *params) {
L_Q();
if (q->getState() != LinphoneCallPaused) {
pauseForTransfer();
}
MediaSessionParams msp;
if (params)
msp = *params;
else {
msp.initDefault(q->getCore());
msp.enableAudio(q->getCurrentParams()->audioEnabled());
msp.enableVideo(q->getCurrentParams()->videoEnabled());
}
lInfo() << "Starting new call to referred address " << q->getReferTo();
L_GET_PRIVATE(&msp)->setReferer(getActiveSession());
L_GET_PRIVATE(getActiveSession())->setReferPending(false);
LinphoneCall *newCall = linphone_core_invite_with_params(
q->getCore()->getCCore(), q->getReferTo().c_str(), L_GET_C_BACK_PTR(&msp));
if (newCall) {
getActiveSession()->getPrivate()->setTransferTarget(L_GET_PRIVATE_FROM_C_OBJECT(newCall)->getActiveSession());
L_GET_PRIVATE_FROM_C_OBJECT(newCall)->getActiveSession()->getPrivate()->notifyReferState();
}
return L_GET_CPP_PTR_FROM_C_OBJECT(newCall);
}
// -----------------------------------------------------------------------------
void CallPrivate::createPlayer () const {
@ -125,28 +155,28 @@ void CallPrivate::terminateBecauseOfLostMedia () {
// -----------------------------------------------------------------------------
void CallPrivate::onAckBeingSent (const std::shared_ptr<const CallSession> &session, LinphoneHeaders *headers) {
void CallPrivate::onAckBeingSent (const shared_ptr<const CallSession> &session, LinphoneHeaders *headers) {
L_Q();
linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, false);
}
void CallPrivate::onAckReceived (const std::shared_ptr<const CallSession> &session, LinphoneHeaders *headers) {
void CallPrivate::onAckReceived (const shared_ptr<const CallSession> &session, LinphoneHeaders *headers) {
L_Q();
linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, true);
}
void CallPrivate::onBackgroundTaskToBeStarted (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onBackgroundTaskToBeStarted (const shared_ptr<const CallSession> &session) {
backgroundTaskId = sal_begin_background_task("liblinphone call notification", nullptr, nullptr);
}
void CallPrivate::onBackgroundTaskToBeStopped (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onBackgroundTaskToBeStopped (const shared_ptr<const CallSession> &session) {
if (backgroundTaskId != 0) {
sal_end_background_task(backgroundTaskId);
backgroundTaskId = 0;
}
}
bool CallPrivate::onCallSessionAccepted (const std::shared_ptr<const CallSession> &session) {
bool CallPrivate::onCallSessionAccepted (const shared_ptr<const CallSession> &session) {
L_Q();
LinphoneCore *lc = q->getCore()->getCCore();
bool wasRinging = false;
@ -167,12 +197,12 @@ bool CallPrivate::onCallSessionAccepted (const std::shared_ptr<const CallSession
return wasRinging;
}
void CallPrivate::onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onCallSessionSetReleased (const shared_ptr<const CallSession> &session) {
L_Q();
linphone_call_unref(L_GET_C_BACK_PTR(q));
}
void CallPrivate::onCallSessionSetTerminated (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onCallSessionSetTerminated (const shared_ptr<const CallSession> &session) {
L_Q();
LinphoneCore *core = q->getCore()->getCCore();
if (q->getSharedFromThis() == q->getCore()->getCurrentCall()) {
@ -197,12 +227,21 @@ void CallPrivate::onCallSessionSetTerminated (const std::shared_ptr<const CallSe
ms_bandwidth_controller_reset_state(core->bw_controller);
}
void CallPrivate::onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state, const string &message) {
void CallPrivate::onCallSessionStartReferred (const shared_ptr<const CallSession> &session) {
startReferredCall(nullptr);
}
void CallPrivate::onCallSessionStateChanged (const shared_ptr<const CallSession> &session, LinphoneCallState state, const string &message) {
L_Q();
linphone_call_notify_state_changed(L_GET_C_BACK_PTR(q), state, message.c_str());
}
void CallPrivate::onCheckForAcceptation (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onCallSessionTransferStateChanged (const shared_ptr<const CallSession> &session, LinphoneCallState state) {
L_Q();
linphone_call_notify_transfer_state_changed(L_GET_C_BACK_PTR(q), state);
}
void CallPrivate::onCheckForAcceptation (const shared_ptr<const CallSession> &session) {
L_Q();
LinphoneCall *lcall = L_GET_C_BACK_PTR(q);
bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_calls(q->getCore()->getCCore()));
@ -225,23 +264,23 @@ void CallPrivate::onCheckForAcceptation (const std::shared_ptr<const CallSession
bctbx_list_free(copy);
}
void CallPrivate::onDtmfReceived (const std::shared_ptr<const CallSession> &session, char dtmf) {
void CallPrivate::onDtmfReceived (const shared_ptr<const CallSession> &session, char dtmf) {
L_Q();
linphone_call_notify_dtmf_received(L_GET_C_BACK_PTR(q), dtmf);
}
void CallPrivate::onIncomingCallSessionNotified (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onIncomingCallSessionNotified (const shared_ptr<const CallSession> &session) {
L_Q();
/* The call is acceptable so we can now add it to our list */
q->getCore()->getPrivate()->addCall(q->getSharedFromThis());
}
void CallPrivate::onIncomingCallSessionStarted (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onIncomingCallSessionStarted (const shared_ptr<const CallSession> &session) {
L_Q();
linphone_core_notify_incoming_call(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q));
}
void CallPrivate::onIncomingCallSessionTimeoutCheck (const std::shared_ptr<const CallSession> &session, int elapsed, bool oneSecondElapsed) {
void CallPrivate::onIncomingCallSessionTimeoutCheck (const shared_ptr<const CallSession> &session, int elapsed, bool oneSecondElapsed) {
L_Q();
if (oneSecondElapsed)
lInfo() << "Incoming call ringing for " << elapsed << " seconds";
@ -253,12 +292,12 @@ void CallPrivate::onIncomingCallSessionTimeoutCheck (const std::shared_ptr<const
}
}
void CallPrivate::onInfoReceived (const std::shared_ptr<const CallSession> &session, const LinphoneInfoMessage *im) {
void CallPrivate::onInfoReceived (const shared_ptr<const CallSession> &session, const LinphoneInfoMessage *im) {
L_Q();
linphone_call_notify_info_message_received(L_GET_C_BACK_PTR(q), im);
}
void CallPrivate::onNoMediaTimeoutCheck (const std::shared_ptr<const CallSession> &session, bool oneSecondElapsed) {
void CallPrivate::onNoMediaTimeoutCheck (const shared_ptr<const CallSession> &session, bool oneSecondElapsed) {
L_Q();
int disconnectTimeout = linphone_core_get_nortp_timeout(q->getCore()->getCCore());
bool disconnected = false;
@ -270,27 +309,27 @@ void CallPrivate::onNoMediaTimeoutCheck (const std::shared_ptr<const CallSession
terminateBecauseOfLostMedia();
}
void CallPrivate::onEncryptionChanged (const std::shared_ptr<const CallSession> &session, bool activated, const string &authToken) {
void CallPrivate::onEncryptionChanged (const shared_ptr<const CallSession> &session, bool activated, const string &authToken) {
L_Q();
linphone_call_notify_encryption_changed(L_GET_C_BACK_PTR(q), activated, authToken.empty() ? nullptr : authToken.c_str());
}
void CallPrivate::onStatsUpdated (const std::shared_ptr<const CallSession> &session, const LinphoneCallStats *stats) {
void CallPrivate::onStatsUpdated (const shared_ptr<const CallSession> &session, const LinphoneCallStats *stats) {
L_Q();
linphone_call_notify_stats_updated(L_GET_C_BACK_PTR(q), stats);
}
void CallPrivate::onResetCurrentSession (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onResetCurrentSession (const shared_ptr<const CallSession> &session) {
L_Q();
q->getCore()->getPrivate()->setCurrentCall(nullptr);
}
void CallPrivate::onSetCurrentSession (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onSetCurrentSession (const shared_ptr<const CallSession> &session) {
L_Q();
q->getCore()->getPrivate()->setCurrentCall(q->getSharedFromThis());
}
void CallPrivate::onFirstVideoFrameDecoded (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onFirstVideoFrameDecoded (const shared_ptr<const CallSession> &session) {
L_Q();
if (nextVideoFrameDecoded._func) {
nextVideoFrameDecoded._func(L_GET_C_BACK_PTR(q), nextVideoFrameDecoded._user_data);
@ -299,16 +338,16 @@ void CallPrivate::onFirstVideoFrameDecoded (const std::shared_ptr<const CallSess
}
}
void CallPrivate::onResetFirstVideoFrameDecoded (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onResetFirstVideoFrameDecoded (const shared_ptr<const CallSession> &session) {
resetFirstVideoFrameDecoded();
}
void CallPrivate::onPlayErrorTone (const std::shared_ptr<const CallSession> &session, LinphoneReason reason) {
void CallPrivate::onPlayErrorTone (const shared_ptr<const CallSession> &session, LinphoneReason reason) {
L_Q();
linphone_core_play_call_error_tone(q->getCore()->getCCore(), reason);
}
void CallPrivate::onRingbackToneRequested (const std::shared_ptr<const CallSession> &session, bool requested) {
void CallPrivate::onRingbackToneRequested (const shared_ptr<const CallSession> &session, bool requested) {
L_Q();
if (requested && linphone_core_get_remote_ringback_tone(q->getCore()->getCCore()))
playingRingbackTone = true;
@ -316,7 +355,7 @@ void CallPrivate::onRingbackToneRequested (const std::shared_ptr<const CallSessi
playingRingbackTone = false;
}
void CallPrivate::onStartRinging (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onStartRinging (const shared_ptr<const CallSession> &session) {
L_Q();
LinphoneCore *lc = q->getCore()->getCCore();
if (lc->ringstream)
@ -324,12 +363,12 @@ void CallPrivate::onStartRinging (const std::shared_ptr<const CallSession> &sess
startRemoteRing();
}
void CallPrivate::onStopRinging (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onStopRinging (const shared_ptr<const CallSession> &session) {
L_Q();
linphone_core_stop_ringing(q->getCore()->getCCore());
}
void CallPrivate::onStopRingingIfInCall (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onStopRingingIfInCall (const shared_ptr<const CallSession> &session) {
L_Q();
LinphoneCore *lc = q->getCore()->getCCore();
// We stop the ring only if we have this current call or if we are in call
@ -338,7 +377,7 @@ void CallPrivate::onStopRingingIfInCall (const std::shared_ptr<const CallSession
}
}
void CallPrivate::onStopRingingIfNeeded (const std::shared_ptr<const CallSession> &session) {
void CallPrivate::onStopRingingIfNeeded (const shared_ptr<const CallSession> &session) {
L_Q();
LinphoneCore *lc = q->getCore()->getCCore();
bool stopRinging = true;
@ -354,7 +393,7 @@ void CallPrivate::onStopRingingIfNeeded (const std::shared_ptr<const CallSession
linphone_core_stop_ringing(lc);
}
bool CallPrivate::isPlayingRingbackTone (const std::shared_ptr<const CallSession> &session) {
bool CallPrivate::isPlayingRingbackTone (const shared_ptr<const CallSession> &session) {
return playingRingbackTone;
}
@ -403,6 +442,11 @@ LinphoneStatus Call::deferUpdate () {
return d->getActiveSession()->deferUpdate();
}
bool Call::hasTransferPending () const {
L_D();
return d->getActiveSession()->hasTransferPending();
}
void Call::oglRender () const {
L_D();
static_pointer_cast<MediaSession>(d->getActiveSession())->getPrivate()->oglRender();
@ -463,6 +507,16 @@ LinphoneStatus Call::terminate (const LinphoneErrorInfo *ei) {
return d->getActiveSession()->terminate(ei);
}
LinphoneStatus Call::transfer (const shared_ptr<Call> &dest) {
L_D();
return d->getActiveSession()->transfer(dest->getPrivate()->getActiveSession());
}
LinphoneStatus Call::transfer (const string &dest) {
L_D();
return d->getActiveSession()->transfer(dest);
}
LinphoneStatus Call::update (const MediaSessionParams *msp) {
L_D();
return static_pointer_cast<MediaSession>(d->getActiveSession())->update(msp);
@ -616,6 +670,23 @@ float Call::getRecordVolume () const {
return static_pointer_cast<const MediaSession>(d->getActiveSession())->getRecordVolume();
}
shared_ptr<Call> Call::getReferer () const {
L_D();
shared_ptr<CallSession> referer = d->getActiveSession()->getReferer();
if (!referer)
return nullptr;
for (const auto &call : getCore()->getCalls()) {
if (call->getPrivate()->getActiveSession() == referer)
return call;
}
return nullptr;
}
string Call::getReferTo () const {
L_D();
return d->getActiveSession()->getReferTo();
}
const Address &Call::getRemoteAddress () const {
L_D();
return d->getActiveSession()->getRemoteAddress();
@ -681,6 +752,23 @@ string Call::getToHeader (const std::string &name) const {
return d->getActiveSession()->getToHeader(name);
}
LinphoneCallState Call::getTransferState () const {
L_D();
return d->getActiveSession()->getTransferState();
}
shared_ptr<Call> Call::getTransferTarget () const {
L_D();
shared_ptr<CallSession> transferTarget = d->getActiveSession()->getTransferTarget();
if (!transferTarget)
return nullptr;
for (const auto &call : getCore()->getCalls()) {
if (call->getPrivate()->getActiveSession() == transferTarget)
return call;
}
return nullptr;
}
LinphoneCallStats *Call::getVideoStats () const {
L_D();
return static_pointer_cast<const MediaSession>(d->getActiveSession())->getVideoStats();

View file

@ -48,6 +48,7 @@ public:
LinphoneStatus decline (LinphoneReason reason);
LinphoneStatus decline (const LinphoneErrorInfo *ei);
LinphoneStatus deferUpdate ();
bool hasTransferPending () const;
void oglRender () const;
LinphoneStatus pause ();
LinphoneStatus redirect (const std::string &redirectUri);
@ -60,6 +61,8 @@ public:
LinphoneStatus takePreviewSnapshot (const std::string &file);
LinphoneStatus takeVideoSnapshot (const std::string &file);
LinphoneStatus terminate (const LinphoneErrorInfo *ei = nullptr);
LinphoneStatus transfer (const std::shared_ptr<Call> &dest);
LinphoneStatus transfer (const std::string &dest);
LinphoneStatus update (const MediaSessionParams *msp = nullptr);
void zoomVideo (float zoomFactor, float *cx, float *cy);
void zoomVideo (float zoomFactor, float cx, float cy);
@ -91,6 +94,8 @@ public:
float getPlayVolume () const;
LinphoneReason getReason () const;
float getRecordVolume () const;
std::shared_ptr<Call> getReferer () const;
std::string getReferTo () const;
const Address &getRemoteAddress () const;
std::string getRemoteAddressAsString () const;
std::string getRemoteContact () const;
@ -104,6 +109,8 @@ public:
LinphoneCallStats *getTextStats () const;
const Address &getToAddress () const;
std::string getToHeader (const std::string &name) const;
LinphoneCallState getTransferState () const;
std::shared_ptr<Call> getTransferTarget () const;
LinphoneCallStats *getVideoStats () const;
bool mediaInProgress () const;
void setAudioRoute (LinphoneAudioRoute route);

View file

@ -30,6 +30,8 @@
LINPHONE_BEGIN_NAMESPACE
class CallSession;
class CallSessionParamsPrivate : public ClonableObjectPrivate {
public:
CallSessionParamsPrivate () = default;
@ -48,8 +50,8 @@ public:
const std::unordered_map<std::string, std::string> &getCustomContactParameters () const { return customContactParameters; }
LinphoneCall *getReferer () const { return referer; }
void setReferer (LinphoneCall *call) { referer = call; }
std::shared_ptr<CallSession> getReferer () const { return referer; }
void setReferer (std::shared_ptr<CallSession> session) { referer = session; }
public:
std::string sessionName;
@ -62,7 +64,7 @@ private:
bool noUserConsent = false; /* When set to true an UPDATE request will be used instead of reINVITE */
SalCustomHeader *customHeaders = nullptr;
std::unordered_map<std::string, std::string> customContactParameters;
LinphoneCall *referer = nullptr; /* In case call creation is consecutive to an incoming transfer, this points to the original call */
std::shared_ptr<CallSession> referer; /* In case call creation is consecutive to an incoming transfer, this points to the original call */
L_DECLARE_PUBLIC(CallSessionParams);
};

View file

@ -37,7 +37,9 @@ public:
virtual bool onCallSessionAccepted (const std::shared_ptr<const CallSession> &session) { return false; }
virtual void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) {}
virtual void onCallSessionSetTerminated (const std::shared_ptr<const CallSession> &session) {}
virtual void onCallSessionStartReferred (const std::shared_ptr<const CallSession> &session) {}
virtual void onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state, const std::string &message) {}
virtual void onCallSessionTransferStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state) {}
virtual void onCheckForAcceptation (const std::shared_ptr<const CallSession> &session) {}
virtual void onDtmfReceived (const std::shared_ptr<const CallSession> &session, char dtmf) {}
virtual void onIncomingCallSessionNotified (const std::shared_ptr<const CallSession> &session) {}

View file

@ -35,7 +35,9 @@ public:
int computeDuration () const;
virtual void initializeParamsAccordingToIncomingCallParams ();
void notifyReferState ();
virtual void setState (LinphoneCallState newState, const std::string &message);
void setTransferState (LinphoneCallState newState);
void startIncomingNotification ();
bool startPing ();
void setPingTime (int value) { pingTime = value; }
@ -45,6 +47,8 @@ public:
SalCallOp * getOp () const { return op; }
bool isBroken () const { return broken; }
void setParams (CallSessionParams *csp);
void setReferPending (bool value) { referPending = value; }
void setTransferTarget (std::shared_ptr<CallSession> session) { transferTarget = session; }
virtual void abort (const std::string &errorMsg);
virtual void accepted ();
@ -54,6 +58,7 @@ public:
virtual bool failure ();
void infoReceived (SalBodyHandler *bodyHandler);
void pingReply ();
void referred (const Address &referToAddr);
virtual void remoteRinging ();
void replaceOp (SalCallOp *newOp);
virtual void terminated ();
@ -109,10 +114,11 @@ protected:
LinphoneCallDir direction = LinphoneCallOutgoing;
LinphoneCallState state = LinphoneCallIdle;
LinphoneCallState prevState = LinphoneCallIdle;
//LinphoneCallState transferState = LinphoneCallIdle;
LinphoneCallState transferState = LinphoneCallIdle;
LinphoneProxyConfig *destProxy = nullptr;
LinphoneErrorInfo *ei = nullptr;
LinphoneCallLog *log = nullptr;
std::string referTo;
SalCallOp *op = nullptr;
@ -120,11 +126,15 @@ protected:
bool pingReplied = false;
int pingTime = 0;
std::shared_ptr<CallSession> referer;
std::shared_ptr<CallSession> transferTarget;
bool broken = false;
bool deferIncomingNotification = false;
bool deferUpdate = false;
bool needLocalIpRefresh = false;
bool nonOpError = false; /* Set when the LinphoneErrorInfo was set at higher level than sal */
bool referPending = false;
bool reinviteOnCancelResponseRequested = false;
private:

View file

@ -54,6 +54,12 @@ void CallSessionPrivate::initializeParamsAccordingToIncomingCallParams () {
currentParams->setPrivacy((LinphonePrivacyMask)op->get_privacy());
}
void CallSessionPrivate::notifyReferState () {
SalCallOp *refererOp = referer->getPrivate()->getOp();
if (refererOp)
refererOp->notify_refer_state(op);
}
void CallSessionPrivate::setState(LinphoneCallState newState, const string &message) {
L_Q();
if (state != newState){
@ -137,12 +143,23 @@ void CallSessionPrivate::setState(LinphoneCallState newState, const string &mess
linphone_call_state_to_string(prevState) << " to " << linphone_call_state_to_string(state) << ")";
}
if (listener)
listener->onCallSessionStateChanged(q->getSharedFromThis(), state, message);
listener->onCallSessionStateChanged(q->getSharedFromThis(), newState, message);
if (newState == LinphoneCallReleased)
setReleased(); /* Shall be performed after app notification */
}
}
void CallSessionPrivate::setTransferState (LinphoneCallState newState) {
L_Q();
if (newState == transferState)
return;
lInfo() << "Transfer state for CallSession [" << q << "] changed from ["
<< linphone_call_state_to_string(transferState) << "] to [" << linphone_call_state_to_string(newState) << "]";
transferState = newState;
if (listener)
listener->onCallSessionTransferStateChanged(q->getSharedFromThis(), newState);
}
void CallSessionPrivate::startIncomingNotification () {
L_Q();
if (listener)
@ -286,15 +303,10 @@ bool CallSessionPrivate::failure () {
if ((ei->reason != SalReasonNone) && listener)
listener->onPlayErrorTone(q->getSharedFromThis(), linphone_reason_from_sal(ei->reason));
}
#if 0
LinphoneCall *referer=call->referer;
if (referer){
/*notify referer of the failure*/
linphone_core_notify_refer_state(lc,referer,call);
/*schedule automatic resume of the call. This must be done only after the notifications are completed due to dialog serialization of requests.*/
linphone_core_queue_task(lc,(belle_sip_source_func_t)resume_call_after_failed_transfer,linphone_call_ref(referer),"Automatic call resuming after failed transfer");
if (referer) {
// Notify referer of the failure
notifyReferState();
}
#endif
return false;
}
@ -321,6 +333,15 @@ void CallSessionPrivate::pingReply () {
}
}
void CallSessionPrivate::referred (const Address &referToAddr) {
L_Q();
referTo = referToAddr.asString();
referPending = true;
setState(LinphoneCallRefered, "Referred");
if (referPending && listener)
listener->onCallSessionStartReferred(q->getSharedFromThis());
}
void CallSessionPrivate::remoteRinging () {
L_Q();
/* Set privacy */
@ -389,10 +410,8 @@ void CallSessionPrivate::terminated () {
default:
break;
}
#if 0
if (call->refer_pending)
linphone_core_start_refered_call(lc,call,NULL);
#endif
if (referPending && listener)
listener->onCallSessionStartReferred(q->getSharedFromThis());
if (listener)
listener->onStopRingingIfInCall(q->getSharedFromThis());
setState(LinphoneCallEnd, "Call ended");
@ -587,16 +606,9 @@ void CallSessionPrivate::setReleased () {
op->release();
op = nullptr;
}
referer = nullptr;
transferTarget = nullptr;
#if 0
/* It is necessary to reset pointers to other call to prevent circular references that would result in memory never freed */
if (call->referer){
linphone_call_unref(call->referer);
call->referer=NULL;
}
if (call->transfer_target){
linphone_call_unref(call->transfer_target);
call->transfer_target=NULL;
}
if (call->chat_room){
linphone_chat_room_unref(call->chat_room);
call->chat_room = NULL;
@ -731,10 +743,8 @@ void CallSessionPrivate::createOpTo (const LinphoneAddress *to) {
op->release();
op = new SalCallOp(q->getCore()->getCCore()->sal);
op->set_user_pointer(q);
#if 0
if (linphone_call_params_get_referer(call->params))
sal_call_set_referer(call->op,linphone_call_params_get_referer(call->params)->op);
#endif
if (params->getPrivate()->getReferer())
op->set_referer(params->getPrivate()->getReferer()->getPrivate()->getOp());
linphone_configure_op(q->getCore()->getCCore(), op, to, q->getParams()->getPrivate()->getCustomHeaders(), false);
if (q->getParams()->getPrivacy() != LinphonePrivacyDefault)
op->set_privacy((SalPrivacyMask)q->getParams()->getPrivacy());
@ -932,6 +942,8 @@ void CallSession::configure (LinphoneCallDir direction, LinphoneProxyConfig *cfg
}
if (direction == LinphoneCallOutgoing) {
if (d->params->getPrivate()->getReferer())
d->referer = d->params->getPrivate()->getReferer();
d->startPing();
} else if (direction == LinphoneCallIncoming) {
d->setParams(new CallSessionParams());
@ -987,6 +999,11 @@ LinphoneStatus CallSession::deferUpdate () {
return 0;
}
bool CallSession::hasTransferPending () {
L_D();
return d->referPending;
}
void CallSession::initiateIncoming () {}
bool CallSession::initiateOutgoing () {
@ -1134,6 +1151,26 @@ LinphoneStatus CallSession::terminate (const LinphoneErrorInfo *ei) {
return 0;
}
LinphoneStatus CallSession::transfer (const shared_ptr<CallSession> &dest) {
L_D();
int result = d->op->refer_with_replaces(dest->getPrivate()->op);
d->setTransferState(LinphoneCallOutgoingInit);
return result;
}
LinphoneStatus CallSession::transfer (const string &dest) {
L_D();
LinphoneAddress *destAddr = linphone_core_interpret_url(getCore()->getCCore(), dest.c_str());
if (!destAddr)
return -1;
char *addrStr = linphone_address_as_string(destAddr);
d->op->refer(addrStr);
bctbx_free(addrStr);
linphone_address_unref(destAddr);
d->setTransferState(LinphoneCallOutgoingInit);
return 0;
}
LinphoneStatus CallSession::update (const CallSessionParams *csp, const string &subject, const Content *content) {
L_D();
LinphoneCallState nextState;
@ -1200,6 +1237,16 @@ LinphoneReason CallSession::getReason () const {
return linphone_error_info_get_reason(getErrorInfo());
}
shared_ptr<CallSession> CallSession::getReferer () const {
L_D();
return d->referer;
}
string CallSession::getReferTo () const {
L_D();
return d->referTo;
}
const Address& CallSession::getRemoteAddress () const {
L_D();
return *L_GET_CPP_PTR_FROM_C_OBJECT((d->direction == LinphoneCallIncoming)
@ -1256,6 +1303,16 @@ const Address& CallSession::getToAddress () const {
return d->toAddress;
}
LinphoneCallState CallSession::getTransferState () const {
L_D();
return d->transferState;
}
shared_ptr<CallSession> CallSession::getTransferTarget () const {
L_D();
return d->transferTarget;
}
string CallSession::getToHeader (const string &name) const {
L_D();
return L_C_TO_STRING(sal_custom_header_find(d->op->get_recv_custom_header(), name.c_str()));

View file

@ -59,6 +59,7 @@ public:
LinphoneStatus decline (const LinphoneErrorInfo *ei);
LinphoneStatus declineNotAnswered (LinphoneReason reason);
virtual LinphoneStatus deferUpdate ();
bool hasTransferPending ();
virtual void initiateIncoming ();
virtual bool initiateOutgoing ();
virtual void iterate (time_t currentRealTime, bool oneSecondElapsed);
@ -67,6 +68,8 @@ public:
virtual void startIncomingNotification ();
virtual int startInvite (const Address *destination, const std::string &subject = "", const Content *content = nullptr);
LinphoneStatus terminate (const LinphoneErrorInfo *ei = nullptr);
LinphoneStatus transfer (const std::shared_ptr<CallSession> &dest);
LinphoneStatus transfer (const std::string &dest);
LinphoneStatus update (const CallSessionParams *csp, const std::string &subject = "", const Content *content = nullptr);
CallSessionParams *getCurrentParams () const;
@ -77,6 +80,8 @@ public:
LinphoneCallLog * getLog () const;
virtual const CallSessionParams *getParams () const;
LinphoneReason getReason () const;
std::shared_ptr<CallSession> getReferer () const;
std::string getReferTo () const;
const Address& getRemoteAddress () const;
std::string getRemoteAddressAsString () const;
std::string getRemoteContact () const;
@ -85,6 +90,8 @@ public:
std::string getRemoteUserAgent () const;
LinphoneCallState getState () const;
const Address& getToAddress () const;
LinphoneCallState getTransferState () const;
std::shared_ptr<CallSession> getTransferTarget () const;
std::string getToHeader (const std::string &name) const;
protected:

View file

@ -40,15 +40,20 @@ public:
MediaSessionPrivate () = default;
public:
static int resumeAfterFailedTransfer (void *userData, unsigned int);
static bool_t startPendingRefer (void *userData);
static void stunAuthRequestedCb (void *userData, const char *realm, const char *nonce, const char **username, const char **password, const char **ha1);
void accepted () override;
void ackReceived (LinphoneHeaders *headers) override;
void dtmfReceived (char dtmf);
bool failure () override;
void pauseForTransfer ();
void pausedByRemote ();
void remoteRinging () override;
int resumeAfterFailedTransfer ();
void resumed ();
void startPendingRefer ();
void telephoneEventReceived (int event);
void terminated () override;
void updated (bool isUpdate);

View file

@ -102,10 +102,8 @@ void MediaSessionPrivate::accepted () {
switch (state) {
case LinphoneCallResuming:
case LinphoneCallConnected:
#if 0
if (call->referer)
linphone_core_notify_refer_state(lc,call->referer,call);
#endif
if (referer)
notifyReferState();
BCTBX_NO_BREAK; /* Intentional no break */
case LinphoneCallUpdating:
case LinphoneCallUpdatedByRemote:
@ -129,10 +127,8 @@ void MediaSessionPrivate::accepted () {
* Our streams are all send-only (with music), soundcard and camera are never used. */
nextState = LinphoneCallPaused;
nextStateMsg = "Call paused";
#if 0
if (call->refer_pending)
linphone_task_list_add(&tl, (LinphoneCoreIterateHook)start_pending_refer, call);
#endif
if (referPending)
linphone_task_list_add(&tl, &MediaSessionPrivate::startPendingRefer, q);
break;
default:
lError() << "accepted(): don't know what to do in state [" << linphone_call_state_to_string(state) << "]";
@ -249,12 +245,26 @@ bool MediaSessionPrivate::failure () {
if (stop)
return true;
if (referer) {
// Schedule automatic resume of the call. This must be done only after the notifications are completed due to dialog serialization of requests
linphone_core_queue_task(q->getCore()->getCCore(),
&MediaSessionPrivate::resumeAfterFailedTransfer, referer.get(),
"Automatic CallSession resuming after failed transfer");
}
if (listener)
listener->onStopRingingIfNeeded(q->getSharedFromThis());
stopStreams();
return false;
}
void MediaSessionPrivate::pauseForTransfer () {
L_Q();
lInfo() << "Automatically pausing current MediaSession to accept transfer";
q->pause();
automaticallyPaused = true;
}
void MediaSessionPrivate::pausedByRemote () {
L_Q();
MediaSessionParams *newParams = new MediaSessionParams(*getParams());
@ -308,10 +318,31 @@ void MediaSessionPrivate::remoteRinging () {
}
}
int MediaSessionPrivate::resumeAfterFailedTransfer () {
L_Q();
if (automaticallyPaused && (state == LinphoneCallPausing))
return BELLE_SIP_CONTINUE; // Was still in pausing state
if (automaticallyPaused && (state == LinphoneCallPaused)) {
if (op->is_idle())
q->resume();
else {
lInfo() << "MediaSessionPrivate::resumeAfterFailedTransfer(), op was busy";
return BELLE_SIP_CONTINUE;
}
}
return BELLE_SIP_STOP;
}
void MediaSessionPrivate::resumed () {
acceptUpdate(nullptr, LinphoneCallStreamsRunning, "Connected (streams running)");
}
void MediaSessionPrivate::startPendingRefer () {
L_Q();
if (listener)
listener->onCallSessionStartReferred(q->getSharedFromThis());
}
void MediaSessionPrivate::telephoneEventReceived (int event) {
static char dtmfTab[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '#', 'A', 'B', 'C', 'D' };
if ((event < 0) || (event > 15)) {
@ -4035,6 +4066,17 @@ int MediaSessionPrivate::sendDtmf () {
// -----------------------------------------------------------------------------
int MediaSessionPrivate::resumeAfterFailedTransfer (void *userData, unsigned int) {
MediaSession *session = reinterpret_cast<MediaSession *>(userData);
return session->getPrivate()->resumeAfterFailedTransfer();
}
bool_t MediaSessionPrivate::startPendingRefer (void *userData) {
MediaSession *session = reinterpret_cast<MediaSession *>(userData);
session->getPrivate()->startPendingRefer();
return TRUE;
}
void MediaSessionPrivate::stunAuthRequestedCb (const char *realm, const char *nonce, const char **username, const char **password, const char **ha1) {
L_Q();
/* Get the username from the nat policy or the proxy config */
@ -4209,11 +4251,6 @@ void MediaSession::configure (LinphoneCallDir direction, LinphoneProxyConfig *cf
d->iceAgent->checkSession(IR_Controlling, false);
d->runStunTestsIfNeeded();
d->discoverMtu(to);
#if 0
if (linphone_call_params_get_referer(params)){
call->referer=linphone_call_ref(linphone_call_params_get_referer(params));
}
#endif
} else if (direction == LinphoneCallIncoming) {
d->selectIncomingIpVersion();
/* Note that the choice of IP version for streams is later refined by setCompatibleIncomingCallParams() when examining the

View file

@ -1415,7 +1415,7 @@ int SalCallOp::notify_refer_state(SalCallOp *newcall) {
if(belle_sip_dialog_get_state(this->dialog) == BELLE_SIP_DIALOG_TERMINATED){
return 0;
}
state = this->dialog?belle_sip_dialog_get_state(this->dialog):BELLE_SIP_DIALOG_NULL;
state = newcall->dialog?belle_sip_dialog_get_state(newcall->dialog):BELLE_SIP_DIALOG_NULL;
switch(state) {
case BELLE_SIP_DIALOG_EARLY:
send_notify_for_refer(100, "Trying");