call.cpp 15.5 KB
Newer Older
1 2
/*
 * call.cpp
Ghislain MARY's avatar
Ghislain MARY committed
3
 * Copyright (C) 2010-2017 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"
22
#include "conference/session/call-session-p.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

32
bool CallPrivate::getAudioMuted () const {
Ronan's avatar
Ronan committed
33
	return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getAudioMuted();
34 35
}

Ronan's avatar
Ronan committed
36
LinphoneProxyConfig *CallPrivate::getDestProxy () const {
37 38 39
	return getActiveSession()->getPrivate()->getDestProxy();
}

Ronan's avatar
Ronan committed
40
IceSession *CallPrivate::getIceSession () const {
Ronan's avatar
Ronan committed
41
	return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getIceSession();
42 43
}

Ronan's avatar
Ronan committed
44
MediaStream *CallPrivate::getMediaStream (LinphoneStreamType type) const {
Ronan's avatar
Ronan committed
45
	return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getMediaStream(type);
46 47
}

48
SalCallOp * CallPrivate::getOp () const {
49 50 51 52
	return getActiveSession()->getPrivate()->getOp();
}

void CallPrivate::setAudioMuted (bool value) {
Ronan's avatar
Ronan committed
53
	static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->setAudioMuted(value);
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
}

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

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) {
75
	return getActiveSession()->startInvite(destination, "");
76 77 78 79
}

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

80 81 82 83 84 85 86
void CallPrivate::createPlayer () const {
	L_Q();
	player = linphone_call_build_player(L_GET_C_BACK_PTR(q));
}

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

87
void CallPrivate::onAckBeingSent (LinphoneHeaders *headers) {
88 89
	L_Q();
	linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, false);
90 91
}

92
void CallPrivate::onAckReceived (LinphoneHeaders *headers) {
93 94
	L_Q();
	linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, true);
95 96
}

97
void CallPrivate::onCallSetReleased () {
98 99
	L_Q();
	linphone_call_unref(L_GET_C_BACK_PTR(q));
100 101
}

102
void CallPrivate::onCallSetTerminated () {
103 104 105
	L_Q();
	LinphoneCall *lcall = L_GET_C_BACK_PTR(q);
	LinphoneCore *core = q->getCore()->getCCore();
106 107 108 109 110 111 112
	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
113 114 115 116 117 118 119 120 121 122
		#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
123 124 125 126 127
		if (!core->calls)
			ms_bandwidth_controller_reset_state(core->bw_controller);
	}
}

Ronan's avatar
Ronan committed
128
void CallPrivate::onCallStateChanged (LinphoneCallState state, const string &message) {
129 130
	L_Q();
	linphone_call_notify_state_changed(L_GET_C_BACK_PTR(q), state, message.c_str());
131 132
}

133
void CallPrivate::onCheckForAcceptation () {
134 135 136
	L_Q();
	LinphoneCall *lcall = L_GET_C_BACK_PTR(q);
	bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_calls(q->getCore()->getCCore()));
137 138 139 140 141 142 143 144
	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
145 146
				lInfo() << "Already existing call [" << call << "] in state [" << linphone_call_state_to_string(linphone_call_get_state(call)) <<
					"], canceling it before accepting new call [" << lcall << "]";
147 148 149 150 151 152 153 154 155
				linphone_call_terminate(call);
				break;
			default:
				break; /* Nothing to do */
		}
	}
	bctbx_list_free(copy);
}

156
void CallPrivate::onIncomingCallStarted () {
157 158
	L_Q();
	linphone_core_notify_incoming_call(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q));
159 160
}

161
void CallPrivate::onIncomingCallToBeAdded () {
162 163 164
	L_Q();
	/* The call is acceptable so we can now add it to our list */
	linphone_core_add_call(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q));
165 166
}

167
void CallPrivate::onInfoReceived (const LinphoneInfoMessage *im) {
168 169
	L_Q();
	linphone_call_notify_info_message_received(L_GET_C_BACK_PTR(q), im);
170 171
}

Ronan's avatar
Ronan committed
172
void CallPrivate::onEncryptionChanged (bool activated, const string &authToken) {
173 174
	L_Q();
	linphone_call_notify_encryption_changed(L_GET_C_BACK_PTR(q), activated, authToken.empty() ? nullptr : authToken.c_str());
175 176
}

177
void CallPrivate::onStatsUpdated (const LinphoneCallStats *stats) {
178 179
	L_Q();
	linphone_call_notify_stats_updated(L_GET_C_BACK_PTR(q), stats);
180 181
}

182
void CallPrivate::onResetCurrentCall () {
183 184
	L_Q();
	q->getCore()->getCCore()->current_call = nullptr;
185 186
}

187
void CallPrivate::onSetCurrentCall () {
188 189
	L_Q();
	q->getCore()->getCCore()->current_call = L_GET_C_BACK_PTR(q);
190 191
}

192
void CallPrivate::onFirstVideoFrameDecoded () {
193 194 195
	L_Q();
	if (nextVideoFrameDecoded._func) {
		nextVideoFrameDecoded._func(L_GET_C_BACK_PTR(q), nextVideoFrameDecoded._user_data);
196 197 198 199 200
		nextVideoFrameDecoded._func = nullptr;
		nextVideoFrameDecoded._user_data = nullptr;
	}
}

201
void CallPrivate::onResetFirstVideoFrameDecoded () {
202 203 204 205
#ifdef VIDEO_ENABLED
	if (nextVideoFrameDecoded._func)
		static_cast<MediaSession *>(getActiveSession().get())->resetFirstVideoFrameDecoded();
#endif // ifdef VIDEO_ENABLED
206
}
207 208 209

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

210 211 212 213
Call::Call (CallPrivate &p, shared_ptr<Core> core) : Object(p), CoreAccessor(core) {
	L_D();
	d->nextVideoFrameDecoded._func = nullptr;
	d->nextVideoFrameDecoded._user_data = nullptr;
214 215 216 217
}

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

218
LinphoneStatus Call::accept (const MediaSessionParams *msp) {
219
	L_D();
220 221 222
	return static_cast<MediaSession *>(d->getActiveSession().get())->accept(msp);
}

223
LinphoneStatus Call::acceptEarlyMedia (const MediaSessionParams *msp) {
224
	L_D();
225 226 227
	return static_cast<MediaSession *>(d->getActiveSession().get())->acceptEarlyMedia(msp);
}

228
LinphoneStatus Call::acceptUpdate (const MediaSessionParams *msp) {
229
	L_D();
230 231 232 233
	return static_cast<MediaSession *>(d->getActiveSession().get())->acceptUpdate(msp);
}

LinphoneStatus Call::decline (LinphoneReason reason) {
234
	L_D();
235 236 237 238
	return d->getActiveSession()->decline(reason);
}

LinphoneStatus Call::decline (const LinphoneErrorInfo *ei) {
239
	L_D();
240 241 242
	return d->getActiveSession()->decline(ei);
}

Ghislain MARY's avatar
Ghislain MARY committed
243 244 245 246 247
void Call::oglRender () const {
	L_D();
	static_pointer_cast<MediaSession>(d->getActiveSession())->getPrivate()->oglRender();
}

248
LinphoneStatus Call::pause () {
249
	L_D();
250 251 252
	return static_cast<MediaSession *>(d->getActiveSession().get())->pause();
}

253 254 255 256 257
LinphoneStatus Call::redirect (const std::string &redirectUri) {
	L_D();
	return d->getActiveSession()->redirect(redirectUri);
}

258
LinphoneStatus Call::resume () {
259
	L_D();
260 261 262
	return static_cast<MediaSession *>(d->getActiveSession().get())->resume();
}

263
void Call::sendVfuRequest () {
264
	L_D();
265 266 267 268
	static_cast<MediaSession *>(d->getActiveSession().get())->sendVfuRequest();
}

void Call::startRecording () {
269
	L_D();
270 271 272 273
	static_cast<MediaSession *>(d->getActiveSession().get())->startRecording();
}

void Call::stopRecording () {
274
	L_D();
275 276 277
	static_cast<MediaSession *>(d->getActiveSession().get())->stopRecording();
}

Ronan's avatar
Ronan committed
278
LinphoneStatus Call::takePreviewSnapshot (const string &file) {
279
	L_D();
280 281 282
	return static_cast<MediaSession *>(d->getActiveSession().get())->takePreviewSnapshot(file);
}

Ronan's avatar
Ronan committed
283
LinphoneStatus Call::takeVideoSnapshot (const string &file) {
284
	L_D();
285 286 287 288
	return static_cast<MediaSession *>(d->getActiveSession().get())->takeVideoSnapshot(file);
}

LinphoneStatus Call::terminate (const LinphoneErrorInfo *ei) {
289
	L_D();
290 291 292
	return d->getActiveSession()->terminate(ei);
}

293
LinphoneStatus Call::update (const MediaSessionParams *msp) {
294
	L_D();
295 296 297 298
	return static_cast<MediaSession *>(d->getActiveSession().get())->update(msp);
}

void Call::zoomVideo (float zoomFactor, float *cx, float *cy) {
299 300 301 302
	zoomVideo(zoomFactor, *cx, *cy);
}

void Call::zoomVideo (float zoomFactor, float cx, float cy) {
303
	L_D();
304
	static_cast<MediaSession *>(d->getActiveSession().get())->zoomVideo(zoomFactor, cx, cy);
305 306 307 308
}

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

309
bool Call::cameraEnabled () const {
310
	L_D();
311 312 313 314
	return static_cast<const MediaSession *>(d->getActiveSession().get())->cameraEnabled();
}

bool Call::echoCancellationEnabled () const {
315
	L_D();
316 317 318 319
	return static_cast<const MediaSession *>(d->getActiveSession().get())->echoCancellationEnabled();
}

bool Call::echoLimiterEnabled () const {
320
	L_D();
321 322 323 324
	return static_cast<const MediaSession *>(d->getActiveSession().get())->echoLimiterEnabled();
}

void Call::enableCamera (bool value) {
325
	L_D();
326
	static_cast<MediaSession *>(d->getActiveSession().get())->enableCamera(value);
327
}
328 329

void Call::enableEchoCancellation (bool value) {
330
	L_D();
331 332 333 334
	static_cast<MediaSession *>(d->getActiveSession().get())->enableEchoCancellation(value);
}

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

bool Call::getAllMuted () const {
340
	L_D();
341 342 343
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAllMuted();
}

Ronan's avatar
Ronan committed
344
LinphoneCallStats *Call::getAudioStats () const {
345
	L_D();
346 347 348 349
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAudioStats();
}

string Call::getAuthenticationToken () const {
350
	L_D();
351 352 353 354
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAuthenticationToken();
}

bool Call::getAuthenticationTokenVerified () const {
355
	L_D();
356 357 358 359
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAuthenticationTokenVerified();
}

float Call::getAverageQuality () const {
360
	L_D();
361 362 363
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getAverageQuality();
}

Ronan's avatar
Ronan committed
364
const MediaSessionParams *Call::getCurrentParams () const {
365
	L_D();
366 367 368 369
	return static_cast<MediaSession *>(d->getActiveSession().get())->getCurrentParams();
}

float Call::getCurrentQuality () const {
370
	L_D();
371 372 373 374
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getCurrentQuality();
}

LinphoneCallDir Call::getDirection () const {
375
	L_D();
376 377 378 379
	return d->getActiveSession()->getDirection();
}

int Call::getDuration () const {
380
	L_D();
381 382 383
	return d->getActiveSession()->getDuration();
}

Ronan's avatar
Ronan committed
384
const LinphoneErrorInfo *Call::getErrorInfo () const {
385
	L_D();
386 387 388
	return d->getActiveSession()->getErrorInfo();
}

Ronan's avatar
Ronan committed
389
LinphoneCallLog *Call::getLog () const {
390
	L_D();
391 392 393
	return d->getActiveSession()->getLog();
}

Ronan's avatar
Ronan committed
394
RtpTransport *Call::getMetaRtcpTransport (int streamIndex) const {
395
	L_D();
396 397 398
	return static_cast<MediaSession *>(d->getActiveSession().get())->getMetaRtcpTransport(streamIndex);
}

Ronan's avatar
Ronan committed
399
RtpTransport *Call::getMetaRtpTransport (int streamIndex) const {
400
	L_D();
401 402 403 404
	return static_cast<MediaSession *>(d->getActiveSession().get())->getMetaRtpTransport(streamIndex);
}

float Call::getMicrophoneVolumeGain () const {
405
	L_D();
406 407 408
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getMicrophoneVolumeGain();
}

Ronan's avatar
Ronan committed
409
void *Call::getNativeVideoWindowId () const {
410
	L_D();
411 412 413
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getNativeVideoWindowId();
}

Ronan's avatar
Ronan committed
414
const MediaSessionParams *Call::getParams () const {
415
	L_D();
416 417 418
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getMediaParams();
}

419 420 421 422 423 424 425
LinphonePlayer *Call::getPlayer () const {
	L_D();
	if (!d->player)
		d->createPlayer();
	return d->player;
}

426
float Call::getPlayVolume () const {
427
	L_D();
428 429 430 431
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getPlayVolume();
}

LinphoneReason Call::getReason () const {
432
	L_D();
433 434 435 436
	return d->getActiveSession()->getReason();
}

float Call::getRecordVolume () const {
437
	L_D();
438 439 440
	return static_cast<const MediaSession *>(d->getActiveSession().get())->getRecordVolume();
}

Ronan's avatar
Ronan committed
441
const Address &Call::getRemoteAddress () const {
442
	L_D();
443 444 445 446
	return d->getActiveSession()->getRemoteAddress();
}

string Call::getRemoteAddressAsString () const {
447
	L_D();
448 449 450 451
	return d->getActiveSession()->getRemoteAddressAsString();
}

string Call::getRemoteContact () const {
452
	L_D();
453 454 455
	return d->getActiveSession()->getRemoteContact();
}

Ronan's avatar
Ronan committed
456
const MediaSessionParams *Call::getRemoteParams () const {
457
	L_D();
458 459 460
	return static_cast<MediaSession *>(d->getActiveSession().get())->getRemoteParams();
}

Ghislain MARY's avatar
Ghislain MARY committed
461 462 463 464 465
string Call::getRemoteUserAgent () const {
	L_D();
	return d->getActiveSession()->getRemoteUserAgent();
}

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

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

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

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

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

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

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

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

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

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

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

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

Ghislain MARY's avatar
Ghislain MARY committed
528 529 530 531 532
void Call::setParams (const MediaSessionParams *msp) {
	L_D();
	static_cast<MediaSession *>(d->getActiveSession().get())->setParams(msp);
}

533
void Call::setSpeakerVolumeGain (float value) {
534
	L_D();
535 536 537 538
	static_cast<MediaSession *>(d->getActiveSession().get())->setSpeakerVolumeGain(value);
}

LINPHONE_END_NAMESPACE