call.cpp 29.5 KB
Newer Older
1 2
/*
 * call.cpp
Ronan's avatar
Ronan committed
3
 * Copyright (C) 2010-2018 Belledonne Communications SARL
4
 *
Ghislain MARY's avatar
Ghislain MARY committed
5 6 7 8
 * 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.
9 10 11 12 13 14 15
 *
 * 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
Ghislain MARY's avatar
Ghislain MARY committed
16 17
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 19
 */

Ghislain MARY's avatar
Ghislain MARY committed
20
#include "c-wrapper/c-wrapper.h"
21
#include "call-p.h"
Ghislain MARY's avatar
Ghislain MARY committed
22
#include "chat/chat-room/real-time-text-chat-room-p.h"
23
#include "conference/params/media-session-params-p.h"
24
#include "conference/session/call-session-p.h"
25
#include "conference/session/media-session-p.h"
26
#include "core/core-p.h"
27
#include "logger/logger.h"
28

Ghislain MARY's avatar
Ghislain MARY committed
29 30
#include "conference_private.h"

31
// =============================================================================
32 33 34

using namespace std;

35
LINPHONE_BEGIN_NAMESPACE
36

37
bool CallPrivate::getAudioMuted () const {
Ronan's avatar
Ronan committed
38
	return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getAudioMuted();
39 40
}

Ghislain MARY's avatar
Ghislain MARY committed
41 42 43 44 45 46 47 48 49 50 51
shared_ptr<RealTimeTextChatRoom> CallPrivate::getChatRoom () {
	L_Q();
	if (!chatRoom && (q->getState() != CallSession::State::End) && (q->getState() != CallSession::State::Released)) {
		ChatRoomId chatRoomId(q->getRemoteAddress(), q->getLocalAddress());
		RealTimeTextChatRoom *rttcr = new RealTimeTextChatRoom(q->getCore(), chatRoomId);
		chatRoom.reset(rttcr);
		rttcr->getPrivate()->setCall(q->getSharedFromThis());
	}
	return chatRoom;
}

Ronan's avatar
Ronan committed
52
LinphoneProxyConfig *CallPrivate::getDestProxy () const {
53 54 55
	return getActiveSession()->getPrivate()->getDestProxy();
}

Ronan's avatar
Ronan committed
56
IceSession *CallPrivate::getIceSession () const {
Ronan's avatar
Ronan committed
57
	return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getIceSession();
58 59
}

60 61 62 63
unsigned int CallPrivate::getMediaStartCount () const {
	return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getMediaStartCount();
}

Ronan's avatar
Ronan committed
64
MediaStream *CallPrivate::getMediaStream (LinphoneStreamType type) const {
Ronan's avatar
Ronan committed
65
	return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getMediaStream(type);
66 67
}

68
SalCallOp * CallPrivate::getOp () const {
69 70 71 72
	return getActiveSession()->getPrivate()->getOp();
}

void CallPrivate::setAudioMuted (bool value) {
Ronan's avatar
Ronan committed
73
	static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->setAudioMuted(value);
74 75
}

76 77 78 79
LinphoneCallStats *CallPrivate::getStats (LinphoneStreamType type) const {
	return static_pointer_cast<const MediaSession>(getActiveSession())->getPrivate()->getStats(type);
}

80 81 82 83 84 85 86
// -----------------------------------------------------------------------------

void CallPrivate::initiateIncoming () {
	getActiveSession()->initiateIncoming();
}

bool CallPrivate::initiateOutgoing () {
Ghislain MARY's avatar
Ghislain MARY committed
87 88 89 90
	shared_ptr<CallSession> session = getActiveSession();
	bool defer = session->initiateOutgoing();
	session->getPrivate()->createOp();
	return defer;
91 92 93 94 95 96 97 98 99 100
}

void CallPrivate::iterate (time_t currentRealTime, bool oneSecondElapsed) {
	getActiveSession()->iterate(currentRealTime, oneSecondElapsed);
}

void CallPrivate::startIncomingNotification () {
	getActiveSession()->startIncomingNotification();
}

101 102 103 104
void CallPrivate::pauseForTransfer () {
	static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->pauseForTransfer();
}

105
int CallPrivate::startInvite (const Address *destination) {
106
	return getActiveSession()->startInvite(destination, "");
107 108
}

109 110
shared_ptr<Call> CallPrivate::startReferredCall (const MediaSessionParams *params) {
	L_Q();
111
	if (q->getState() != CallSession::State::Paused) {
112 113 114 115 116 117 118 119 120 121 122 123 124
		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);
Ghislain MARY's avatar
Ghislain MARY committed
125 126 127
	LinphoneCallParams *lcp = L_GET_C_BACK_PTR(&msp);
	LinphoneCall *newCall = linphone_core_invite_with_params(q->getCore()->getCCore(), q->getReferTo().c_str(), lcp);
	linphone_call_params_unref(lcp);
128 129 130 131 132 133 134
	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);
}

135 136
// -----------------------------------------------------------------------------

137 138 139 140 141 142 143
void CallPrivate::createPlayer () const {
	L_Q();
	player = linphone_call_build_player(L_GET_C_BACK_PTR(q));
}

// -----------------------------------------------------------------------------

Ghislain MARY's avatar
Ghislain MARY committed
144 145 146 147 148 149 150 151 152 153
void CallPrivate::initializeMediaStreams () {
	static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->initializeStreams();
}

void CallPrivate::stopMediaStreams () {
	static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->stopStreams();
}

// -----------------------------------------------------------------------------

154 155 156
void CallPrivate::resetFirstVideoFrameDecoded () {
#ifdef VIDEO_ENABLED
	if (nextVideoFrameDecoded._func)
Ghislain MARY's avatar
Ghislain MARY committed
157
		static_pointer_cast<MediaSession>(getActiveSession())->resetFirstVideoFrameDecoded();
158 159 160
#endif // ifdef VIDEO_ENABLED
}

161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
void CallPrivate::startRemoteRing () {
	L_Q();
	LinphoneCore *lc = q->getCore()->getCCore();
	if (!lc->sound_conf.play_sndcard)
		return;

	MSSndCard *ringCard = lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.play_sndcard;
	int maxRate = static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getLocalDesc()->streams[0].max_rate;
	if (maxRate > 0)
		ms_snd_card_set_preferred_sample_rate(ringCard, maxRate);
	// We release sound before playing ringback tone
	AudioStream *as = reinterpret_cast<AudioStream *>(getMediaStream(LinphoneStreamTypeAudio));
	if (as)
		audio_stream_unprepare_sound(as);
	if (lc->sound_conf.remote_ring) {
		lc->ringstream = ring_start(lc->factory, lc->sound_conf.remote_ring, 2000, ringCard);
	}
}

void CallPrivate::terminateBecauseOfLostMedia () {
	L_Q();
Ghislain MARY's avatar
Ghislain MARY committed
182
	lInfo() << "Call [" << q << "]: Media connectivity with " << q->getRemoteAddress().asString()
183 184 185 186 187 188 189
		<< " is lost, call is going to be terminated";
	static_pointer_cast<MediaSession>(getActiveSession())->terminateBecauseOfLostMedia();
	linphone_core_play_named_tone(q->getCore()->getCCore(), LinphoneToneCallLost);
}

// -----------------------------------------------------------------------------

190
void CallPrivate::onAckBeingSent (const shared_ptr<CallSession> &session, LinphoneHeaders *headers) {
191 192
	L_Q();
	linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, false);
193 194
}

195
void CallPrivate::onAckReceived (const shared_ptr<CallSession> &session, LinphoneHeaders *headers) {
196 197
	L_Q();
	linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, true);
198 199
}

200
void CallPrivate::onBackgroundTaskToBeStarted (const shared_ptr<CallSession> &session) {
201
	bgTask.start();
202 203
}

204
void CallPrivate::onBackgroundTaskToBeStopped (const shared_ptr<CallSession> &session) {
205
	bgTask.stop();
206 207
}

208
bool CallPrivate::onCallSessionAccepted (const shared_ptr<CallSession> &session) {
209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
	L_Q();
	LinphoneCore *lc = q->getCore()->getCCore();
	bool wasRinging = false;

	if (q->getCore()->getCurrentCall() != q->getSharedFromThis())
		linphone_core_preempt_sound_resources(lc);

	// Stop ringing
	if (linphone_ringtoneplayer_is_started(lc->ringtoneplayer)) {
		lInfo() << "Stop ringing";
		linphone_core_stop_ringing(lc);
		wasRinging = true;
	}
	if (ringingBeep) {
		linphone_core_stop_dtmf(lc);
		ringingBeep = false;
	}
	return wasRinging;
}

229
void CallPrivate::onCallSessionConferenceStreamStarting (const shared_ptr<CallSession> &session, bool mute) {
Ghislain MARY's avatar
Ghislain MARY committed
230 231 232 233 234 235
	L_Q();
	if (q->getCore()->getCCore()->conf_ctx) {
		linphone_conference_on_call_stream_starting(q->getCore()->getCCore()->conf_ctx, L_GET_C_BACK_PTR(q), mute);
	}
}

236
void CallPrivate::onCallSessionConferenceStreamStopping (const shared_ptr<CallSession> &session) {
Ghislain MARY's avatar
Ghislain MARY committed
237 238 239 240 241 242
	L_Q();
	LinphoneCore *lc = q->getCore()->getCCore();
	if (lc->conf_ctx && _linphone_call_get_endpoint(L_GET_C_BACK_PTR(q)))
		linphone_conference_on_call_stream_stopping(lc->conf_ctx, L_GET_C_BACK_PTR(q));
}

243
void CallPrivate::onCallSessionEarlyFailed (const shared_ptr<CallSession> &session, LinphoneErrorInfo *ei) {
Ghislain MARY's avatar
Ghislain MARY committed
244 245 246 247 248 249 250 251 252 253
	L_Q();
	LinphoneCallLog *log = session->getLog();
	linphone_core_report_early_failed_call(q->getCore()->getCCore(),
		linphone_call_log_get_dir(log),
		linphone_address_clone(linphone_call_log_get_from(log)),
		linphone_address_clone(linphone_call_log_get_to(log)),
		ei);
	linphone_call_unref(L_GET_C_BACK_PTR(q));
}

254
void CallPrivate::onCallSessionSetReleased (const shared_ptr<CallSession> &session) {
255 256
	L_Q();
	linphone_call_unref(L_GET_C_BACK_PTR(q));
257 258
}

259
void CallPrivate::onCallSessionSetTerminated (const shared_ptr<CallSession> &session) {
260 261
	L_Q();
	LinphoneCore *core = q->getCore()->getCCore();
262 263 264 265 266 267 268
	if (q->getSharedFromThis() == q->getCore()->getCurrentCall()) {
		lInfo() << "Resetting the current call";
		q->getCore()->getPrivate()->setCurrentCall(nullptr);
	}
	if (q->getCore()->getPrivate()->removeCall(q->getSharedFromThis()) != 0)
		lError() << "Could not remove the call from the list!!!";
	if (core->conf_ctx)
Ghislain MARY's avatar
Ghislain MARY committed
269
		linphone_conference_on_call_terminating(core->conf_ctx, L_GET_C_BACK_PTR(q));
270
	if (ringingBeep) {
271
		linphone_core_stop_dtmf(core);
272
		ringingBeep = false;
273
	}
274
#if 0
275 276 277 278 279
	if (lcall->chat_room)
		linphone_chat_room_set_call(lcall->chat_room, nullptr);
#endif // if 0
	if (!q->getCore()->getPrivate()->hasCalls())
		ms_bandwidth_controller_reset_state(core->bw_controller);
280 281
}

282
void CallPrivate::onCallSessionStartReferred (const shared_ptr<CallSession> &session) {
283 284 285
	startReferredCall(nullptr);
}

286
void CallPrivate::onCallSessionStateChanged (const shared_ptr<CallSession> &session, CallSession::State state, const string &message) {
287
	L_Q();
288 289 290 291 292 293 294 295 296 297 298 299 300 301 302
	switch(state){
		case CallSession::State::OutgoingInit:
		case CallSession::State::IncomingReceived:
			getPlatformHelpers(q->getCore()->getCCore())->acquireWifiLock();
			getPlatformHelpers(q->getCore()->getCCore())->acquireMcastLock();
			getPlatformHelpers(q->getCore()->getCCore())->acquireCpuLock();
			break;
		case CallSession::State::Released:
			getPlatformHelpers(q->getCore()->getCCore())->releaseWifiLock();
			getPlatformHelpers(q->getCore()->getCCore())->releaseMcastLock();
			getPlatformHelpers(q->getCore()->getCCore())->releaseCpuLock();
			break;
		default:
			break;
	}
303
	linphone_call_notify_state_changed(L_GET_C_BACK_PTR(q), static_cast<LinphoneCallState>(state), message.c_str());
304 305
}

306
void CallPrivate::onCallSessionTransferStateChanged (const shared_ptr<CallSession> &session, CallSession::State state) {
307
	L_Q();
308
	linphone_call_notify_transfer_state_changed(L_GET_C_BACK_PTR(q), static_cast<LinphoneCallState>(state));
309 310
}

311
void CallPrivate::onCheckForAcceptation (const shared_ptr<CallSession> &session) {
312 313 314
	L_Q();
	LinphoneCall *lcall = L_GET_C_BACK_PTR(q);
	bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_calls(q->getCore()->getCCore()));
315 316 317
	for (bctbx_list_t *it = copy; it != nullptr; it = bctbx_list_next(it)) {
		LinphoneCall *call = reinterpret_cast<LinphoneCall *>(bctbx_list_get_data(it));
		if (call == lcall) continue;
318 319 320 321 322
		switch (L_GET_CPP_PTR_FROM_C_OBJECT(call)->getState()) {
			case CallSession::State::OutgoingInit:
			case CallSession::State::OutgoingProgress:
			case CallSession::State::OutgoingRinging:
			case CallSession::State::OutgoingEarlyMedia:
Ronan's avatar
Ronan committed
323 324
				lInfo() << "Already existing call [" << call << "] in state [" << linphone_call_state_to_string(linphone_call_get_state(call)) <<
					"], canceling it before accepting new call [" << lcall << "]";
325 326 327 328 329 330 331 332 333
				linphone_call_terminate(call);
				break;
			default:
				break; /* Nothing to do */
		}
	}
	bctbx_list_free(copy);
}

334
void CallPrivate::onDtmfReceived (const shared_ptr<CallSession> &session, char dtmf) {
Ghislain MARY's avatar
Ghislain MARY committed
335 336 337 338
	L_Q();
	linphone_call_notify_dtmf_received(L_GET_C_BACK_PTR(q), dtmf);
}

339
void CallPrivate::onIncomingCallSessionNotified (const shared_ptr<CallSession> &session) {
340 341 342 343 344
	L_Q();
	/* The call is acceptable so we can now add it to our list */
	q->getCore()->getPrivate()->addCall(q->getSharedFromThis());
}

345
void CallPrivate::onIncomingCallSessionStarted (const shared_ptr<CallSession> &session) {
346 347
	L_Q();
	linphone_core_notify_incoming_call(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q));
348 349
}

350
void CallPrivate::onIncomingCallSessionTimeoutCheck (const shared_ptr<CallSession> &session, int elapsed, bool oneSecondElapsed) {
351
	L_Q();
352 353 354 355 356 357 358 359
	if (oneSecondElapsed)
		lInfo() << "Incoming call ringing for " << elapsed << " seconds";
	if (elapsed > q->getCore()->getCCore()->sip_conf.inc_timeout) {
		lInfo() << "Incoming call timeout (" << q->getCore()->getCCore()->sip_conf.inc_timeout << ")";
		LinphoneReason declineReason = (q->getCore()->getCurrentCall() != q->getSharedFromThis())
			? LinphoneReasonBusy : LinphoneReasonDeclined;
		getActiveSession()->declineNotAnswered(declineReason);
	}
360 361
}

362
void CallPrivate::onInfoReceived (const shared_ptr<CallSession> &session, const LinphoneInfoMessage *im) {
363 364
	L_Q();
	linphone_call_notify_info_message_received(L_GET_C_BACK_PTR(q), im);
365 366
}

367
void CallPrivate::onNoMediaTimeoutCheck (const shared_ptr<CallSession> &session, bool oneSecondElapsed) {
368 369 370 371
	L_Q();
	int disconnectTimeout = linphone_core_get_nortp_timeout(q->getCore()->getCCore());
	bool disconnected = false;
	AudioStream *as = reinterpret_cast<AudioStream *>(getMediaStream(LinphoneStreamTypeAudio));
372
	if (((q->getState() == CallSession::State::StreamsRunning) || (q->getState() == CallSession::State::PausedByRemote))
373 374 375 376 377 378
		&& oneSecondElapsed && as && (as->ms.state == MSStreamStarted) && (disconnectTimeout > 0))
		disconnected = !audio_stream_alive(as, disconnectTimeout);
	if (disconnected)
		terminateBecauseOfLostMedia();
}

379
void CallPrivate::onEncryptionChanged (const shared_ptr<CallSession> &session, bool activated, const string &authToken) {
380 381
	L_Q();
	linphone_call_notify_encryption_changed(L_GET_C_BACK_PTR(q), activated, authToken.empty() ? nullptr : authToken.c_str());
382 383
}

384
void CallPrivate::onCallSessionStateChangedForReporting (const shared_ptr<CallSession> &session) {
Ghislain MARY's avatar
Ghislain MARY committed
385 386 387 388
	L_Q();
	linphone_reporting_call_state_updated(L_GET_C_BACK_PTR(q));
}

389
void CallPrivate::onRtcpUpdateForReporting (const shared_ptr<CallSession> &session, SalStreamType type) {
Ghislain MARY's avatar
Ghislain MARY committed
390 391 392 393
	L_Q();
	linphone_reporting_on_rtcp_update(L_GET_C_BACK_PTR(q), type);
}

394
void CallPrivate::onStatsUpdated (const shared_ptr<CallSession> &session, const LinphoneCallStats *stats) {
395 396
	L_Q();
	linphone_call_notify_stats_updated(L_GET_C_BACK_PTR(q), stats);
397 398
}

399
void CallPrivate::onUpdateMediaInfoForReporting (const shared_ptr<CallSession> &session, int statsType) {
Ghislain MARY's avatar
Ghislain MARY committed
400 401 402 403
	L_Q();
	linphone_reporting_update_media_info(L_GET_C_BACK_PTR(q), statsType);
}

404
void CallPrivate::onResetCurrentSession (const shared_ptr<CallSession> &session) {
405
	L_Q();
406
	q->getCore()->getPrivate()->setCurrentCall(nullptr);
407 408
}

409
void CallPrivate::onSetCurrentSession (const shared_ptr<CallSession> &session) {
410
	L_Q();
411
	q->getCore()->getPrivate()->setCurrentCall(q->getSharedFromThis());
412 413
}

414
void CallPrivate::onFirstVideoFrameDecoded (const shared_ptr<CallSession> &session) {
415 416 417
	L_Q();
	if (nextVideoFrameDecoded._func) {
		nextVideoFrameDecoded._func(L_GET_C_BACK_PTR(q), nextVideoFrameDecoded._user_data);
418 419 420 421 422
		nextVideoFrameDecoded._func = nullptr;
		nextVideoFrameDecoded._user_data = nullptr;
	}
}

423
void CallPrivate::onResetFirstVideoFrameDecoded (const shared_ptr<CallSession> &session) {
424
	resetFirstVideoFrameDecoded();
425
}
426

427
void CallPrivate::onPlayErrorTone (const shared_ptr<CallSession> &session, LinphoneReason reason) {
428 429 430 431
	L_Q();
	linphone_core_play_call_error_tone(q->getCore()->getCCore(), reason);
}

432
void CallPrivate::onRingbackToneRequested (const shared_ptr<CallSession> &session, bool requested) {
433 434 435 436 437 438 439
	L_Q();
	if (requested && linphone_core_get_remote_ringback_tone(q->getCore()->getCCore()))
		playingRingbackTone = true;
	else if (!requested)
		playingRingbackTone = false;
}

440
void CallPrivate::onStartRinging (const shared_ptr<CallSession> &session) {
441 442 443 444 445 446 447
	L_Q();
	LinphoneCore *lc = q->getCore()->getCCore();
	if (lc->ringstream)
		return; // Already ringing!
	startRemoteRing();
}

448
void CallPrivate::onStopRinging (const shared_ptr<CallSession> &session) {
449 450 451 452
	L_Q();
	linphone_core_stop_ringing(q->getCore()->getCCore());
}

453
void CallPrivate::onStopRingingIfInCall (const shared_ptr<CallSession> &session) {
454 455 456 457 458 459 460 461
	L_Q();
	LinphoneCore *lc = q->getCore()->getCCore();
	// We stop the ring only if we have this current call or if we are in call
	if ((q->getCore()->getCallCount() == 1) || linphone_core_in_call(lc)) {
		linphone_core_stop_ringing(lc);
	}
}

462
void CallPrivate::onStopRingingIfNeeded (const shared_ptr<CallSession> &session) {
463 464 465 466 467
	L_Q();
	LinphoneCore *lc = q->getCore()->getCCore();
	bool stopRinging = true;
	bool ringDuringEarlyMedia = linphone_core_get_ring_during_incoming_early_media(lc);
	for (const auto &call : q->getCore()->getCalls()) {
468 469
		if ((call->getState() == CallSession::State::IncomingReceived)
			|| (ringDuringEarlyMedia && call->getState() == CallSession::State::IncomingEarlyMedia)) {
470 471 472 473 474 475 476 477
			stopRinging = false;
			break;
		}
	}
	if (stopRinging)
		linphone_core_stop_ringing(lc);
}

478
bool CallPrivate::areSoundResourcesAvailable (const shared_ptr<CallSession> &session) {
Ghislain MARY's avatar
Ghislain MARY committed
479 480 481 482 483 484
	L_Q();
	LinphoneCore *lc = q->getCore()->getCCore();
	shared_ptr<Call> currentCall = q->getCore()->getCurrentCall();
	return !linphone_core_is_in_conference(lc) && (!currentCall || (currentCall == q->getSharedFromThis()));
}

485
bool CallPrivate::isPlayingRingbackTone (const shared_ptr<CallSession> &session) {
486 487 488
	return playingRingbackTone;
}

489
void CallPrivate::onRealTimeTextCharacterReceived (const shared_ptr<CallSession> &session, RealtimeTextReceivedCharacter *data) {
Ghislain MARY's avatar
Ghislain MARY committed
490 491 492 493
	L_Q();
	getChatRoom()->getPrivate()->realtimeTextReceived(data->character, q->getSharedFromThis());
}

494 495
// =============================================================================

496 497 498 499
Call::Call (CallPrivate &p, shared_ptr<Core> core) : Object(p), CoreAccessor(core) {
	L_D();
	d->nextVideoFrameDecoded._func = nullptr;
	d->nextVideoFrameDecoded._user_data = nullptr;
500 501

	d->bgTask.setName("Liblinphone call notification");
502 503 504 505
}

// -----------------------------------------------------------------------------

506
LinphoneStatus Call::accept (const MediaSessionParams *msp) {
507
	L_D();
508
	return static_pointer_cast<MediaSession>(d->getActiveSession())->accept(msp);
509 510
}

511
LinphoneStatus Call::acceptEarlyMedia (const MediaSessionParams *msp) {
512
	L_D();
513
	return static_pointer_cast<MediaSession>(d->getActiveSession())->acceptEarlyMedia(msp);
514 515
}

516
LinphoneStatus Call::acceptUpdate (const MediaSessionParams *msp) {
517
	L_D();
518
	return static_pointer_cast<MediaSession>(d->getActiveSession())->acceptUpdate(msp);
519 520
}

Ghislain MARY's avatar
Ghislain MARY committed
521 522 523 524 525
void Call::cancelDtmfs () {
	L_D();
	static_pointer_cast<MediaSession>(d->getActiveSession())->cancelDtmfs();
}

526
LinphoneStatus Call::decline (LinphoneReason reason) {
527
	L_D();
528 529 530 531
	return d->getActiveSession()->decline(reason);
}

LinphoneStatus Call::decline (const LinphoneErrorInfo *ei) {
532
	L_D();
533 534 535
	return d->getActiveSession()->decline(ei);
}

536 537 538 539 540
LinphoneStatus Call::deferUpdate () {
	L_D();
	return d->getActiveSession()->deferUpdate();
}

541 542 543 544 545
bool Call::hasTransferPending () const {
	L_D();
	return d->getActiveSession()->hasTransferPending();
}

Ghislain MARY's avatar
Ghislain MARY committed
546 547 548 549 550
void Call::oglRender () const {
	L_D();
	static_pointer_cast<MediaSession>(d->getActiveSession())->getPrivate()->oglRender();
}

551
LinphoneStatus Call::pause () {
552
	L_D();
553
	return static_pointer_cast<MediaSession>(d->getActiveSession())->pause();
554 555
}

556
LinphoneStatus Call::redirect (const string &redirectUri) {
557 558 559 560
	L_D();
	return d->getActiveSession()->redirect(redirectUri);
}

561
LinphoneStatus Call::resume () {
562
	L_D();
563
	return static_pointer_cast<MediaSession>(d->getActiveSession())->resume();
564 565
}

Ghislain MARY's avatar
Ghislain MARY committed
566 567 568 569 570
LinphoneStatus Call::sendDtmf (char dtmf) {
	L_D();
	return static_pointer_cast<MediaSession>(d->getActiveSession())->sendDtmf(dtmf);
}

571
LinphoneStatus Call::sendDtmfs (const string &dtmfs) {
Ghislain MARY's avatar
Ghislain MARY committed
572 573 574 575
	L_D();
	return static_pointer_cast<MediaSession>(d->getActiveSession())->sendDtmfs(dtmfs);
}

576
void Call::sendVfuRequest () {
577
	L_D();
578
	static_pointer_cast<MediaSession>(d->getActiveSession())->sendVfuRequest();
579 580 581
}

void Call::startRecording () {
582
	L_D();
583
	static_pointer_cast<MediaSession>(d->getActiveSession())->startRecording();
584 585 586
}

void Call::stopRecording () {
587
	L_D();
588
	static_pointer_cast<MediaSession>(d->getActiveSession())->stopRecording();
589 590
}

Ronan's avatar
Ronan committed
591
LinphoneStatus Call::takePreviewSnapshot (const string &file) {
592
	L_D();
593
	return static_pointer_cast<MediaSession>(d->getActiveSession())->takePreviewSnapshot(file);
594 595
}

Ronan's avatar
Ronan committed
596
LinphoneStatus Call::takeVideoSnapshot (const string &file) {
597
	L_D();
598
	return static_pointer_cast<MediaSession>(d->getActiveSession())->takeVideoSnapshot(file);
599 600 601
}

LinphoneStatus Call::terminate (const LinphoneErrorInfo *ei) {
602
	L_D();
603 604 605
	return d->getActiveSession()->terminate(ei);
}

606 607 608 609 610 611 612 613 614 615
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);
}

616
LinphoneStatus Call::update (const MediaSessionParams *msp) {
617
	L_D();
618
	return static_pointer_cast<MediaSession>(d->getActiveSession())->update(msp);
619 620 621
}

void Call::zoomVideo (float zoomFactor, float *cx, float *cy) {
622 623 624 625
	zoomVideo(zoomFactor, *cx, *cy);
}

void Call::zoomVideo (float zoomFactor, float cx, float cy) {
626
	L_D();
627
	static_pointer_cast<MediaSession>(d->getActiveSession())->zoomVideo(zoomFactor, cx, cy);
628 629 630 631
}

// -----------------------------------------------------------------------------

632
bool Call::cameraEnabled () const {
633
	L_D();
634
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->cameraEnabled();
635 636 637
}

bool Call::echoCancellationEnabled () const {
638
	L_D();
639
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->echoCancellationEnabled();
640 641 642
}

bool Call::echoLimiterEnabled () const {
643
	L_D();
644
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->echoLimiterEnabled();
645 646 647
}

void Call::enableCamera (bool value) {
648
	L_D();
649
	static_pointer_cast<MediaSession>(d->getActiveSession())->enableCamera(value);
650
}
651 652

void Call::enableEchoCancellation (bool value) {
653
	L_D();
654
	static_pointer_cast<MediaSession>(d->getActiveSession())->enableEchoCancellation(value);
655 656 657
}

void Call::enableEchoLimiter (bool value) {
658
	L_D();
659
	static_pointer_cast<MediaSession>(d->getActiveSession())->enableEchoLimiter(value);
660 661 662
}

bool Call::getAllMuted () const {
663
	L_D();
664
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getAllMuted();
665 666
}

Ronan's avatar
Ronan committed
667
LinphoneCallStats *Call::getAudioStats () const {
668
	L_D();
669
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getAudioStats();
670 671 672
}

string Call::getAuthenticationToken () const {
673
	L_D();
674
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getAuthenticationToken();
675 676 677
}

bool Call::getAuthenticationTokenVerified () const {
678
	L_D();
679
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getAuthenticationTokenVerified();
680 681 682
}

float Call::getAverageQuality () const {
683
	L_D();
684
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getAverageQuality();
685 686
}

Ronan's avatar
Ronan committed
687
const MediaSessionParams *Call::getCurrentParams () const {
688
	L_D();
689
	return static_pointer_cast<MediaSession>(d->getActiveSession())->getCurrentParams();
690 691 692
}

float Call::getCurrentQuality () const {
693
	L_D();
694
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getCurrentQuality();
695 696 697
}

LinphoneCallDir Call::getDirection () const {
698
	L_D();
699 700 701
	return d->getActiveSession()->getDirection();
}

702 703 704 705 706
const Address &Call::getDiversionAddress () const {
	L_D();
	return d->getActiveSession()->getDiversionAddress();
}

707
int Call::getDuration () const {
708
	L_D();
709 710 711
	return d->getActiveSession()->getDuration();
}

Ronan's avatar
Ronan committed
712
const LinphoneErrorInfo *Call::getErrorInfo () const {
713
	L_D();
714 715 716
	return d->getActiveSession()->getErrorInfo();
}

Ghislain MARY's avatar
Ghislain MARY committed
717 718 719 720 721
const Address &Call::getLocalAddress () const {
	L_D();
	return d->getActiveSession()->getLocalAddress();
}

Ronan's avatar
Ronan committed
722
LinphoneCallLog *Call::getLog () const {
723
	L_D();
724 725 726
	return d->getActiveSession()->getLog();
}

Ronan's avatar
Ronan committed
727
RtpTransport *Call::getMetaRtcpTransport (int streamIndex) const {
728
	L_D();
729
	return static_pointer_cast<MediaSession>(d->getActiveSession())->getMetaRtcpTransport(streamIndex);
730 731
}

Ronan's avatar
Ronan committed
732
RtpTransport *Call::getMetaRtpTransport (int streamIndex) const {
733
	L_D();
734
	return static_pointer_cast<MediaSession>(d->getActiveSession())->getMetaRtpTransport(streamIndex);
735 736 737
}

float Call::getMicrophoneVolumeGain () const {
738
	L_D();
739
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getMicrophoneVolumeGain();
740 741
}

Ronan's avatar
Ronan committed
742
void *Call::getNativeVideoWindowId () const {
743
	L_D();
744
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getNativeVideoWindowId();
745 746
}

Ronan's avatar
Ronan committed
747
const MediaSessionParams *Call::getParams () const {
748
	L_D();
749
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getMediaParams();
750 751
}

752 753 754 755 756 757 758
LinphonePlayer *Call::getPlayer () const {
	L_D();
	if (!d->player)
		d->createPlayer();
	return d->player;
}

759
float Call::getPlayVolume () const {
760
	L_D();
761
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getPlayVolume();
762 763 764
}

LinphoneReason Call::getReason () const {
765
	L_D();
766 767 768 769
	return d->getActiveSession()->getReason();
}

float Call::getRecordVolume () const {
770
	L_D();
771
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getRecordVolume();
772 773
}

774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790
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();
}

Ronan's avatar
Ronan committed
791
const Address &Call::getRemoteAddress () const {
792
	L_D();
793 794 795 796
	return d->getActiveSession()->getRemoteAddress();
}

string Call::getRemoteContact () const {
797
	L_D();
798 799 800
	return d->getActiveSession()->getRemoteContact();
}

Ronan's avatar
Ronan committed
801
const MediaSessionParams *Call::getRemoteParams () const {
802
	L_D();
803
	return static_pointer_cast<MediaSession>(d->getActiveSession())->getRemoteParams();
804 805
}

Ghislain MARY's avatar
Ghislain MARY committed
806 807 808 809 810
string Call::getRemoteUserAgent () const {
	L_D();
	return d->getActiveSession()->getRemoteUserAgent();
}

Ghislain MARY's avatar
Ghislain MARY committed
811 812 813 814 815 816 817 818 819 820 821 822
shared_ptr<Call> Call::getReplacedCall () const {
	L_D();
	shared_ptr<CallSession> replacedCallSession = d->getActiveSession()->getReplacedCallSession();
	if (!replacedCallSession)
		return nullptr;
	for (const auto &call : getCore()->getCalls()) {
		if (call->getPrivate()->getActiveSession() == replacedCallSession)
			return call;
	}
	return nullptr;
}

823
float Call::getSpeakerVolumeGain () const {
824
	L_D();
825
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getSpeakerVolumeGain();
826 827
}

828
CallSession::State Call::getState () const {
829
	L_D();
830 831 832
	return d->getActiveSession()->getState();
}

Ronan's avatar
Ronan committed
833
LinphoneCallStats *Call::getStats (LinphoneStreamType type) const {
834
	L_D();
835
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getStats(type);
836 837
}

838
int Call::getStreamCount () const {
839
	L_D();
840
	return static_pointer_cast<MediaSession>(d->getActiveSession())->getStreamCount();
841 842 843
}

MSFormatType Call::getStreamType (int streamIndex) const {
844
	L_D();
845
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getStreamType(streamIndex);
846 847
}

Ronan's avatar
Ronan committed
848
LinphoneCallStats *Call::getTextStats () const {
849
	L_D();
850 851 852 853 854 855 856 857
	return static_pointer_cast<const MediaSession>(d->getActiveSession())->getTextStats();
}

const Address &Call::getToAddress () const {
	L_D();
	return d->getActiveSession()->getToAddress();
}

858
string Call::getToHeader (const string &name) const {
859 860
	L_D();
	return d->getActiveSession()->getToHeader(name);