call.cpp 15.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
/*
 * call.cpp
 * Copyright (C) 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 3 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, see <http://www.gnu.org/licenses/>.
 */

19
#include "call-p.h"
20
#include "conference/local-conference.h"
21
#include "conference/participant-p.h"
22
#include "conference/remote-conference.h"
23
#include "conference/session/media-session-p.h"
24
#include "logger/logger.h"
25

26
// =============================================================================
27 28 29

using namespace std;

30
LINPHONE_BEGIN_NAMESPACE
31

Ronan's avatar
Ronan committed
32 33 34 35 36 37 38 39 40 41
CallPrivate::CallPrivate (
	LinphoneCall *call,
	LinphoneCore *core,
	LinphoneCallDir direction,
	const Address &from,
	const Address &to,
	LinphoneProxyConfig *cfg,
	SalOp *op,
	const MediaSessionParams *msp
) : lcall(call), core(core) {
42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
	nextVideoFrameDecoded._func = nullptr;
	nextVideoFrameDecoded._user_data = nullptr;
}

CallPrivate::~CallPrivate () {
	if (conference)
		delete conference;
}

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

shared_ptr<CallSession> CallPrivate::getActiveSession () const {
	return conference->getActiveParticipant()->getPrivate()->getSession();
}

bool CallPrivate::getAudioMuted () const {
	return static_cast<MediaSession *>(getActiveSession().get())->getPrivate()->getAudioMuted();
}

Ronan's avatar
Ronan committed
61
LinphoneProxyConfig *CallPrivate::getDestProxy () const {
62 63 64
	return getActiveSession()->getPrivate()->getDestProxy();
}

Ronan's avatar
Ronan committed
65
IceSession *CallPrivate::getIceSession () const {
66 67 68
	return static_cast<MediaSession *>(getActiveSession().get())->getPrivate()->getIceSession();
}

Ronan's avatar
Ronan committed
69
MediaStream *CallPrivate::getMediaStream (LinphoneStreamType type) const {
70 71 72
	return static_cast<MediaSession *>(getActiveSession().get())->getPrivate()->getMediaStream(type);
}

Ronan's avatar
Ronan committed
73
SalOp *CallPrivate::getOp () const {
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
	return getActiveSession()->getPrivate()->getOp();
}

void CallPrivate::setAudioMuted (bool value) {
	static_cast<MediaSession *>(getActiveSession().get())->getPrivate()->setAudioMuted(value);
}

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

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

bool CallPrivate::initiateOutgoing () {
	return getActiveSession()->initiateOutgoing();
}

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

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

int CallPrivate::startInvite (const Address *destination) {
100
	return getActiveSession()->startInvite(destination, "");
101 102 103 104
}

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

105
void CallPrivate::onAckBeingSent (LinphoneHeaders *headers) {
106 107 108 109
	if (lcall)
		linphone_call_notify_ack_processing(lcall, headers, false);
}

110
void CallPrivate::onAckReceived (LinphoneHeaders *headers) {
111 112 113 114
	if (lcall)
		linphone_call_notify_ack_processing(lcall, headers, true);
}

115
void CallPrivate::onCallSetReleased () {
116 117 118 119
	if (lcall)
		linphone_call_unref(lcall);
}

120
void CallPrivate::onCallSetTerminated () {
121 122 123 124 125 126 127
	if (lcall) {
		if (lcall == core->current_call) {
			lInfo() << "Resetting the current call";
			core->current_call = nullptr;
		}
		if (linphone_core_del_call(core, lcall) != 0)
			lError() << "Could not remove the call from the list!!!";
Ronan's avatar
Ronan committed
128 129 130 131 132 133 134 135 136 137
		#if 0
			if (core->conf_ctx)
				linphone_conference_on_call_terminating(core->conf_ctx, lcall);
			if (lcall->ringing_beep) {
				linphone_core_stop_dtmf(core);
				lcall->ringing_beep = false;
			}
			if (lcall->chat_room)
				linphone_chat_room_set_call(lcall->chat_room, nullptr);
		#endif // if 0
138 139 140 141 142
		if (!core->calls)
			ms_bandwidth_controller_reset_state(core->bw_controller);
	}
}

Ronan's avatar
Ronan committed
143
void CallPrivate::onCallStateChanged (LinphoneCallState state, const string &message) {
144 145 146 147
	if (lcall)
		linphone_call_notify_state_changed(lcall, state, message.c_str());
}

148 149 150 151 152 153 154 155 156 157
void CallPrivate::onCheckForAcceptation () {
	bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_calls(core));
	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;
		switch (linphone_call_get_state(call)) {
			case LinphoneCallOutgoingInit:
			case LinphoneCallOutgoingProgress:
			case LinphoneCallOutgoingRinging:
			case LinphoneCallOutgoingEarlyMedia:
Ronan's avatar
Ronan committed
158 159
				lInfo() << "Already existing call [" << call << "] in state [" << linphone_call_state_to_string(linphone_call_get_state(call)) <<
					"], canceling it before accepting new call [" << lcall << "]";
160 161 162 163 164 165 166 167 168
				linphone_call_terminate(call);
				break;
			default:
				break; /* Nothing to do */
		}
	}
	bctbx_list_free(copy);
}

169
void CallPrivate::onIncomingCallStarted () {
170 171 172 173
	if (lcall)
		linphone_core_notify_incoming_call(core, lcall);
}

174
void CallPrivate::onIncomingCallToBeAdded () {
175 176 177 178
	if (lcall) /* The call is acceptable so we can now add it to our list */
		linphone_core_add_call(core, lcall);
}

Ronan's avatar
Ronan committed
179
void CallPrivate::onEncryptionChanged (bool activated, const string &authToken) {
180 181 182 183
	if (lcall)
		linphone_call_notify_encryption_changed(lcall, activated, authToken.empty() ? nullptr : authToken.c_str());
}

184
void CallPrivate::onStatsUpdated (const LinphoneCallStats *stats) {
185 186 187 188
	if (lcall)
		linphone_call_notify_stats_updated(lcall, stats);
}

189
void CallPrivate::onResetCurrentCall () {
190 191 192
	core->current_call = nullptr;
}

193
void CallPrivate::onSetCurrentCall () {
194 195 196 197
	if (lcall)
		core->current_call = lcall;
}

198
void CallPrivate::onFirstVideoFrameDecoded () {
199 200 201 202 203 204 205
	if (lcall && nextVideoFrameDecoded._func) {
		nextVideoFrameDecoded._func(lcall, nextVideoFrameDecoded._user_data);
		nextVideoFrameDecoded._func = nullptr;
		nextVideoFrameDecoded._user_data = nullptr;
	}
}

206
void CallPrivate::onResetFirstVideoFrameDecoded () {
Ronan's avatar
Ronan committed
207 208 209 210
	#ifdef VIDEO_ENABLED
		if (lcall && nextVideoFrameDecoded._func)
			static_cast<MediaSession *>(getActiveSession().get())->resetFirstVideoFrameDecoded();
	#endif // ifdef VIDEO_ENABLED
211
}
212 213 214

// =============================================================================

Ronan's avatar
Ronan committed
215 216 217 218 219 220 221 222 223 224
Call::Call (
	LinphoneCall *call,
	LinphoneCore *core,
	LinphoneCallDir direction,
	const Address &from,
	const Address &to,
	LinphoneProxyConfig *cfg,
	SalOp *op,
	const MediaSessionParams *msp
) : Object(*new CallPrivate(call, core, direction, from, to, cfg, op, msp)) {
225
	L_D();
226 227 228 229 230 231 232 233 234 235
	const Address *myAddress = (direction == LinphoneCallIncoming) ? &to : &from;
	string confType = lp_config_get_string(linphone_core_get_config(core), "misc", "conference_type", "local");
	if (confType == "remote") {
		d->conference = new RemoteConference(core, *myAddress, d);
	} else {
		d->conference = new LocalConference(core, *myAddress, d);
	}
	const Address *remoteAddress = (direction == LinphoneCallIncoming) ? &from : &to;
	shared_ptr<Participant> participant = d->conference->addParticipant(*remoteAddress, msp, true);
	participant->getPrivate()->getSession()->configure(direction, cfg, op, from, to);
236 237 238 239
}

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

240
LinphoneStatus Call::accept (const MediaSessionParams *msp) {
241
	L_D();
242 243 244
	return static_cast<MediaSession *>(d->getActiveSession().get())->accept(msp);
}

245
LinphoneStatus Call::acceptEarlyMedia (const MediaSessionParams *msp) {
246
	L_D();
247 248 249
	return static_cast<MediaSession *>(d->getActiveSession().get())->acceptEarlyMedia(msp);
}

250
LinphoneStatus Call::acceptUpdate (const MediaSessionParams *msp) {
251
	L_D();
252 253 254 255
	return static_cast<MediaSession *>(d->getActiveSession().get())->acceptUpdate(msp);
}

LinphoneStatus Call::decline (LinphoneReason reason) {
256
	L_D();
257 258 259 260
	return d->getActiveSession()->decline(reason);
}

LinphoneStatus Call::decline (const LinphoneErrorInfo *ei) {
261
	L_D();
262 263 264
	return d->getActiveSession()->decline(ei);
}

265
LinphoneStatus Call::pause () {
266
	L_D();
267 268 269 270
	return static_cast<MediaSession *>(d->getActiveSession().get())->pause();
}

LinphoneStatus Call::resume () {
271
	L_D();
272 273 274
	return static_cast<MediaSession *>(d->getActiveSession().get())->resume();
}

275
void Call::sendVfuRequest () {
276
	L_D();
277 278 279 280
	static_cast<MediaSession *>(d->getActiveSession().get())->sendVfuRequest();
}

void Call::startRecording () {
281
	L_D();
282 283 284 285
	static_cast<MediaSession *>(d->getActiveSession().get())->startRecording();
}

void Call::stopRecording () {
286
	L_D();
287 288 289
	static_cast<MediaSession *>(d->getActiveSession().get())->stopRecording();
}

Ronan's avatar
Ronan committed
290
LinphoneStatus Call::takePreviewSnapshot (const string &file) {
291
	L_D();
292 293 294
	return static_cast<MediaSession *>(d->getActiveSession().get())->takePreviewSnapshot(file);
}

Ronan's avatar
Ronan committed
295
LinphoneStatus Call::takeVideoSnapshot (const string &file) {
296
	L_D();
297 298 299 300
	return static_cast<MediaSession *>(d->getActiveSession().get())->takeVideoSnapshot(file);
}

LinphoneStatus Call::terminate (const LinphoneErrorInfo *ei) {
301
	L_D();
302 303 304
	return d->getActiveSession()->terminate(ei);
}

305
LinphoneStatus Call::update (const MediaSessionParams *msp) {
306
	L_D();
307 308 309 310
	return static_cast<MediaSession *>(d->getActiveSession().get())->update(msp);
}

void Call::zoomVideo (float zoomFactor, float *cx, float *cy) {
311
	L_D();
312
	static_cast<MediaSession *>(d->getActiveSession().get())->zoomVideo(zoomFactor, cx, cy);
313 314 315 316
}

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

317
bool Call::cameraEnabled () const {
318
	L_D();
319 320 321 322
	return static_cast<const MediaSession *>(d->getActiveSession().get())->cameraEnabled();
}

bool Call::echoCancellationEnabled () const {
323
	L_D();
324 325 326 327
	return static_cast<const MediaSession *>(d->getActiveSession().get())->echoCancellationEnabled();
}

bool Call::echoLimiterEnabled () const {
328
	L_D();
329 330 331 332
	return static_cast<const MediaSession *>(d->getActiveSession().get())->echoLimiterEnabled();
}

void Call::enableCamera (bool value) {
333
	L_D();
334
	static_cast<MediaSession *>(d->getActiveSession().get())->enableCamera(value);
335
}
336 337

void Call::enableEchoCancellation (bool value) {
338
	L_D();
339 340 341 342
	static_cast<MediaSession *>(d->getActiveSession().get())->enableEchoCancellation(value);
}

void Call::enableEchoLimiter (bool value) {
343
	L_D();
344 345 346 347
	static_cast<MediaSession *>(d->getActiveSession().get())->enableEchoLimiter(value);
}

bool Call::getAllMuted () const {
348
	L_D();
349 350 351
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAllMuted();
}

Ronan's avatar
Ronan committed
352
LinphoneCallStats *Call::getAudioStats () const {
353
	L_D();
354 355 356 357
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAudioStats();
}

string Call::getAuthenticationToken () const {
358
	L_D();
359 360 361 362
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAuthenticationToken();
}

bool Call::getAuthenticationTokenVerified () const {
363
	L_D();
364 365 366 367
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAuthenticationTokenVerified();
}

float Call::getAverageQuality () const {
368
	L_D();
369 370 371
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAverageQuality();
}

Ronan's avatar
Ronan committed
372
LinphoneCore *Call::getCore () const {
373
	L_D();
374 375 376
	return d->core;
}

Ronan's avatar
Ronan committed
377
const MediaSessionParams *Call::getCurrentParams () const {
378
	L_D();
379 380 381 382
	return static_cast<MediaSession *>(d->getActiveSession().get())->getCurrentParams();
}

float Call::getCurrentQuality () const {
383
	L_D();
384 385 386 387
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getCurrentQuality();
}

LinphoneCallDir Call::getDirection () const {
388
	L_D();
389 390 391 392
	return d->getActiveSession()->getDirection();
}

int Call::getDuration () const {
393
	L_D();
394 395 396
	return d->getActiveSession()->getDuration();
}

Ronan's avatar
Ronan committed
397
const LinphoneErrorInfo *Call::getErrorInfo () const {
398
	L_D();
399 400 401
	return d->getActiveSession()->getErrorInfo();
}

Ronan's avatar
Ronan committed
402
LinphoneCallLog *Call::getLog () const {
403
	L_D();
404 405 406
	return d->getActiveSession()->getLog();
}

Ronan's avatar
Ronan committed
407
RtpTransport *Call::getMetaRtcpTransport (int streamIndex) const {
408
	L_D();
409 410 411
	return static_cast<MediaSession *>(d->getActiveSession().get())->getMetaRtcpTransport(streamIndex);
}

Ronan's avatar
Ronan committed
412
RtpTransport *Call::getMetaRtpTransport (int streamIndex) const {
413
	L_D();
414 415 416 417
	return static_cast<MediaSession *>(d->getActiveSession().get())->getMetaRtpTransport(streamIndex);
}

float Call::getMicrophoneVolumeGain () const {
418
	L_D();
419 420 421
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getMicrophoneVolumeGain();
}

Ronan's avatar
Ronan committed
422
void *Call::getNativeVideoWindowId () const {
423
	L_D();
424 425 426
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getNativeVideoWindowId();
}

Ronan's avatar
Ronan committed
427
const MediaSessionParams *Call::getParams () const {
428
	L_D();
429 430 431 432
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getMediaParams();
}

float Call::getPlayVolume () const {
433
	L_D();
434 435 436 437
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getPlayVolume();
}

LinphoneReason Call::getReason () const {
438
	L_D();
439 440 441 442
	return d->getActiveSession()->getReason();
}

float Call::getRecordVolume () const {
443
	L_D();
444 445 446
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getRecordVolume();
}

Ronan's avatar
Ronan committed
447
const Address &Call::getRemoteAddress () const {
448
	L_D();
449 450 451 452
	return d->getActiveSession()->getRemoteAddress();
}

string Call::getRemoteAddressAsString () const {
453
	L_D();
454 455 456 457
	return d->getActiveSession()->getRemoteAddressAsString();
}

string Call::getRemoteContact () const {
458
	L_D();
459 460 461
	return d->getActiveSession()->getRemoteContact();
}

Ronan's avatar
Ronan committed
462
const MediaSessionParams *Call::getRemoteParams () const {
463
	L_D();
464 465 466 467
	return static_cast<MediaSession *>(d->getActiveSession().get())->getRemoteParams();
}

float Call::getSpeakerVolumeGain () const {
468
	L_D();
469 470 471 472
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getSpeakerVolumeGain();
}

LinphoneCallState Call::getState () const {
473
	L_D();
474 475 476
	return d->getActiveSession()->getState();
}

Ronan's avatar
Ronan committed
477
LinphoneCallStats *Call::getStats (LinphoneStreamType type) const {
478
	L_D();
479 480 481
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getStats(type);
}

482
int Call::getStreamCount () const {
483
	L_D();
484 485 486 487
	return static_cast<MediaSession *>(d->getActiveSession().get())->getStreamCount();
}

MSFormatType Call::getStreamType (int streamIndex) const {
488
	L_D();
489 490 491
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getStreamType(streamIndex);
}

Ronan's avatar
Ronan committed
492
LinphoneCallStats *Call::getTextStats () const {
493
	L_D();
494 495 496
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getTextStats();
}

Ronan's avatar
Ronan committed
497
LinphoneCallStats *Call::getVideoStats () const {
498
	L_D();
499 500 501 502
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getVideoStats();
}

bool Call::mediaInProgress () const {
503
	L_D();
504 505 506 507
	return static_cast<const MediaSession *>(d->getActiveSession().get())->mediaInProgress();
}

void Call::setAuthenticationTokenVerified (bool value) {
508
	L_D();
509 510 511 512
	static_cast<MediaSession *>(d->getActiveSession().get())->setAuthenticationTokenVerified(value);
}

void Call::setMicrophoneVolumeGain (float value) {
513
	L_D();
514 515 516 517
	static_cast<MediaSession *>(d->getActiveSession().get())->setMicrophoneVolumeGain(value);
}

void Call::setNativeVideoWindowId (void *id) {
518
	L_D();
519 520 521 522
	static_cast<MediaSession *>(d->getActiveSession().get())->setNativeVideoWindowId(id);
}

void Call::setNextVideoFrameDecodedCallback (LinphoneCallCbFunc cb, void *user_data) {
523
	L_D();
524 525
	d->nextVideoFrameDecoded._func = cb;
	d->nextVideoFrameDecoded._user_data = user_data;
526
	d->onResetFirstVideoFrameDecoded();
527 528 529
}

void Call::setSpeakerVolumeGain (float value) {
530
	L_D();
531 532 533 534
	static_cast<MediaSession *>(d->getActiveSession().get())->setSpeakerVolumeGain(value);
}

LINPHONE_END_NAMESPACE