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 "core/core-p.h"
25
#include "logger/logger.h"
26

27
// =============================================================================
28 29 30

using namespace std;

31
LINPHONE_BEGIN_NAMESPACE
32

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

159
void CallPrivate::onIncomingCallToBeAdded () {
160 161
	L_Q();
	/* The call is acceptable so we can now add it to our list */
162
	q->getCore()->getPrivate()->addCall(q->getSharedFromThis());
163 164
}

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

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

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

180
void CallPrivate::onResetCurrentCall () {
181
	L_Q();
182
	q->getCore()->getPrivate()->setCurrentCall(nullptr);
183 184
}

185
void CallPrivate::onSetCurrentCall () {
186
	L_Q();
187
	q->getCore()->getPrivate()->setCurrentCall(q->getSharedFromThis());
188 189
}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

LINPHONE_END_NAMESPACE