forked from mirrors/linphone-iphone
214 lines
6.1 KiB
C++
214 lines
6.1 KiB
C++
/*
|
|
* core-call.cpp
|
|
* 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.
|
|
*/
|
|
|
|
#include <algorithm>
|
|
|
|
#include "core-p.h"
|
|
#include "call/call-p.h"
|
|
#include "conference/session/call-session-p.h"
|
|
#include "logger/logger.h"
|
|
|
|
// TODO: Remove me later.
|
|
#include "c-wrapper/c-wrapper.h"
|
|
|
|
// =============================================================================
|
|
|
|
using namespace std;
|
|
|
|
LINPHONE_BEGIN_NAMESPACE
|
|
|
|
int CorePrivate::addCall (const shared_ptr<Call> &call) {
|
|
L_Q();
|
|
L_ASSERT(call);
|
|
if (!canWeAddCall())
|
|
return -1;
|
|
if (!hasCalls())
|
|
notifySoundcardUsage(true);
|
|
calls.push_back(call);
|
|
linphone_core_notify_call_created(q->getCCore(), L_GET_C_BACK_PTR(call));
|
|
return 0;
|
|
}
|
|
|
|
bool CorePrivate::canWeAddCall () const {
|
|
L_Q();
|
|
if (q->getCallCount() < static_cast<unsigned int>(q->getCCore()->max_calls))
|
|
return true;
|
|
lInfo() << "Maximum amount of simultaneous calls reached!";
|
|
return false;
|
|
}
|
|
|
|
bool CorePrivate::inviteReplacesABrokenCall (SalCallOp *op) {
|
|
CallSession *replacedSession = nullptr;
|
|
SalCallOp *replacedOp = op->get_replaces();
|
|
if (replacedOp)
|
|
replacedSession = reinterpret_cast<CallSession *>(replacedOp->get_user_pointer());
|
|
for (const auto &call : calls) {
|
|
shared_ptr<CallSession> session = call->getPrivate()->getActiveSession();
|
|
if (session
|
|
&& ((session->getPrivate()->isBroken() && op->compare_op(session->getPrivate()->getOp()))
|
|
|| ((replacedSession == session.get())
|
|
&& (strcmp(op->get_from(), replacedOp->get_from()) == 0)
|
|
&& (strcmp(op->get_to(), replacedOp->get_to()) == 0)))
|
|
) {
|
|
session->getPrivate()->replaceOp(op);
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
bool CorePrivate::isAlreadyInCallWithAddress (const Address &addr) const {
|
|
for (const auto &call : calls) {
|
|
if (call->getRemoteAddress().weakEqual(addr))
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void CorePrivate::iterateCalls (time_t currentRealTime, bool oneSecondElapsed) const {
|
|
for (const auto &call : calls) {
|
|
call->getPrivate()->iterate(currentRealTime, oneSecondElapsed);
|
|
}
|
|
}
|
|
|
|
void CorePrivate::notifySoundcardUsage (bool used) {
|
|
L_Q();
|
|
MSSndCard *card = q->getCCore()->sound_conf.capt_sndcard;
|
|
if (card && (ms_snd_card_get_capabilities(card) & MS_SND_CARD_CAP_IS_SLOW))
|
|
ms_snd_card_set_usage_hint(card, used);
|
|
}
|
|
|
|
int CorePrivate::removeCall (const shared_ptr<Call> &call) {
|
|
L_ASSERT(call);
|
|
auto iter = find(calls.begin(), calls.end(), call);
|
|
if (iter == calls.end()) {
|
|
lWarning() << "Could not find the call to remove";
|
|
return -1;
|
|
}
|
|
calls.erase(iter);
|
|
return 0;
|
|
}
|
|
|
|
void CorePrivate::unsetVideoWindowId (bool preview, void *id) {
|
|
#ifdef VIDEO_ENABLED
|
|
for (const auto &call : calls) {
|
|
VideoStream *vstream = reinterpret_cast<VideoStream *>(call->getPrivate()->getMediaStream(LinphoneStreamTypeVideo));
|
|
if (vstream) {
|
|
if (preview)
|
|
video_stream_set_native_preview_window_id(vstream, id);
|
|
else
|
|
video_stream_set_native_window_id(vstream, id);
|
|
}
|
|
}
|
|
#endif
|
|
}
|
|
|
|
// =============================================================================
|
|
|
|
bool Core::areSoundResourcesLocked () const {
|
|
L_D();
|
|
for (const auto &call : d->calls) {
|
|
if (call->mediaInProgress())
|
|
return true;
|
|
switch (call->getState()) {
|
|
case LinphoneCallOutgoingInit:
|
|
case LinphoneCallOutgoingProgress:
|
|
case LinphoneCallOutgoingRinging:
|
|
case LinphoneCallOutgoingEarlyMedia:
|
|
case LinphoneCallConnected:
|
|
case LinphoneCallRefered:
|
|
case LinphoneCallIncomingEarlyMedia:
|
|
case LinphoneCallUpdating:
|
|
lInfo() << "Call " << call << " is locking sound resources";
|
|
return true;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
shared_ptr<Call> Core::getCallByRemoteAddress (const Address &addr) const {
|
|
L_D();
|
|
for (const auto &call : d->calls) {
|
|
if (call->getRemoteAddress().weakEqual(addr))
|
|
return call;
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
const list<shared_ptr<Call>> &Core::getCalls () const {
|
|
L_D();
|
|
return d->calls;
|
|
}
|
|
|
|
unsigned int Core::getCallCount () const {
|
|
L_D();
|
|
return static_cast<unsigned int>(d->calls.size());
|
|
}
|
|
|
|
shared_ptr<Call> Core::getCurrentCall () const {
|
|
L_D();
|
|
return d->currentCall;
|
|
}
|
|
|
|
LinphoneStatus Core::pauseAllCalls () {
|
|
L_D();
|
|
for (const auto &call : d->calls) {
|
|
if ((call->getState() == LinphoneCallStreamsRunning) || (call->getState() == LinphoneCallPausedByRemote))
|
|
call->pause();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void Core::soundcardHintCheck () {
|
|
L_D();
|
|
bool noNeedForSound = true;
|
|
// Check if the remaining calls are paused
|
|
for (const auto &call : d->calls) {
|
|
if ((call->getState() != LinphoneCallPausing)
|
|
&& (call->getState() != LinphoneCallPaused)
|
|
&& (call->getState() != LinphoneCallEnd)
|
|
&& (call->getState() != LinphoneCallError)) {
|
|
noNeedForSound = false;
|
|
break;
|
|
}
|
|
}
|
|
// If no more calls or all calls are paused, we can free the soundcard
|
|
LinphoneConfig *config = linphone_core_get_config(L_GET_C_BACK_PTR(this));
|
|
bool useRtpIo = !!lp_config_get_int(config, "sound", "rtp_io", FALSE);
|
|
bool useRtpIoEnableLocalOutput = !!lp_config_get_int(config, "sound", "rtp_io_enable_local_output", FALSE);
|
|
bool useFiles = L_GET_C_BACK_PTR(getSharedFromThis())->use_files;
|
|
if ((!d->hasCalls() || noNeedForSound)
|
|
&& (!useFiles && (!useRtpIo || (useRtpIo && useRtpIoEnableLocalOutput)))) {
|
|
lInfo() << "Notifying soundcard that we don't need it anymore for calls";
|
|
d->notifySoundcardUsage(false);
|
|
}
|
|
}
|
|
|
|
LinphoneStatus Core::terminateAllCalls () {
|
|
L_D();
|
|
while (!d->calls.empty()) {
|
|
d->calls.front()->terminate();
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
LINPHONE_END_NAMESPACE
|