audio_routes_tester.c 119.59 KiB
/*
 * Copyright (c) 2010-2022 Belledonne Communications SARL.
 * This file is part of Liblinphone
 * (see https://gitlab.linphone.org/BC/public/liblinphone).
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero 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 Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <sys/stat.h>
#include <sys/types.h>
#include <bctoolbox/defs.h>
#include "belle-sip/sipstack.h"
#include "mediastreamer2/msutils.h"
#include "liblinphone_tester.h"
#include "linphone/core.h"
#include "linphone/lpconfig.h"
#include "mediastreamer2/msutils.h"
#include "tester_utils.h"
static int audio_device_name_match(LinphoneAudioDevice *audio_device, const char *name) {
	return strcmp(linphone_audio_device_get_device_name(audio_device), name);
static void register_device(LinphoneCoreManager *mgr, MSSndCardDesc *card_desc) {
	// Get number of devices before loading
	bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(mgr->lc);
	int native_audio_devices_count = (int)bctbx_list_size(audio_devices);
	bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref);
	MSFactory *factory = linphone_core_get_ms_factory(mgr->lc);
	// Adding 1 devices to sound card manager:
	// - dummy_test_snd_card_desc
	MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory);
	// This devices are prepended to the list of so that they can be easily accessed later
	ms_snd_card_manager_register_desc(sndcard_manager, card_desc);
	linphone_core_reload_sound_devices(mgr->lc);
	// Choose Marie's audio devices
	// Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT
	// devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type
	audio_devices = linphone_core_get_extended_audio_devices(mgr->lc);
	int audio_devices_count = (int)bctbx_list_size(audio_devices);
	BC_ASSERT_EQUAL(audio_devices_count, (native_audio_devices_count + 1), int, "%d");
	// Unref cards
	bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref);
static LinphoneAudioDevice *
unregister_device(bool_t enable, LinphoneCoreManager *mgr, LinphoneAudioDevice *current_dev, MSSndCardDesc *card_desc) {
	// Unref current_dev
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
linphone_audio_device_unref(current_dev); if (enable) { MSFactory *factory = linphone_core_get_ms_factory(mgr->lc); MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory); // Check that description is in the card manager BC_ASSERT_PTR_NOT_NULL(bctbx_list_find(sndcard_manager->descs, card_desc)); const int noListUpdated = mgr->stat.number_of_LinphoneCoreAudioDevicesListUpdated; // Unregister card ms_snd_card_manager_unregister_desc(sndcard_manager, card_desc); linphone_core_reload_sound_devices(mgr->lc); BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneCoreAudioDevicesListUpdated, noListUpdated + 1, int, "%d"); // Get next device at the head of the list // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per // type bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(mgr->lc); LinphoneAudioDevice *next_dev = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(next_dev); linphone_audio_device_ref(next_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); return next_dev; } return linphone_audio_device_ref(current_dev); } static void unregister_all_devices(LinphoneCoreManager *mgr) { MSFactory *factory = linphone_core_get_ms_factory(mgr->lc); MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory); while (sndcard_manager->descs) ms_snd_card_manager_unregister_desc(sndcard_manager, bctbx_list_get_data(sndcard_manager->descs)); linphone_core_reload_sound_devices(mgr->lc); } static void check_io_devs(LinphoneCoreManager *mgr, const LinphoneAudioDevice *exp_dev, bool_t force_dev_check) { LinphoneCall *mgr_call = linphone_core_get_current_call(mgr->lc); const LinphoneCallParams *call_params = mgr_call != NULL ? linphone_call_get_current_params(mgr_call) : NULL; LinphoneCallState call_state = mgr_call ? linphone_call_get_state(mgr_call) : LinphoneCallStateIdle; // If no call, then there is no input or output device. Getter should return NULL if (!linphone_core_get_use_files(mgr->lc) && ((mgr_call != NULL) || (force_dev_check == TRUE))) { // Note : on these states : Paused, OutgoingRinging, Pausing, IncomingReceived // => regular devices are null (capture/playback) BUT output device comes from tonemanager. It's why there is no // specific case for it. BC_ASSERT_PTR_NOT_NULL(linphone_core_get_output_audio_device(mgr->lc)); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(mgr->lc), exp_dev); if (!mgr_call || (call_params && linphone_call_params_get_audio_direction(call_params) == LinphoneMediaDirectionRecvOnly) || call_state == LinphoneCallStatePaused) { /* FIXME: the audio inputs and outputs are unspecified when in Paused or PausedByRemote states. Indeed, the mediastreamer2 AudioStream can accept input or output MSSndCard but does nothing with it. If the MS2AudioStream goes through render, then the MSSndCard will be reset to NULL. */ // BC_ASSERT_PTR_NULL(linphone_core_get_input_audio_device(mgr->lc)); } else { BC_ASSERT_PTR_NOT_NULL(linphone_core_get_input_audio_device(mgr->lc)); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(mgr->lc), exp_dev); } } else { BC_ASSERT_PTR_NULL(linphone_core_get_output_audio_device(mgr->lc));
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
BC_ASSERT_PTR_NULL(linphone_core_get_input_audio_device(mgr->lc)); } BC_ASSERT_PTR_NOT_NULL(linphone_core_get_default_output_audio_device(mgr->lc)); BC_ASSERT_PTR_EQUAL(linphone_core_get_default_output_audio_device(mgr->lc), exp_dev); BC_ASSERT_PTR_NOT_NULL(linphone_core_get_default_input_audio_device(mgr->lc)); BC_ASSERT_PTR_EQUAL(linphone_core_get_default_input_audio_device(mgr->lc), exp_dev); } static void emulate_unreliable_device(LinphoneCoreManager *mgr, MSSndCardDesc *card_desc, const LinphoneAudioDeviceCapabilities desiredCapability, bool_t force_dev_check) { register_device(mgr, card_desc); // Choose manager audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(mgr->lc); // As it is assumed that new devices are prepended, they can be easily accessed and we do not run the risk of // gettting a device whose type is Unknown device at the head of the list LinphoneAudioDevice *exp_dev = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(exp_dev); linphone_audio_device_ref(exp_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); // Newly added device (dummy_test_snd_card_desc) is expected to have playback and record capabilities if (LinphoneAudioDeviceCapabilityPlay & desiredCapability) { BC_ASSERT_TRUE(linphone_audio_device_has_capability(exp_dev, LinphoneAudioDeviceCapabilityPlay)); } if (LinphoneAudioDeviceCapabilityRecord & desiredCapability) { BC_ASSERT_TRUE(linphone_audio_device_has_capability(exp_dev, LinphoneAudioDeviceCapabilityRecord)); } // Set default audio devices linphone_core_set_default_input_audio_device(mgr->lc, exp_dev); linphone_core_set_default_output_audio_device(mgr->lc, exp_dev); // Force input and output device linphone_core_set_output_audio_device(mgr->lc, exp_dev); linphone_core_set_input_audio_device(mgr->lc, exp_dev); linphone_core_set_ringer_device(mgr->lc, linphone_audio_device_get_id(exp_dev)); // The ringer ca be used on ringback tone // stay in pause a little while in order to generate traffic wait_for_until(mgr->lc, NULL, NULL, 5, 2000); check_io_devs(mgr, exp_dev, force_dev_check); BC_ASSERT_PTR_EQUAL(linphone_core_get_default_output_audio_device(mgr->lc), exp_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_default_input_audio_device(mgr->lc), exp_dev); exp_dev = unregister_device(TRUE, mgr, exp_dev, card_desc); wait_for_until(mgr->lc, NULL, NULL, 1, 100); check_io_devs(mgr, exp_dev, force_dev_check); linphone_audio_device_unref(exp_dev); } static void call_with_unreliable_device(void) { bctbx_list_t *lcs = NULL; bool_t force_dev_check = FALSE; LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
lcs = bctbx_list_append(lcs, marie->lc); unregister_all_devices(marie); // This should be the device the core falls back when the current is unregistered register_device(marie, &dummy3_test_snd_card_desc); emulate_unreliable_device(marie, &dummy_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 1 done"); LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); lcs = bctbx_list_append(lcs, pauline->lc); unregister_all_devices(pauline); // This should be the device the core falls back when the current is unregistered register_device(pauline, &dummy3_test_snd_card_desc); // Marie is calling (sound played on the ringstream) and Pauline is receiving the call (sound played on the ringtone // player) LinphoneCall *marie_call = linphone_core_invite_address(marie->lc, pauline->identity); BC_ASSERT_PTR_NOT_NULL(marie_call); // Marie should hear ringback as well BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1, 5000)); // Ringback emulate_unreliable_device(marie, &dummy2_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 2 done"); // Ringtone emulate_unreliable_device(pauline, &dummy_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 3 done"); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); BC_ASSERT_PTR_NOT_NULL(pauline_call); linphone_call_ref(pauline_call); // Take call - ringing ends linphone_call_accept(pauline_call); // force device check as a call is ongoing, paused or resumed therefore it is possible to change the currently used // audio device force_dev_check = TRUE; BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); // Call emulate_unreliable_device(marie, &dummy_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 4 done"); // Call emulate_unreliable_device(pauline, &dummy2_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 5 done"); linphone_call_pause(pauline_call); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallPausing, 1)); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallPausedByRemote, 1)); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallPaused, 1));
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
// Paused call emulate_unreliable_device(pauline, &dummy_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 6 done"); // PausedByRemote call emulate_unreliable_device(marie, &dummy2_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 7 done"); linphone_call_resume(pauline_call); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 2)); BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 2)); // Resumed Call emulate_unreliable_device(marie, &dummy_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 8 done"); // Resumed Call emulate_unreliable_device(pauline, &dummy2_test_snd_card_desc, (LinphoneAudioDeviceCapabilityRecord | LinphoneAudioDeviceCapabilityPlay), force_dev_check); ms_message("emulate_unreliable_device 9 done"); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // End call linphone_call_terminate(pauline_call); linphone_call_unref(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); bctbx_list_free(lcs); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); } static void call_with_audio_device_change_using_public_api(void) { bctbx_list_t *lcs; // Marie is the caller LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); register_device(marie, &dummy_test_snd_card_desc); register_device(marie, &dummy2_test_snd_card_desc); register_device(marie, &dummy_capture_test_snd_card_desc); register_device(marie, &dummy_playback_test_snd_card_desc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(marie->lc); bctbx_list_t *dev_found = NULL; // 1st device dev_found = bctbx_list_find_custom(audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *current_dev = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(current_dev); linphone_audio_device_ref(current_dev);
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
// device dummy_playback in the list dev_found = bctbx_list_find_custom(audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_PLAYBACK_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *playback_dev = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(playback_dev); linphone_audio_device_ref(playback_dev); // device dummy_capture in the list dev_found = bctbx_list_find_custom(audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_CAPTURE_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *capture_dev = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(capture_dev); linphone_audio_device_ref(capture_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(NULL, marie->lc); // Pauline is offline LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_set_network_reachable(pauline->lc, TRUE); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); lcs = bctbx_list_append(lcs, pauline->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, current_dev); linphone_core_set_default_output_audio_device(marie->lc, current_dev); LinphoneCall *marie_call = linphone_core_invite_address(marie->lc, pauline->identity); BC_ASSERT_PTR_NOT_NULL(marie_call); // Pauline shall receive the call immediately BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1, 5000)); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); if (!BC_ASSERT_PTR_NOT_NULL(pauline_call)) goto end; linphone_call_ref(pauline_call); // Marie should hear ringback as well BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1, 5000)); // Take call - ringing ends linphone_call_accept(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), current_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), current_dev); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); int noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_call_set_output_audio_device(marie_call, playback_dev); linphone_call_set_input_audio_device(marie_call, capture_dev); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (noDevChanges + 2), int, "%d"); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), playback_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), capture_dev);
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
// Set invalid audio device noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_call_set_output_audio_device(marie_call, capture_dev); linphone_call_set_input_audio_device(marie_call, playback_dev); // wait a little bit to ensure that no change is triggered wait_for_until(pauline->lc, marie->lc, NULL, 5, 1000); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), playback_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), capture_dev); // Set again the same audio device noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_call_set_output_audio_device(marie_call, playback_dev); linphone_call_set_input_audio_device(marie_call, capture_dev); // wait a little bit to ensure that no change is triggered wait_for_until(pauline->lc, marie->lc, NULL, 5, 1000); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), playback_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), capture_dev); // End call linphone_call_terminate(pauline_call); linphone_call_unref(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallReleased, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallReleased, 1)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); // After call, unref the sound card linphone_audio_device_unref(current_dev); linphone_audio_device_unref(playback_dev); linphone_audio_device_unref(capture_dev); end: bctbx_list_free(lcs); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); } static void call_with_disconnecting_device_base(bool_t before_ringback, bool_t during_ringback, bool_t during_call) { bctbx_list_t *lcs; // Marie is the caller LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); register_device(marie, &dummy_test_snd_card_desc); register_device(marie, &dummy2_test_snd_card_desc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(marie->lc); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *current_dev = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(current_dev); linphone_audio_device_ref(current_dev);
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
// Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(NULL, marie->lc); // Pauline is offline LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_set_network_reachable(pauline->lc, FALSE); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); lcs = bctbx_list_append(lcs, pauline->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, current_dev); linphone_core_set_default_output_audio_device(marie->lc, current_dev); LinphoneCall *marie_call = linphone_core_invite_address(marie->lc, pauline->identity); BC_ASSERT_PTR_NOT_NULL(marie_call); current_dev = unregister_device(before_ringback, marie, current_dev, &dummy_test_snd_card_desc); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Pauline is now online - ringback can start linphone_core_set_network_reachable(pauline->lc, TRUE); // Pauline shall receive the call immediately BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1, 5000)); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); if (!BC_ASSERT_PTR_NOT_NULL(pauline_call)) goto end; linphone_call_ref(pauline_call); // Marie should hear ringback as well BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1, 5000)); // After the ringback startx, the default device is expected to be used linphone_audio_device_unref(current_dev); audio_devices = linphone_core_get_extended_audio_devices(marie->lc); current_dev = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); linphone_audio_device_ref(current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); linphone_core_set_output_audio_device(marie->lc, current_dev); linphone_core_set_input_audio_device(marie->lc, current_dev); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev); current_dev = unregister_device(during_ringback, marie, current_dev, &dummy_test_snd_card_desc); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Take call - ringing ends linphone_call_accept(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev);
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
// Unref current device as we are deletig its card current_dev = unregister_device(during_call, marie, current_dev, &dummy_test_snd_card_desc); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // End call linphone_call_terminate(pauline_call); linphone_call_unref(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); // After call, unref the sound card linphone_audio_device_unref(current_dev); end: bctbx_list_free(lcs); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); } static void call_with_disconnecting_device_before_ringback(void) { call_with_disconnecting_device_base(TRUE, FALSE, FALSE); } static void call_with_disconnecting_device_during_ringback(void) { call_with_disconnecting_device_base(FALSE, TRUE, FALSE); } static void call_with_disconnecting_device_after_ringback(void) { call_with_disconnecting_device_base(FALSE, FALSE, TRUE); } static LinphoneAudioDevice * dev_mux(LinphoneAudioDevice *current_dev, LinphoneAudioDevice *dev0, LinphoneAudioDevice *dev1) { LinphoneAudioDevice *next_dev = NULL; if (current_dev == dev0) { next_dev = dev1; } else { next_dev = dev0; } return next_dev; } LinphoneAudioDevice *change_device(bool_t enable, LinphoneCoreManager *mgr, LinphoneAudioDevice *current_dev, LinphoneAudioDevice *dev0, LinphoneAudioDevice *dev1) { // Unref current_dev linphone_audio_device_unref(current_dev); if (enable) { LinphoneAudioDevice *next_dev = dev_mux(current_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(next_dev); next_dev = linphone_audio_device_ref(next_dev); int noDevChanges = mgr->stat.number_of_LinphoneCoreAudioDeviceChanged; const bool_t coreIsInConference = linphone_core_is_in_conference(mgr->lc); int devChanges = 0; if (linphone_audio_device_has_capability(next_dev, LinphoneAudioDeviceCapabilityPlay)) { // Change output audio device
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
if (coreIsInConference) { LinphoneConference *conference = linphone_core_get_conference(mgr->lc); BC_ASSERT_PTR_NOT_NULL(conference); if (conference) { linphone_conference_set_output_audio_device(conference, next_dev); BC_ASSERT_PTR_EQUAL(linphone_conference_get_output_audio_device(conference), next_dev); devChanges += 1; } BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(mgr->lc), next_dev); } else { LinphoneCall *call = linphone_core_get_current_call(mgr->lc); if (call) { linphone_call_set_output_audio_device(call, next_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(call), next_dev); devChanges += 1; } else { linphone_core_set_output_audio_device(mgr->lc, next_dev); const bctbx_list_t *calls = linphone_core_get_calls(mgr->lc); devChanges += (1 + ((int)bctbx_list_size(calls))); } BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(mgr->lc), next_dev); } } if (linphone_audio_device_has_capability(next_dev, LinphoneAudioDeviceCapabilityRecord)) { // Change input audio device if (coreIsInConference) { LinphoneConference *conference = linphone_core_get_conference(mgr->lc); BC_ASSERT_PTR_NOT_NULL(conference); if (conference) { linphone_conference_set_input_audio_device(conference, next_dev); BC_ASSERT_PTR_EQUAL(linphone_conference_get_input_audio_device(conference), next_dev); devChanges += 1; } BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(mgr->lc), next_dev); } else { LinphoneCall *call = linphone_core_get_current_call(mgr->lc); if (call) { linphone_call_set_input_audio_device(call, next_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(call), next_dev); devChanges += 1; } else { linphone_core_set_input_audio_device(mgr->lc, next_dev); const bctbx_list_t *calls = linphone_core_get_calls(mgr->lc); devChanges += (1 + (int)bctbx_list_size(calls)); } BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(mgr->lc), next_dev); } } BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneCoreAudioDeviceChanged, (noDevChanges + devChanges), int, "%d"); return next_dev; } return linphone_audio_device_ref(current_dev); } static void simple_call_with_audio_device_change_same_audio_device_base(bool_t before_ringback, bool_t during_ringback, bool_t during_call) { bctbx_list_t *lcs; // Marie is the caller LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); // load audio devices and get initial number of cards linphone_core_reload_sound_devices(marie->lc); bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int native_audio_devices_count = (int)bctbx_list_size(audio_devices); bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref);
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
MSFactory *factory = linphone_core_get_ms_factory(marie->lc); // Adding 2 devices to Marie' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory); // This devices are prepended to the list of so that they can be easily accessed later ms_snd_card_manager_register_desc(sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(sndcard_manager, &dummy2_test_snd_card_desc); linphone_core_reload_sound_devices(marie->lc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int audio_devices_count = (int)bctbx_list_size(audio_devices); BC_ASSERT_EQUAL(audio_devices_count, (native_audio_devices_count + 2), int, "%d"); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(dev0); linphone_audio_device_ref(dev0); // 2nd device in the list LinphoneAudioDevice *dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(dev1); linphone_audio_device_ref(dev1); // At the start, choose default device i.e. dev0 LinphoneAudioDevice *current_dev = dev0; BC_ASSERT_PTR_NOT_NULL(current_dev); linphone_audio_device_ref(current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(NULL, marie->lc); // Pauline is offline LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_set_network_reachable(pauline->lc, FALSE); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); lcs = bctbx_list_append(lcs, pauline->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, current_dev); linphone_core_set_default_output_audio_device(marie->lc, current_dev); LinphoneCall *marie_call = linphone_core_invite_address(marie->lc, pauline->identity); BC_ASSERT_PTR_NOT_NULL(marie_call); current_dev = change_device(before_ringback, marie, current_dev, dev0, dev1); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Pauline is now online - ringback can start linphone_core_set_network_reachable(pauline->lc, TRUE); // Pauline shall receive the call immediately BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1, 5000)); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); if (!BC_ASSERT_PTR_NOT_NULL(pauline_call)) goto end; linphone_call_ref(pauline_call);
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
// Marie should hear ringback as well BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1, 5000)); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev); current_dev = change_device(during_ringback, marie, current_dev, dev0, dev1); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Take call - ringing ends linphone_call_accept(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev); current_dev = change_device(during_call, marie, current_dev, dev0, dev1); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // End call linphone_call_terminate(pauline_call); linphone_call_unref(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); end: bctbx_list_free(lcs); // After call, unref the sound card linphone_audio_device_unref(dev0); linphone_audio_device_unref(dev1); linphone_audio_device_unref(current_dev); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); } static void simple_call_with_audio_device_change_same_audio_device_pingpong(void) { simple_call_with_audio_device_change_same_audio_device_base(TRUE, TRUE, TRUE); } static void create_devices(LinphoneCoreManager *manager, bctbx_list_t **audio_devices) { linphone_core_reload_sound_devices(manager->lc); *audio_devices = linphone_core_get_extended_audio_devices(manager->lc); int native_audio_devices_count = (int)bctbx_list_size(*audio_devices); bctbx_list_free_with_data(*audio_devices, (void (*)(void *))linphone_audio_device_unref); MSFactory *factory = linphone_core_get_ms_factory(manager->lc); // Adding 2 devices to manager' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory); // This devices are prepended to the list of so that they can be easily accessed later ms_snd_card_manager_register_desc(sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(sndcard_manager, &dummy2_test_snd_card_desc); linphone_core_reload_sound_devices(manager->lc); // Choose manager's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
*audio_devices = linphone_core_get_extended_audio_devices(manager->lc); int audio_devices_count = (int)bctbx_list_size(*audio_devices); BC_ASSERT_EQUAL(audio_devices_count, (native_audio_devices_count + 2), int, "%d"); } static void simple_call_with_audio_device_change_base(bool_t during_incoming_early_media, bool_t during_outgoing_early_media, bool_t before_ringback, bool_t during_ringback, bool_t during_call) { bctbx_list_t *lcs; // Marie is the caller LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); linphone_core_set_ring_during_incoming_early_media(marie->lc, (during_incoming_early_media || during_outgoing_early_media)); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_config_set_bool(linphone_core_get_config(pauline->lc), "sip", "incoming_calls_early_media", (during_incoming_early_media || during_outgoing_early_media)); bctbx_list_t *audio_devices = NULL, *pauline_audio_devices = NULL; create_devices(marie, &audio_devices); create_devices(pauline, &pauline_audio_devices); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(dev0); linphone_audio_device_ref(dev0); // 2nd device in the list LinphoneAudioDevice *dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(dev1); linphone_audio_device_ref(dev1); // At the start, choose default devices LinphoneAudioDevice *current_output_dev = dev0; BC_ASSERT_PTR_NOT_NULL(current_output_dev); linphone_audio_device_ref(current_output_dev); LinphoneAudioDevice *current_input_dev = dev1; BC_ASSERT_PTR_NOT_NULL(current_input_dev); linphone_audio_device_ref(current_input_dev); LinphoneAudioDevice *pauline_dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(pauline_audio_devices); BC_ASSERT_PTR_NOT_NULL(pauline_dev0); linphone_audio_device_ref(pauline_dev0); // 2nd device in the list LinphoneAudioDevice *pauline_dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(pauline_audio_devices->next); BC_ASSERT_PTR_NOT_NULL(pauline_dev1); linphone_audio_device_ref(pauline_dev1); // At the start, choose default devices LinphoneAudioDevice *pauline_current_output_dev = pauline_dev0; BC_ASSERT_PTR_NOT_NULL(pauline_current_output_dev); linphone_audio_device_ref(pauline_current_output_dev); LinphoneAudioDevice *pauline_current_input_dev = pauline_dev1; BC_ASSERT_PTR_NOT_NULL(pauline_current_input_dev); linphone_audio_device_ref(pauline_current_input_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); bctbx_list_free_with_data(pauline_audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(NULL, marie->lc); // Pauline is offline linphone_core_set_network_reachable(pauline->lc, FALSE); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE);
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
lcs = bctbx_list_append(lcs, pauline->lc); int initialNoDevChanges = 0; int devChanges = 0; // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, current_input_dev); linphone_core_set_default_output_audio_device(marie->lc, current_output_dev); linphone_core_set_default_input_audio_device(pauline->lc, pauline_current_input_dev); linphone_core_set_default_output_audio_device(pauline->lc, pauline_current_output_dev); linphone_core_set_ringer_device( pauline->lc, linphone_audio_device_get_id( pauline_current_input_dev)); // Set the ringer device to test if changes are not based on this card LinphoneCall *marie_call = linphone_core_invite_address(marie->lc, pauline->identity); if (!BC_ASSERT_PTR_NOT_NULL(marie_call)) goto end; linphone_call_ref(marie_call); unsigned int audioStreamStopped = _linphone_call_get_nb_audio_stops(marie_call); if (before_ringback) { linphone_audio_device_unref(current_output_dev); current_output_dev = dev_mux(current_output_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_output_dev); linphone_audio_device_ref(current_output_dev); linphone_audio_device_unref(current_input_dev); current_input_dev = dev_mux(current_input_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_input_dev); linphone_audio_device_ref(current_input_dev); initialNoDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; devChanges = 0; // Change output audio device linphone_core_set_output_audio_device(marie->lc, current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); devChanges += 2; // Change input audio device linphone_core_set_input_audio_device(marie->lc, current_input_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_input_dev); devChanges += 2; BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (initialNoDevChanges + devChanges), int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); } // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); BC_ASSERT_EQUAL(_linphone_call_get_nb_audio_stops(marie_call), audioStreamStopped, unsigned int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); // Pauline is now online - ringback can start linphone_core_set_network_reachable(pauline->lc, TRUE); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); // Pauline shall receive the call immediately BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1, 5000)); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); if (!BC_ASSERT_PTR_NOT_NULL(pauline_call)) goto end; linphone_call_ref(pauline_call); if (during_incoming_early_media || during_outgoing_early_media) { BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 5000)); if (during_incoming_early_media) {
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
linphone_audio_device_unref(pauline_current_output_dev); pauline_current_output_dev = dev_mux(pauline_current_output_dev, pauline_dev0, pauline_dev1); BC_ASSERT_PTR_NOT_NULL(pauline_current_output_dev); linphone_audio_device_ref(pauline_current_output_dev); linphone_audio_device_unref(pauline_current_input_dev); pauline_current_input_dev = dev_mux(pauline_current_input_dev, pauline_dev0, pauline_dev1); BC_ASSERT_PTR_NOT_NULL(pauline_current_input_dev); linphone_audio_device_ref(pauline_current_input_dev); initialNoDevChanges = pauline->stat.number_of_LinphoneCoreAudioDeviceChanged; devChanges = 0; // Change output audio device linphone_core_set_output_audio_device(pauline->lc, pauline_current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(pauline->lc), pauline_current_output_dev); devChanges += 2; // Change input audio device linphone_core_set_input_audio_device(pauline->lc, pauline_current_input_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(pauline->lc), pauline_current_input_dev); devChanges += 2; BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreAudioDeviceChanged, (initialNoDevChanges + devChanges), int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(pauline->lc), pauline_current_output_dev); } BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia, 1, 5000)); BC_ASSERT_EQUAL(_linphone_call_get_nb_audio_stops(marie_call), audioStreamStopped, unsigned int, "%d"); if (during_outgoing_early_media) { linphone_audio_device_unref(current_output_dev); current_output_dev = dev_mux(current_output_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_output_dev); linphone_audio_device_ref(current_output_dev); linphone_audio_device_unref(current_input_dev); current_input_dev = dev_mux(current_input_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_input_dev); linphone_audio_device_ref(current_input_dev); initialNoDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; devChanges = 0; // Change output audio device linphone_core_set_output_audio_device(marie->lc, current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); devChanges += 2; // Change input audio device linphone_core_set_input_audio_device(marie->lc, current_input_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_input_dev); devChanges += 2; BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (initialNoDevChanges + devChanges), int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); ++audioStreamStopped; // Call stream need to restart on accept to take account of new device during ringback } } else { // Marie should hear ringback as well BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1, 5000)); } // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_input_dev); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); BC_ASSERT_EQUAL(_linphone_call_get_nb_audio_stops(marie_call), audioStreamStopped, unsigned int, "%d");
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
if (during_ringback) { linphone_audio_device_unref(current_output_dev); current_output_dev = dev_mux(current_output_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_output_dev); linphone_audio_device_ref(current_output_dev); linphone_audio_device_unref(current_input_dev); current_input_dev = dev_mux(current_input_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_input_dev); linphone_audio_device_ref(current_input_dev); initialNoDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; devChanges = 0; // Change output audio device linphone_core_set_output_audio_device(marie->lc, current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); devChanges += 2; // Change input audio device linphone_core_set_input_audio_device(marie->lc, current_input_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_input_dev); devChanges += 2; BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (initialNoDevChanges + devChanges), int, "%d"); } BC_ASSERT_EQUAL(_linphone_call_get_nb_audio_stops(marie_call), audioStreamStopped, unsigned int, "%d"); if (during_incoming_early_media && during_outgoing_early_media) // In this case, there is one more stop() for marie. ++audioStreamStopped; // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); BC_ASSERT_EQUAL(_linphone_call_get_nb_audio_stops(marie_call), audioStreamStopped, unsigned int, "%d"); // Take call - ringing ends linphone_call_accept(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_input_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), current_input_dev); BC_ASSERT_EQUAL(_linphone_call_get_nb_audio_stops(marie_call), audioStreamStopped, unsigned int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(pauline->lc), pauline_current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(pauline->lc), pauline_current_input_dev); BC_ASSERT_STRING_EQUAL(linphone_audio_device_get_id(linphone_core_get_output_audio_device(pauline->lc)), linphone_audio_device_get_id(pauline_current_output_dev)); // To know what IDs are BC_ASSERT_STRING_EQUAL(linphone_audio_device_get_id(linphone_core_get_input_audio_device(pauline->lc)), linphone_audio_device_get_id(pauline_current_input_dev)); BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(pauline_call), pauline_current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(pauline_call), pauline_current_input_dev); if (during_call) { linphone_audio_device_unref(current_output_dev); current_output_dev = dev_mux(current_output_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_output_dev); linphone_audio_device_ref(current_output_dev); linphone_audio_device_unref(current_input_dev); current_input_dev = dev_mux(current_input_dev, dev0, dev1); BC_ASSERT_PTR_NOT_NULL(current_input_dev); linphone_audio_device_ref(current_input_dev); initialNoDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; devChanges = 0;
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
// Change output audio device linphone_core_set_output_audio_device(marie->lc, current_output_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_output_dev); devChanges += 2; // Change input audio device linphone_core_set_input_audio_device(marie->lc, current_input_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_input_dev); devChanges += 2; ++audioStreamStopped; // From doing render() after setting devices. TODO : only count if filters doesn't // implement MS_AUDIO_*_SET_INTERNAL_ID BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (initialNoDevChanges + devChanges), int, "%d"); } // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // End call linphone_call_terminate(pauline_call); ++audioStreamStopped; linphone_call_unref(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(_linphone_call_get_nb_audio_stops(marie_call), audioStreamStopped, unsigned int, "%d"); linphone_call_unref(marie_call); end: // After call, unref the sound card linphone_audio_device_unref(dev0); linphone_audio_device_unref(dev1); linphone_audio_device_unref(current_input_dev); linphone_audio_device_unref(current_output_dev); linphone_audio_device_unref(pauline_dev0); linphone_audio_device_unref(pauline_dev1); linphone_audio_device_unref(pauline_current_input_dev); linphone_audio_device_unref(pauline_current_output_dev); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); bctbx_list_free(lcs); } static void simple_call_with_audio_device_change_during_incoming_early_media(void) { simple_call_with_audio_device_change_base(TRUE, FALSE, FALSE, FALSE, FALSE); } static void simple_call_with_audio_device_change_during_outgoing_early_media(void) { simple_call_with_audio_device_change_base(FALSE, TRUE, FALSE, FALSE, FALSE); } static void simple_call_with_audio_device_change_before_ringback(void) { simple_call_with_audio_device_change_base(FALSE, FALSE, TRUE, FALSE, FALSE); } static void simple_call_with_audio_device_change_during_ringback(void) { simple_call_with_audio_device_change_base(FALSE, FALSE, FALSE, TRUE, FALSE); } static void simple_call_with_audio_device_change_after_ringback(void) { simple_call_with_audio_device_change_base(FALSE, FALSE, FALSE, FALSE, TRUE); } static void simple_call_with_audio_device_change_pingpong(void) {
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
simple_call_with_audio_device_change_base(TRUE, TRUE, TRUE, TRUE, TRUE); } LinphoneAudioDevice *pause_call_changing_device(bool_t enable, bctbx_list_t *lcs, LinphoneCall *call, LinphoneCoreManager *mgr_pausing, LinphoneCoreManager *mgr_paused, LinphoneCoreManager *mgr_change_device, LinphoneAudioDevice *current_dev, LinphoneAudioDevice *dev0, LinphoneAudioDevice *dev1) { int noCallPaused = mgr_pausing->stat.number_of_LinphoneCallPaused; int noCallPausing = mgr_pausing->stat.number_of_LinphoneCallPausing; int noCallPausedByRemote = mgr_paused->stat.number_of_LinphoneCallPausedByRemote; int noCallResuming = mgr_pausing->stat.number_of_LinphoneCallResuming; int noStreamRunningPausing = mgr_pausing->stat.number_of_LinphoneCallStreamsRunning; int noStreamRunningPaused = mgr_paused->stat.number_of_LinphoneCallStreamsRunning; BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(mgr_change_device->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(mgr_change_device->lc), current_dev); BC_ASSERT_FALSE(linphone_core_is_in_conference(mgr_pausing->lc)); linphone_call_pause(call); BC_ASSERT_TRUE(wait_for_list(lcs, &mgr_pausing->stat.number_of_LinphoneCallPausing, (noCallPausing + 1), 5000)); BC_ASSERT_TRUE( wait_for_list(lcs, &mgr_paused->stat.number_of_LinphoneCallPausedByRemote, (noCallPausedByRemote + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &mgr_pausing->stat.number_of_LinphoneCallPaused, (noCallPaused + 1), 5000)); LinphoneAudioDevice *next_dev = change_device(enable, mgr_change_device, current_dev, dev0, dev1); // Check output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(mgr_change_device->lc), next_dev); LinphoneAudioDevice *expected_input_dev = NULL; if (enable || linphone_core_is_in_conference(mgr_change_device->lc)) { // If the call is paused, input soundcard is not used but as it is changed, the getter returns the new sound // card expected_input_dev = next_dev; } else { // If call is paused, input soundcard is not used therefore the current one is NULL expected_input_dev = NULL; } BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(mgr_change_device->lc), expected_input_dev); // stay in pause a little while in order to generate traffic wait_for_until(mgr_pausing->lc, mgr_paused->lc, NULL, 5, 2000); linphone_call_resume(call); BC_ASSERT_TRUE(wait_for_list(lcs, &mgr_pausing->stat.number_of_LinphoneCallStreamsRunning, (noStreamRunningPausing + 1), 5000)); BC_ASSERT_TRUE( wait_for_list(lcs, &mgr_paused->stat.number_of_LinphoneCallStreamsRunning, (noStreamRunningPaused + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &mgr_pausing->stat.number_of_LinphoneCallResuming, (noCallResuming + 1), 5000)); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(mgr_change_device->lc), next_dev); BC_ASSERT_STRING_EQUAL(linphone_audio_device_get_id(linphone_core_get_output_audio_device(mgr_change_device->lc)), linphone_audio_device_get_id(next_dev)); // To know what IDs are BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(mgr_change_device->lc), next_dev); return next_dev; } static void simple_call_with_audio_device_change_during_call_pause_base(bool_t callee, bool_t caller) { bctbx_list_t *lcs; // Marie is the caller
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); // Adding 2 devices to Marie' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc register_device(marie, &dummy_test_snd_card_desc); register_device(marie, &dummy2_test_snd_card_desc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(marie->lc); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *marie_dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(marie_dev0); marie_dev0 = linphone_audio_device_ref(marie_dev0); // 2nd device in the list LinphoneAudioDevice *marie_dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(marie_dev1); marie_dev1 = linphone_audio_device_ref(marie_dev1); // At the start, choose default device for marie i.e. marie_dev0 LinphoneAudioDevice *marie_current_dev = marie_dev0; BC_ASSERT_PTR_NOT_NULL(marie_current_dev); marie_current_dev = linphone_audio_device_ref(marie_current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(NULL, marie->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, marie_dev1); linphone_core_set_default_output_audio_device(marie->lc, marie_dev1); // Pauline is online - ringback can start immediately LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); linphone_core_set_network_reachable(pauline->lc, TRUE); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); // Adding 2 devices to Pauline sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc register_device(pauline, &dummy_test_snd_card_desc); register_device(pauline, &dummy2_test_snd_card_desc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type audio_devices = linphone_core_get_extended_audio_devices(pauline->lc); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *pauline_dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(pauline_dev0); pauline_dev0 = linphone_audio_device_ref(pauline_dev0); // 2nd device in the list LinphoneAudioDevice *pauline_dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(pauline_dev1); pauline_dev1 = linphone_audio_device_ref(pauline_dev1); // At the start, choose default device for pauline i.e. pauline_dev0 LinphoneAudioDevice *pauline_current_dev = pauline_dev0; BC_ASSERT_PTR_NOT_NULL(pauline_current_dev);
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
pauline_current_dev = linphone_audio_device_ref(pauline_current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(lcs, pauline->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(pauline->lc, pauline_dev1); linphone_core_set_default_output_audio_device(pauline->lc, pauline_dev1); LinphoneCallParams *marie_params = linphone_core_create_call_params(marie->lc, NULL); linphone_call_params_set_input_audio_device(marie_params, marie_current_dev); linphone_call_params_set_output_audio_device(marie_params, marie_current_dev); LinphoneCall *marie_call = linphone_core_invite_address_with_params(marie->lc, pauline->identity, marie_params); BC_ASSERT_PTR_NOT_NULL(marie_call); linphone_call_params_unref(marie_params); // Pauline shall receive the call immediately BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1, 5000)); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); if (!BC_ASSERT_PTR_NOT_NULL(pauline_call)) goto end; // Marie should hear ringback as well BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1, 5000)); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), marie_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), marie_current_dev); LinphoneCallParams *pauline_params = linphone_core_create_call_params(pauline->lc, NULL); linphone_call_params_set_input_audio_device(pauline_params, pauline_current_dev); linphone_call_params_set_output_audio_device(pauline_params, pauline_current_dev); // Take call - ringing ends linphone_call_accept_with_params(pauline_call, pauline_params); linphone_call_params_unref(pauline_params); // Start call with a device that it is not the default one linphone_audio_device_unref(pauline_current_dev); pauline_current_dev = linphone_audio_device_ref(pauline_dev1); BC_ASSERT_PTR_NOT_NULL(pauline_current_dev); linphone_audio_device_unref(marie_current_dev); marie_current_dev = linphone_audio_device_ref(marie_dev1); BC_ASSERT_PTR_NOT_NULL(marie_current_dev); // Set audio device to start with a known situation linphone_core_set_input_audio_device(pauline->lc, pauline_current_dev); linphone_core_set_output_audio_device(pauline->lc, pauline_current_dev); linphone_core_set_input_audio_device(marie->lc, marie_current_dev); linphone_core_set_output_audio_device(marie->lc, marie_current_dev); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1)); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Callee pauses call and changes device pauline_current_dev = pause_call_changing_device(callee, lcs, pauline_call, pauline, marie, pauline, pauline_current_dev, pauline_dev0, pauline_dev1); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), marie_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), marie_current_dev); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Callee pauses call and caller changes device marie_current_dev = pause_call_changing_device(callee, lcs, pauline_call, pauline, marie, marie, marie_current_dev, marie_dev0, marie_dev1);
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(pauline->lc), pauline_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(pauline->lc), pauline_current_dev); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Caller pauses call and callee changes device pauline_current_dev = pause_call_changing_device(caller, lcs, marie_call, marie, pauline, pauline, pauline_current_dev, pauline_dev0, pauline_dev1); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), marie_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), marie_current_dev); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // Caller pauses call and changes device marie_current_dev = pause_call_changing_device(caller, lcs, marie_call, marie, pauline, marie, marie_current_dev, marie_dev0, marie_dev1); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(pauline->lc), pauline_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(pauline->lc), pauline_current_dev); // stay in pause a little while in order to generate traffic wait_for_until(pauline->lc, marie->lc, NULL, 5, 2000); // End call linphone_call_terminate(pauline_call); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1)); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); end: // After call, unref the sound card linphone_audio_device_unref(marie_dev0); linphone_audio_device_unref(marie_dev1); linphone_audio_device_unref(marie_current_dev); linphone_core_manager_destroy(marie); linphone_audio_device_unref(pauline_dev0); linphone_audio_device_unref(pauline_dev1); linphone_audio_device_unref(pauline_current_dev); linphone_core_manager_destroy(pauline); bctbx_list_free(lcs); } static void simple_call_with_audio_device_change_during_call_pause_callee(void) { simple_call_with_audio_device_change_during_call_pause_base(TRUE, FALSE); } static void simple_call_with_audio_device_change_during_call_pause_caller(void) { simple_call_with_audio_device_change_during_call_pause_base(FALSE, TRUE); } static void simple_call_with_audio_device_change_during_call_pause_caller_callee(void) { simple_call_with_audio_device_change_during_call_pause_base(TRUE, TRUE); } static void simple_call_with_audio_devices_reload(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); unregister_all_devices(marie); BC_ASSERT_PTR_NULL(linphone_core_get_output_audio_device(marie->lc)); BC_ASSERT_PTR_NULL(linphone_core_get_input_audio_device(marie->lc)); BC_ASSERT_PTR_NULL(linphone_core_get_output_audio_device(pauline->lc)); BC_ASSERT_PTR_NULL(linphone_core_get_input_audio_device(pauline->lc)); BC_ASSERT_PTR_NULL(linphone_core_get_default_input_audio_device( pauline->lc)); // Pauline is using files instead of soundcard, so defaults cards for Pauline are NULL BC_ASSERT_PTR_NULL(linphone_core_get_default_output_audio_device(pauline->lc));
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
BC_ASSERT_TRUE(call(marie, pauline)); for (int i = 0; i < 2; ++i) { BC_ASSERT_PTR_NULL(linphone_core_get_output_audio_device(marie->lc)); // No devices for audio streaming BC_ASSERT_PTR_NULL(linphone_core_get_input_audio_device(marie->lc)); BC_ASSERT_PTR_NULL( linphone_core_get_output_audio_device(pauline->lc)); // Pauline is using files instead of soundcard so all // cards should stay at NULL after accepting the call BC_ASSERT_PTR_NULL(linphone_core_get_input_audio_device(pauline->lc)); LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); BC_ASSERT_PTR_NULL(linphone_call_get_output_audio_device(marie_call)); // No sound card yet BC_ASSERT_PTR_NULL(linphone_call_get_input_audio_device(marie_call)); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); BC_ASSERT_PTR_NULL(linphone_call_get_output_audio_device(pauline_call)); BC_ASSERT_PTR_NULL(linphone_call_get_input_audio_device(pauline_call)); int noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; int nbDevListUpdates = marie->stat.number_of_LinphoneCoreAudioDevicesListUpdated; // Device reconnection register_device(marie, &dummy_test_snd_card_desc); noDevChanges += 2; // This is a new device from nothing. There are 2 updates : input/output BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDevicesListUpdated, nbDevListUpdates + 1, int, "%d"); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); BC_ASSERT_PTR_NOT_NULL(linphone_core_get_output_audio_device(marie->lc)); BC_ASSERT_PTR_NOT_NULL(linphone_core_get_input_audio_device(marie->lc)); BC_ASSERT_PTR_NOT_NULL(linphone_call_get_output_audio_device(marie_call)); BC_ASSERT_PTR_NOT_NULL(linphone_call_get_input_audio_device(marie_call)); bctbx_list_t *audio_devices = linphone_core_get_audio_devices(marie->lc); BC_ASSERT_EQUAL((int)bctbx_list_size(audio_devices), 1, int, "%d"); LinphoneAudioDevice *audio_device = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(audio_device); linphone_audio_device_ref(audio_device); bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); // Core should not be notified of audio device changed BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); linphone_core_set_output_audio_device(marie->lc, audio_device); noDevChanges += 1; // Only output has been changed BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), audio_device); linphone_core_set_input_audio_device(marie->lc, audio_device); noDevChanges += 1; // Only input has been changed BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), audio_device); // Now test when all devices disconnect while being in call unregister_all_devices(marie); linphone_audio_device_unref(audio_device); } end_call(marie, pauline); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); BC_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCoreLastCallEnded, 1, int, "%d"); linphone_core_manager_destroy(pauline); linphone_core_manager_destroy(marie); } static void simple_conference_with_audio_device_change_base(bool_t during_setup, bool_t before_all_join, bool_t after_all_join) { bctbx_list_t *lcs = NULL; // Marie is the caller
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
LinphoneCoreManager *marie = create_mgr_for_conference("marie_rc", TRUE, NULL); unregister_all_devices(marie); // Start with no sound cards bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int native_audio_devices_count = (int)bctbx_list_size(audio_devices); bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); // Adding 2 devices to Marie' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc // This devices are prepended to the list of so that they can be easily accessed later register_device(marie, &dummy_test_snd_card_desc); register_device(marie, &dummy2_test_snd_card_desc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int audio_devices_count = (int)bctbx_list_size(audio_devices); BC_ASSERT_EQUAL(audio_devices_count, (native_audio_devices_count + 2), int, "%d"); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(dev0); linphone_audio_device_ref(dev0); // 2nd device in the list LinphoneAudioDevice *dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(dev1); linphone_audio_device_ref(dev1); // At the start, choose default device i.e. dev0 LinphoneAudioDevice *current_dev = dev0; BC_ASSERT_PTR_NOT_NULL(current_dev); linphone_audio_device_ref(current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(lcs, marie->lc); // Pauline is offline LinphoneCoreManager *pauline = create_mgr_for_conference( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", TRUE, NULL); linphone_core_set_network_reachable(pauline->lc, FALSE); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); lcs = bctbx_list_append(lcs, pauline->lc); LinphoneCoreManager *laure = create_mgr_for_conference(liblinphone_tester_ipv6_available() ? "laure_tcp_rc" : "laure_rc_udp", TRUE, NULL); linphone_core_set_network_reachable(laure->lc, TRUE); lcs = bctbx_list_append(lcs, laure->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, current_dev); linphone_core_set_default_output_audio_device(marie->lc, current_dev); // Laure creates the conference LinphoneConferenceParams *conf_params = linphone_core_create_conference_params_2(laure->lc, NULL); linphone_conference_params_set_video_enabled(conf_params, FALSE); LinphoneConference *conf = linphone_core_create_conference_with_params(laure->lc, conf_params); linphone_conference_params_unref(conf_params); bctbx_list_t *participants = NULL; participants = bctbx_list_append(participants, pauline);
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
participants = bctbx_list_append(participants, marie); int noParticipants = (int)bctbx_list_size(participants); add_participant_to_local_conference_through_invite(lcs, laure, participants, NULL); LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); BC_ASSERT_PTR_NOT_NULL(marie_call); linphone_audio_device_unref(current_dev); current_dev = linphone_audio_device_ref(dev1); BC_ASSERT_PTR_NOT_NULL(current_dev); // Set audio device to start with a known situation - do not use default device linphone_core_set_input_audio_device(marie->lc, current_dev); // This set capture linphone_core_set_output_audio_device(marie->lc, current_dev); // This set Playback linphone_core_set_ringer_device(marie->lc, linphone_audio_device_get_id(current_dev)); // This set ringer // wait a bit before Marie changes device wait_for_list(lcs, NULL, 0, 2000); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); // Incoming call : the output is the ring stream BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev); current_dev = change_device(during_setup, marie, current_dev, dev0, dev1); // wait a bit before Marie accepts the call wait_for_list(lcs, NULL, 0, 2000); linphone_call_accept(marie_call); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneConferenceStateCreationPending, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneConferenceStateCreationPending, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallConnected, 1, 10000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallStreamsRunning, 1, 3000)); // wait a bit before Marie changes device wait_for_list(lcs, NULL, 0, 2000); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); BC_ASSERT_STRING_EQUAL(linphone_audio_device_get_id(linphone_core_get_output_audio_device(marie->lc)), linphone_audio_device_get_id(current_dev)); // To know what IDs are BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev); current_dev = change_device(before_all_join, marie, current_dev, dev0, dev1); // wait a bit before Pauline is reachable wait_for_list(lcs, NULL, 0, 2000); linphone_core_set_network_reachable(pauline->lc, TRUE); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallOutgoingProgress, noParticipants, 2000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1, 10000)); LinphoneCall *pauline_call = linphone_core_get_current_call(pauline->lc); BC_ASSERT_PTR_NOT_NULL(pauline_call); linphone_call_accept(pauline_call); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneConferenceStateCreationPending, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneConferenceStateCreationPending, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneConferenceStateCreated, 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallConnected, noParticipants, 10000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallStreamsRunning, noParticipants, 3000)); // make sure that the two calls from Marie's standpoint are in conference const bctbx_list_t *laure_calls = linphone_core_get_calls(laure->lc); BC_ASSERT_EQUAL((int)bctbx_list_size(laure_calls), noParticipants, int, "%i"); const bctbx_list_t *it; for (it = laure_calls; it != NULL; it = it->next) { BC_ASSERT_TRUE(linphone_call_params_get_local_conference_mode( linphone_call_get_current_params((LinphoneCall *)it->data)) == TRUE); }
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
// wait a bit before Marie changes device wait_for_list(lcs, NULL, 0, 2000); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev); current_dev = change_device(after_all_join, marie, current_dev, dev0, dev1); // wait a bit before ending the conference wait_for_list(lcs, NULL, 0, 5000); terminate_conference(participants, laure, conf, NULL); linphone_conference_unref(conf); destroy_mgr_in_conference(marie); destroy_mgr_in_conference(pauline); destroy_mgr_in_conference(laure); linphone_audio_device_unref(dev0); linphone_audio_device_unref(dev1); linphone_audio_device_unref(current_dev); bctbx_list_free(participants); bctbx_list_free(lcs); } static void simple_conference_with_audio_device_change_during_setup(void) { simple_conference_with_audio_device_change_base(TRUE, FALSE, FALSE); } static void simple_conference_with_audio_device_change_before_all_join(void) { simple_conference_with_audio_device_change_base(FALSE, TRUE, FALSE); } static void simple_conference_with_audio_device_change_after_all_join(void) { simple_conference_with_audio_device_change_base(FALSE, FALSE, TRUE); } static void simple_conference_with_audio_device_change_pingpong(void) { simple_conference_with_audio_device_change_base(TRUE, TRUE, TRUE); } static void simple_conference_with_audio_device_change_during_pause_base(bool_t callee, bool_t caller) { bctbx_list_t *lcs = NULL; // Marie is the caller LinphoneCoreManager *marie = create_mgr_for_conference("marie_rc", TRUE, NULL); // load audio devices and get initial number of cards linphone_core_reload_sound_devices(marie->lc); bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int native_audio_devices_count = (int)bctbx_list_size(audio_devices); bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); MSFactory *factory = linphone_core_get_ms_factory(marie->lc); // Adding 2 devices to Marie' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory); // This devices are prepended to the list of so that they can be easily accessed later ms_snd_card_manager_register_desc(sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(sndcard_manager, &dummy2_test_snd_card_desc); linphone_core_reload_sound_devices(marie->lc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int audio_devices_count = (int)bctbx_list_size(audio_devices); BC_ASSERT_EQUAL(audio_devices_count, (native_audio_devices_count + 2), int, "%d"); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
// type is Unknown device at the head of the list LinphoneAudioDevice *marie_dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(marie_dev0); linphone_audio_device_ref(marie_dev0); // 2nd device in the list LinphoneAudioDevice *marie_dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(marie_dev1); linphone_audio_device_ref(marie_dev1); // At the start, choose default device i.e. dev0 LinphoneAudioDevice *marie_current_dev = marie_dev0; BC_ASSERT_PTR_NOT_NULL(marie_current_dev); linphone_audio_device_ref(marie_current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(lcs, marie->lc); // Pauline is onlineoffline LinphoneCoreManager *pauline = create_mgr_for_conference( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", TRUE, NULL); linphone_core_set_network_reachable(pauline->lc, TRUE); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); // load audio devices and get initial number of cards linphone_core_reload_sound_devices(pauline->lc); audio_devices = linphone_core_get_extended_audio_devices(pauline->lc); native_audio_devices_count = (int)bctbx_list_size(audio_devices); bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); factory = linphone_core_get_ms_factory(pauline->lc); // Adding 2 devices to Marie' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc sndcard_manager = ms_factory_get_snd_card_manager(factory); // This devices are prepended to the list of so that they can be easily accessed later ms_snd_card_manager_register_desc(sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(sndcard_manager, &dummy2_test_snd_card_desc); linphone_core_reload_sound_devices(pauline->lc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type audio_devices = linphone_core_get_extended_audio_devices(pauline->lc); audio_devices_count = (int)bctbx_list_size(audio_devices); BC_ASSERT_EQUAL(audio_devices_count, (native_audio_devices_count + 2), int, "%d"); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *pauline_dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(pauline_dev0); linphone_audio_device_ref(pauline_dev0); // 2nd device in the list LinphoneAudioDevice *pauline_dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(pauline_dev1); linphone_audio_device_ref(pauline_dev1); // At the start, choose default device i.e. dev0 LinphoneAudioDevice *pauline_current_dev = pauline_dev0; BC_ASSERT_PTR_NOT_NULL(pauline_current_dev); linphone_audio_device_ref(pauline_current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref);
1821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
lcs = bctbx_list_append(lcs, pauline->lc); LinphoneCoreManager *laure = create_mgr_for_conference(liblinphone_tester_ipv6_available() ? "laure_tcp_rc" : "laure_rc_udp", TRUE, NULL); linphone_core_set_network_reachable(laure->lc, TRUE); lcs = bctbx_list_append(lcs, laure->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, marie_current_dev); linphone_core_set_default_output_audio_device(marie->lc, marie_current_dev); linphone_core_set_default_input_audio_device(pauline->lc, pauline_current_dev); linphone_core_set_default_output_audio_device(pauline->lc, pauline_current_dev); // Laure creates the conference LinphoneConferenceParams *conf_params = linphone_core_create_conference_params_2(pauline->lc, NULL); linphone_conference_params_set_video_enabled(conf_params, FALSE); LinphoneConference *conf = linphone_core_create_conference_with_params(pauline->lc, conf_params); linphone_conference_params_unref(conf_params); bctbx_list_t *participants = NULL; participants = bctbx_list_append(participants, laure); participants = bctbx_list_append(participants, marie); int noParticipants = (int)bctbx_list_size(participants); add_participant_to_local_conference_through_invite(lcs, pauline, participants, NULL); linphone_audio_device_unref(marie_current_dev); marie_current_dev = linphone_audio_device_ref(marie_dev1); BC_ASSERT_PTR_NOT_NULL(marie_current_dev); linphone_audio_device_unref(pauline_current_dev); pauline_current_dev = linphone_audio_device_ref(pauline_dev1); BC_ASSERT_PTR_NOT_NULL(pauline_current_dev); LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); BC_ASSERT_PTR_NOT_NULL(marie_call); // Set audio device to start with a known situation - do not use default device linphone_core_set_input_audio_device(marie->lc, marie_current_dev); linphone_core_set_output_audio_device(marie->lc, marie_current_dev); linphone_core_set_input_audio_device(pauline->lc, pauline_current_dev); linphone_core_set_output_audio_device(pauline->lc, pauline_current_dev); // wait a bit before Marie accepts the call wait_for_list(lcs, NULL, 0, 2000); linphone_call_accept(marie_call); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallConnected, 1, 10000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1, 3000)); // wait a bit before Pauline is reachable wait_for_list(lcs, NULL, 0, 2000); linphone_core_set_network_reachable(pauline->lc, TRUE); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingProgress, noParticipants, 2000)); BC_ASSERT_TRUE(wait_for_list(lcs, &laure->stat.number_of_LinphoneCallIncomingReceived, 1, 10000)); LinphoneCall *laure_call = linphone_core_get_current_call(laure->lc); BC_ASSERT_PTR_NOT_NULL(laure_call); linphone_call_accept(laure_call); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallConnected, noParticipants, 10000)); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, noParticipants, 3000)); LinphoneCall *pauline_call = NULL; // make sure that the two calls from Marie's standpoint are in conference const bctbx_list_t *pauline_calls = linphone_core_get_calls(pauline->lc); BC_ASSERT_EQUAL((int)bctbx_list_size(pauline_calls), noParticipants, int, "%i"); const bctbx_list_t *it; for (it = pauline_calls; it != NULL; it = it->next) {
1891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
pauline_call = (LinphoneCall *)it->data; BC_ASSERT_TRUE(linphone_call_params_get_local_conference_mode( linphone_call_get_current_params((LinphoneCall *)it->data)) == TRUE); } if (!BC_ASSERT_PTR_NOT_NULL(pauline_call)) goto end; linphone_call_ref(pauline_call); // wait a bit before changing device wait_for_list(lcs, NULL, 0, 2000); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), marie_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), marie_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(pauline->lc), pauline_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(pauline->lc), pauline_current_dev); // Callee pauses call and callee changes device pauline_current_dev = pause_call_changing_device(callee, lcs, marie_call, marie, pauline, pauline, pauline_current_dev, pauline_dev0, pauline_dev1); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), marie_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), marie_current_dev); // wait a bit before Marie changes device wait_for_list(lcs, NULL, 0, 2000); // Caller pauses call and changes device marie_current_dev = pause_call_changing_device(caller, lcs, marie_call, marie, pauline, marie, marie_current_dev, marie_dev0, marie_dev1); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(pauline->lc), pauline_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(pauline->lc), pauline_current_dev); // wait a bit before ending the conference wait_for_list(lcs, NULL, 0, 5000); terminate_conference(participants, pauline, conf, NULL); end: if (pauline_call) linphone_call_unref(pauline_call); linphone_conference_unref(conf); // After call, unref the sound card linphone_audio_device_unref(marie_dev0); linphone_audio_device_unref(marie_dev1); linphone_audio_device_unref(marie_current_dev); destroy_mgr_in_conference(marie); linphone_audio_device_unref(pauline_dev0); linphone_audio_device_unref(pauline_dev1); linphone_audio_device_unref(pauline_current_dev); destroy_mgr_in_conference(pauline); destroy_mgr_in_conference(laure); bctbx_list_free(participants); bctbx_list_free(lcs); } static void simple_conference_with_audio_device_change_during_pause_callee(void) { simple_conference_with_audio_device_change_during_pause_base(TRUE, FALSE); } static void simple_conference_with_audio_device_change_during_pause_caller(void) { simple_conference_with_audio_device_change_during_pause_base(FALSE, TRUE); } static void simple_conference_with_audio_device_change_during_pause_caller_callee(void) { simple_conference_with_audio_device_change_during_pause_base(TRUE, TRUE); } static void conference_with_simple_audio_device_change(void) { bctbx_list_t *lcs = NULL; bctbx_list_t *dev_found = NULL;
1961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
// Marie is the caller LinphoneCoreManager *marie = create_mgr_for_conference("marie_rc", TRUE, NULL); // load audio devices and get initial number of cards linphone_core_reload_sound_devices(marie->lc); bctbx_list_t *marie_audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int native_marie_audio_devices_count = (int)bctbx_list_size(marie_audio_devices); bctbx_list_free_with_data(marie_audio_devices, (void (*)(void *))linphone_audio_device_unref); MSFactory *marie_factory = linphone_core_get_ms_factory(marie->lc); // Adding 4 devices to Marie' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc // - dummy_capture_test_snd_card_desc // - dummy_playback_test_snd_card_desc MSSndCardManager *marie_sndcard_manager = ms_factory_get_snd_card_manager(marie_factory); // This devices are prepended to the list of so that they can be easily accessed later ms_snd_card_manager_register_desc(marie_sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(marie_sndcard_manager, &dummy2_test_snd_card_desc); ms_snd_card_manager_register_desc(marie_sndcard_manager, &dummy_capture_test_snd_card_desc); ms_snd_card_manager_register_desc(marie_sndcard_manager, &dummy_playback_test_snd_card_desc); linphone_core_reload_sound_devices(marie->lc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type marie_audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int marie_audio_devices_count = (int)bctbx_list_size(marie_audio_devices); BC_ASSERT_EQUAL(marie_audio_devices_count, (native_marie_audio_devices_count + 4), int, "%d"); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown 1st device dev_found = bctbx_list_find_custom(marie_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *marie_dev0 = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(marie_dev0); linphone_audio_device_ref(marie_dev0); // 2nd device dev_found = bctbx_list_find_custom(marie_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY2_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *marie_dev1 = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(marie_dev1); linphone_audio_device_ref(marie_dev1); // device dummy_playback in the list dev_found = bctbx_list_find_custom(marie_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_PLAYBACK_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *marie_playback = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(marie_playback); linphone_audio_device_ref(marie_playback); // device dummy_capture in the list dev_found = bctbx_list_find_custom(marie_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_CAPTURE_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *marie_capture = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(marie_capture); linphone_audio_device_ref(marie_capture); // At the start, choose default device i.e. marie_dev0 LinphoneAudioDevice *marie_current_dev = marie_dev0; BC_ASSERT_PTR_NOT_NULL(marie_current_dev); linphone_audio_device_ref(marie_current_dev);
2031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
// Unref cards bctbx_list_free_with_data(marie_audio_devices, (void (*)(void *))linphone_audio_device_unref); // Pauline is offline LinphoneCoreManager *pauline = create_mgr_for_conference( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", TRUE, NULL); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); LinphoneCoreManager *laure = create_mgr_for_conference(liblinphone_tester_ipv6_available() ? "laure_tcp_rc" : "laure_rc_udp", TRUE, NULL); // Do not allow Laure to use files as the goal of the test is to test audio routes linphone_core_set_use_files(laure->lc, FALSE); // Laure creates the conference LinphoneConferenceParams *conf_params = linphone_core_create_conference_params_2(laure->lc, NULL); linphone_conference_params_set_video_enabled(conf_params, FALSE); LinphoneConference *conf = linphone_core_create_conference_with_params(laure->lc, conf_params); linphone_conference_params_unref(conf_params); // load audio devices and get initial number of cards linphone_core_reload_sound_devices(laure->lc); bctbx_list_t *laure_audio_devices = linphone_core_get_extended_audio_devices(laure->lc); int native_laure_audio_devices_count = (int)bctbx_list_size(laure_audio_devices); bctbx_list_free_with_data(laure_audio_devices, (void (*)(void *))linphone_audio_device_unref); MSFactory *laure_factory = linphone_core_get_ms_factory(laure->lc); // Adding 2 devices to Laure' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc MSSndCardManager *laure_sndcard_manager = ms_factory_get_snd_card_manager(laure_factory); // This devices are prepended to the list of so that they can be easily accessed later ms_snd_card_manager_register_desc(laure_sndcard_manager, &dummy2_test_snd_card_desc); ms_snd_card_manager_register_desc(laure_sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(laure_sndcard_manager, &dummy_capture_test_snd_card_desc); ms_snd_card_manager_register_desc(laure_sndcard_manager, &dummy_playback_test_snd_card_desc); linphone_core_reload_sound_devices(laure->lc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type laure_audio_devices = linphone_core_get_extended_audio_devices(laure->lc); int laure_audio_devices_count = (int)bctbx_list_size(laure_audio_devices); BC_ASSERT_EQUAL(laure_audio_devices_count, (native_laure_audio_devices_count + 4), int, "%d"); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown 1st device dev_found = bctbx_list_find_custom(laure_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY2_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *laure_dev0 = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(laure_dev0); linphone_audio_device_ref(laure_dev0); // 2nd device dev_found = bctbx_list_find_custom(laure_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *laure_dev1 = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(laure_dev1); linphone_audio_device_ref(laure_dev1); // device dummy_playback in the list dev_found = bctbx_list_find_custom(laure_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_PLAYBACK_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *laure_playback = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(laure_playback); linphone_audio_device_ref(laure_playback);
2101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170
// device dummy_capture in the list dev_found = bctbx_list_find_custom(laure_audio_devices, (bctbx_compare_func)audio_device_name_match, DUMMY_CAPTURE_TEST_SOUNDCARD); BC_ASSERT_PTR_NOT_NULL(dev_found); LinphoneAudioDevice *laure_capture = (dev_found) ? (LinphoneAudioDevice *)bctbx_list_get_data(dev_found) : NULL; BC_ASSERT_PTR_NOT_NULL(laure_capture); linphone_audio_device_ref(laure_capture); // At the start, choose default device i.e. laure_dev0 LinphoneAudioDevice *laure_current_dev = laure_dev0; BC_ASSERT_PTR_NOT_NULL(laure_current_dev); linphone_audio_device_ref(laure_current_dev); // Unref cards bctbx_list_free_with_data(laure_audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(lcs, laure->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, marie_current_dev); linphone_core_set_default_output_audio_device(marie->lc, marie_current_dev); linphone_core_set_default_input_audio_device(laure->lc, laure_current_dev); linphone_core_set_default_output_audio_device(laure->lc, laure_current_dev); bctbx_list_t *participants = NULL; participants = bctbx_list_append(participants, pauline); participants = bctbx_list_append(participants, marie); initiate_calls(participants, laure); unsigned int idx = 0; LinphoneCoreManager *prev_mgr = NULL; for (bctbx_list_t *it = participants; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = (LinphoneCoreManager *)bctbx_list_get_data(it); LinphoneCore *c = m->lc; lcs = bctbx_list_append(lcs, c); if (prev_mgr != NULL) { LinphoneCall *m_called_by_laure = linphone_core_get_current_call(prev_mgr->lc); LinphoneCall *laure_call_m = linphone_core_get_call_by_remote_address2(laure->lc, prev_mgr->identity); BC_ASSERT_TRUE(pause_call_1(laure, laure_call_m, prev_mgr, m_called_by_laure)); } const LinphoneAddress *caller_uri = m->identity; LinphoneCall *laure_call = linphone_core_get_call_by_remote_address2(laure->lc, caller_uri); BC_ASSERT_PTR_NOT_NULL(laure_call); // Take call - ringing ends linphone_call_accept(laure_call); idx++; BC_ASSERT_TRUE(wait_for_until(m->lc, laure->lc, &m->stat.number_of_LinphoneCallConnected, 1, 5000)); BC_ASSERT_TRUE(wait_for_until(m->lc, laure->lc, &m->stat.number_of_LinphoneCallStreamsRunning, 1, 5000)); BC_ASSERT_TRUE(wait_for_until(m->lc, laure->lc, &laure->stat.number_of_LinphoneCallConnected, idx, 5000)); BC_ASSERT_TRUE(wait_for_until(m->lc, laure->lc, &laure->stat.number_of_LinphoneCallStreamsRunning, idx, 5000)); prev_mgr = m; } LinphoneCall *marie_call = linphone_core_get_current_call(marie->lc); BC_ASSERT_PTR_NOT_NULL(marie_call); int noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; if (marie_call) {
2171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
BC_ASSERT_PTR_NOT_NULL(marie_playback); if (marie_playback) { linphone_call_set_output_audio_device(marie_call, marie_playback); } BC_ASSERT_PTR_NOT_NULL(marie_capture); if (marie_capture) { linphone_call_set_input_audio_device(marie_call, marie_capture); } } BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (noDevChanges + 2), int, "%d"); // Check Marie's output device BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), marie_playback); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), marie_capture); LinphoneCall *laure_call = linphone_core_get_current_call(laure->lc); BC_ASSERT_PTR_NOT_NULL(laure_call); noDevChanges = laure->stat.number_of_LinphoneCoreAudioDeviceChanged; if (laure_call) { BC_ASSERT_PTR_NOT_NULL(laure_playback); if (laure_playback) { linphone_call_set_output_audio_device(laure_call, laure_playback); } BC_ASSERT_PTR_NOT_NULL(laure_capture); if (laure_capture) { linphone_call_set_input_audio_device(laure_call, laure_capture); } } BC_ASSERT_EQUAL(laure->stat.number_of_LinphoneCoreAudioDeviceChanged, (noDevChanges + 2), int, "%d"); // Check Laure's output device BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(laure_call), laure_playback); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(laure_call), laure_capture); add_calls_to_local_conference(lcs, laure, conf, participants, FALSE); // wait a bit before Marie changes device wait_for_list(lcs, NULL, 0, 2000); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), marie_capture); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), marie_playback); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), marie_capture); BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), marie_playback); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(laure->lc), laure_capture); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(laure->lc), laure_playback); BC_ASSERT_PTR_EQUAL(linphone_conference_get_input_audio_device(conf), laure_capture); BC_ASSERT_PTR_EQUAL(linphone_conference_get_output_audio_device(conf), laure_playback); // Set invalid audio device to the call noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_call_set_input_audio_device(marie_call, marie_playback); linphone_call_set_output_audio_device(marie_call, marie_capture); wait_for_list(lcs, NULL, 0, 1000); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), marie_capture); BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), marie_playback); // Set invalid audio device to the conference noDevChanges = laure->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_conference_set_input_audio_device(conf, laure_playback); linphone_conference_set_output_audio_device(conf, laure_capture); wait_for_list(lcs, NULL, 0, 1000); BC_ASSERT_EQUAL(laure->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_conference_get_input_audio_device(conf), laure_capture); BC_ASSERT_PTR_EQUAL(linphone_conference_get_output_audio_device(conf), laure_playback);
2241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310
// Set again the same audio device to the call noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_call_set_input_audio_device(marie_call, marie_capture); linphone_call_set_output_audio_device(marie_call, marie_playback); wait_for_list(lcs, NULL, 0, 1000); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_call_get_input_audio_device(marie_call), marie_capture); BC_ASSERT_PTR_EQUAL(linphone_call_get_output_audio_device(marie_call), marie_playback); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(laure->lc), laure_capture); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(laure->lc), laure_playback); BC_ASSERT_PTR_EQUAL(linphone_conference_get_input_audio_device(conf), laure_capture); BC_ASSERT_PTR_EQUAL(linphone_conference_get_output_audio_device(conf), laure_playback); // Set invalid audio device to the conference noDevChanges = laure->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_conference_set_input_audio_device(conf, laure_capture); linphone_conference_set_output_audio_device(conf, laure_playback); wait_for_list(lcs, NULL, 0, 1000); BC_ASSERT_EQUAL(laure->stat.number_of_LinphoneCoreAudioDeviceChanged, noDevChanges, int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_conference_get_input_audio_device(conf), laure_capture); BC_ASSERT_PTR_EQUAL(linphone_conference_get_output_audio_device(conf), laure_playback); marie_current_dev = change_device(TRUE, marie, marie_current_dev, marie_dev0, marie_dev1); laure_current_dev = change_device(TRUE, laure, laure_current_dev, laure_dev0, laure_dev1); // wait a bit before Marie and Laure change devices wait_for_list(lcs, NULL, 0, 2000); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), marie_current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(laure->lc), laure_current_dev); terminate_conference(participants, laure, conf, NULL); bctbx_list_free(lcs); bctbx_list_free(participants); linphone_audio_device_unref(marie_dev0); linphone_audio_device_unref(marie_dev1); linphone_audio_device_unref(marie_playback); linphone_audio_device_unref(marie_capture); linphone_audio_device_unref(marie_current_dev); linphone_audio_device_unref(laure_dev0); linphone_audio_device_unref(laure_dev1); linphone_audio_device_unref(laure_playback); linphone_audio_device_unref(laure_capture); linphone_audio_device_unref(laure_current_dev); linphone_conference_unref(conf); destroy_mgr_in_conference(marie); destroy_mgr_in_conference(pauline); destroy_mgr_in_conference(laure); } static void regex_card_selection(void) { LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc"); linphone_core_reload_sound_devices(marie->lc); MSFactory *factory = linphone_core_get_ms_factory(marie->lc); MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory); ms_snd_card_manager_register_desc(sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(sndcard_manager, &dummy2_test_snd_card_desc); linphone_core_reload_sound_devices(marie->lc); // Get dummy MSSndCard *card = ms_snd_card_manager_get_card(sndcard_manager, ".*dummy .*"); if (!BC_ASSERT_PTR_NOT_NULL(card)) goto end; BC_ASSERT_STRING_EQUAL(card->name, DUMMY_TEST_SOUNDCARD); // Get dummy2
2311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
card = ms_snd_card_manager_get_card(sndcard_manager, ".*dummy2 .*"); if (!BC_ASSERT_PTR_NOT_NULL(card)) goto end; BC_ASSERT_STRING_EQUAL(card->name, DUMMY2_TEST_SOUNDCARD); // Get a card only from filter card = ms_snd_card_manager_get_card(sndcard_manager, "dummyTest?( .*)?:.*"); if (!BC_ASSERT_PTR_NOT_NULL(card)) goto end; BC_ASSERT_STRING_EQUAL(card->desc->driver_type, "dummyTest"); // Get a card only from filter card = ms_snd_card_manager_get_card(sndcard_manager, "dummyTest2?( .*)?:.*"); if (!BC_ASSERT_PTR_NOT_NULL(card)) goto end; BC_ASSERT_STRING_EQUAL(card->desc->driver_type, "dummyTest2"); // Get a card from bad filter and good id card = ms_snd_card_manager_get_card(sndcard_manager, "dummyTest?( .*)?:.*dummy2.*"); if (!BC_ASSERT_PTR_NULL(card)) goto end; // Get a card from good filter and bad id card = ms_snd_card_manager_get_card(sndcard_manager, "dummyTest2?( .*)?:.*dummy3.*"); if (!BC_ASSERT_PTR_NULL(card)) goto end; // Get a card from good filter and id card = ms_snd_card_manager_get_card(sndcard_manager, "dummyTest2?( .*)?:.*dummy2.*"); if (!BC_ASSERT_PTR_NOT_NULL(card)) goto end; BC_ASSERT_STRING_EQUAL(card->name, DUMMY2_TEST_SOUNDCARD); // ID doesn't exists card = ms_snd_card_manager_get_card(sndcard_manager, ".*dummy3.*"); if (!BC_ASSERT_PTR_NULL(card)) goto end; end: linphone_core_manager_destroy(marie); } static void simple_conference_with_audio_device_change_using_public_api(void) { bctbx_list_t *lcs = NULL; // Marie is the caller LinphoneCoreManager *marie = create_mgr_for_conference("marie_rc", TRUE, NULL); // load audio devices and get initial number of cards linphone_core_reload_sound_devices(marie->lc); bctbx_list_t *audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int native_audio_devices_count = (int)bctbx_list_size(audio_devices); bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); MSFactory *factory = linphone_core_get_ms_factory(marie->lc); // Adding 2 devices to Marie' sound card manager: // - dummy_test_snd_card_desc // - dummy2_test_snd_card_desc MSSndCardManager *sndcard_manager = ms_factory_get_snd_card_manager(factory); // This devices are prepended to the list of so that they can be easily accessed later ms_snd_card_manager_register_desc(sndcard_manager, &dummy_test_snd_card_desc); ms_snd_card_manager_register_desc(sndcard_manager, &dummy2_test_snd_card_desc); linphone_core_reload_sound_devices(marie->lc); // Choose Marie's audio devices // Use linphone_core_get_extended_audio_devices instead of linphone_core_get_audio_devices because we added 2 BT // devices, therefore we want the raw list In fact, linphone_core_get_audio_devices returns only 1 device per type audio_devices = linphone_core_get_extended_audio_devices(marie->lc); int audio_devices_count = (int)bctbx_list_size(audio_devices); BC_ASSERT_EQUAL(audio_devices_count, (native_audio_devices_count + 2), int, "%d"); // As new devices are prepended, they can be easily accessed and we do not run the risk of gettting a device whose // type is Unknown device at the head of the list LinphoneAudioDevice *dev0 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices); BC_ASSERT_PTR_NOT_NULL(dev0); linphone_audio_device_ref(dev0); // 2nd device in the list LinphoneAudioDevice *dev1 = (LinphoneAudioDevice *)bctbx_list_get_data(audio_devices->next); BC_ASSERT_PTR_NOT_NULL(dev1); linphone_audio_device_ref(dev1);
2381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450
// At the start, choose default device i.e. dev0 LinphoneAudioDevice *current_dev = dev0; BC_ASSERT_PTR_NOT_NULL(current_dev); linphone_audio_device_ref(current_dev); // Unref cards bctbx_list_free_with_data(audio_devices, (void (*)(void *))linphone_audio_device_unref); lcs = bctbx_list_append(lcs, marie->lc); LinphoneCoreManager *pauline = create_mgr_for_conference( transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc", TRUE, NULL); // Do not allow Pauline to use files as the goal of the test is to test audio routes linphone_core_set_use_files(pauline->lc, FALSE); lcs = bctbx_list_append(lcs, pauline->lc); LinphoneCoreManager *laure = create_mgr_for_conference(liblinphone_tester_ipv6_available() ? "laure_tcp_rc" : "laure_rc_udp", TRUE, NULL); lcs = bctbx_list_append(lcs, laure->lc); // Set audio device to start with a known situation linphone_core_set_default_input_audio_device(marie->lc, current_dev); linphone_core_set_default_output_audio_device(marie->lc, current_dev); // Laure creates the conference LinphoneConferenceParams *conf_params = linphone_core_create_conference_params_2(marie->lc, NULL); linphone_conference_params_set_video_enabled(conf_params, FALSE); LinphoneConference *conf = linphone_core_create_conference_with_params(marie->lc, conf_params); BC_ASSERT_PTR_NOT_NULL(conf); linphone_conference_params_unref(conf_params); bctbx_list_t *participants = NULL; participants = bctbx_list_append(participants, pauline); participants = bctbx_list_append(participants, laure); initiate_calls(participants, marie); unsigned int idx = 0; LinphoneCoreManager *prev_mgr = NULL; for (bctbx_list_t *it = participants; it; it = bctbx_list_next(it)) { LinphoneCoreManager *m = (LinphoneCoreManager *)bctbx_list_get_data(it); if (prev_mgr != NULL) { LinphoneCall *m_called_by_marie = linphone_core_get_current_call(prev_mgr->lc); LinphoneCall *marie_call_m = linphone_core_get_call_by_remote_address2(marie->lc, prev_mgr->identity); BC_ASSERT_TRUE(pause_call_1(marie, marie_call_m, prev_mgr, m_called_by_marie)); } const LinphoneAddress *caller_uri = m->identity; LinphoneCall *marie_call = linphone_core_get_call_by_remote_address2(marie->lc, caller_uri); BC_ASSERT_PTR_NOT_NULL(marie_call); // Take call - ringing ends linphone_call_accept(marie_call); idx++; BC_ASSERT_TRUE(wait_for_until(m->lc, marie->lc, &m->stat.number_of_LinphoneCallConnected, 1, 5000)); BC_ASSERT_TRUE(wait_for_until(m->lc, marie->lc, &m->stat.number_of_LinphoneCallStreamsRunning, 1, 5000)); BC_ASSERT_TRUE(wait_for_until(m->lc, marie->lc, &marie->stat.number_of_LinphoneCallConnected, idx, 5000)); BC_ASSERT_TRUE(wait_for_until(m->lc, marie->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, idx, 5000)); prev_mgr = m; } add_calls_to_local_conference(lcs, marie, conf, participants, FALSE); BC_ASSERT_PTR_EQUAL(conf, linphone_core_get_conference(marie->lc));
2451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
wait_for_list(lcs, NULL, 0, 2000); BC_ASSERT_PTR_EQUAL(linphone_core_get_output_audio_device(marie->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_core_get_input_audio_device(marie->lc), current_dev); BC_ASSERT_PTR_EQUAL(linphone_conference_get_output_audio_device(conf), current_dev); BC_ASSERT_PTR_EQUAL(linphone_conference_get_input_audio_device(conf), current_dev); linphone_audio_device_unref(current_dev); current_dev = linphone_audio_device_ref(dev1); BC_ASSERT_PTR_NOT_NULL(current_dev); int noDevChanges = marie->stat.number_of_LinphoneCoreAudioDeviceChanged; linphone_conference_set_output_audio_device(conf, current_dev); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (noDevChanges + 1), int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_conference_get_output_audio_device(conf), current_dev); linphone_conference_set_input_audio_device(conf, current_dev); BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneCoreAudioDeviceChanged, (noDevChanges + 2), int, "%d"); BC_ASSERT_PTR_EQUAL(linphone_conference_get_input_audio_device(conf), current_dev); terminate_conference(participants, marie, conf, NULL); bctbx_list_free(lcs); bctbx_list_free(participants); linphone_conference_unref(conf); linphone_audio_device_unref(dev0); linphone_audio_device_unref(dev1); linphone_audio_device_unref(current_dev); destroy_mgr_in_conference(marie); destroy_mgr_in_conference(pauline); destroy_mgr_in_conference(laure); } test_t audio_routes_tests[] = { TEST_NO_TAG("Simple call with audio devices reload", simple_call_with_audio_devices_reload), TEST_NO_TAG("Call with disconnecting device before ringback", call_with_disconnecting_device_before_ringback), TEST_NO_TAG("Call with disconnecting device during ringback", call_with_disconnecting_device_during_ringback), TEST_NO_TAG("Call with disconnecting device after ringback", call_with_disconnecting_device_after_ringback), TEST_NO_TAG("Call with audio device change using public API", call_with_audio_device_change_using_public_api), TEST_NO_TAG("Call with unreliable device", call_with_unreliable_device), TEST_NO_TAG("Simple call with audio device change during incoming early media", simple_call_with_audio_device_change_during_incoming_early_media), TEST_NO_TAG("Simple call with audio device change during outgoing early media", simple_call_with_audio_device_change_during_outgoing_early_media), TEST_NO_TAG("Simple call with audio device change before ringback", simple_call_with_audio_device_change_before_ringback), TEST_NO_TAG("Simple call with audio device change during ringback", simple_call_with_audio_device_change_during_ringback), TEST_NO_TAG("Simple call with audio device change after ringback", simple_call_with_audio_device_change_after_ringback), TEST_NO_TAG("Simple call with audio device change ping-pong", simple_call_with_audio_device_change_pingpong), TEST_NO_TAG("Simple call with audio device change same audio device pingpong", simple_call_with_audio_device_change_same_audio_device_pingpong), TEST_NO_TAG("Simple call with audio device change during call pause callee", simple_call_with_audio_device_change_during_call_pause_callee), TEST_NO_TAG("Simple call with audio device change during call pause caller", simple_call_with_audio_device_change_during_call_pause_caller), TEST_NO_TAG("Simple call with audio device change during call pause both parties", simple_call_with_audio_device_change_during_call_pause_caller_callee), TEST_NO_TAG("Conference with simple audio device change", conference_with_simple_audio_device_change), TEST_NO_TAG("Simple conference with audio device change using public API", simple_conference_with_audio_device_change_using_public_api), TEST_NO_TAG("Simple conference with audio device change during setup", simple_conference_with_audio_device_change_during_setup), TEST_NO_TAG("Simple conference with audio device change before all join", simple_conference_with_audio_device_change_before_all_join), TEST_NO_TAG("Simple conference with audio device change after all join", simple_conference_with_audio_device_change_after_all_join),
25212522252325242525252625272528252925302531253225332534253525362537253825392540
TEST_NO_TAG("Simple conference with audio device change ping pong", simple_conference_with_audio_device_change_pingpong), TEST_NO_TAG("Simple conference with audio device change during pause callee", simple_conference_with_audio_device_change_during_pause_callee), TEST_NO_TAG("Simple conference with audio device change during pause caller", simple_conference_with_audio_device_change_during_pause_caller), TEST_NO_TAG("Simple conference with audio device change during pause both parties", simple_conference_with_audio_device_change_during_pause_caller_callee), TEST_NO_TAG("Regex audio card selection", regex_card_selection) }; test_suite_t audio_routes_test_suite = {"Audio Routes", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, sizeof(audio_routes_tests) / sizeof(audio_routes_tests[0]), audio_routes_tests, 0};