Newer
Older
/*
* Copyright (c) 2010-2019 Belledonne Communications SARL.
*
* This file is part of Liblinphone.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
#include "linphone/core.h"
François Grisez
committed
#include "linphone/logging.h"
#include "logging-private.h"
#include "liblinphone_tester.h"
#include <bctoolbox/tester.h>
#include "shared_tester_functions.h"

Julien Wadel
committed
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#ifdef _WIN32
#if defined(__MINGW32__) || !defined(WINAPI_FAMILY_PARTITION) || !defined(WINAPI_PARTITION_DESKTOP)
#define LINPHONE_WINDOWS_DESKTOP 1
#elif defined(WINAPI_FAMILY_PARTITION)
//See bctoolbox/include/port.h for WINAPI_PARTITION checker
#if defined(WINAPI_PARTITION_DESKTOP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP)
#define LINPHONE_WINDOWS_DESKTOP 1
#elif defined (WINAPI_PARTITION_PC_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PC_APP)
#define LINPHONE_WINDOWS_DESKTOP 1
#define LINPHONE_WINDOWS_UNIVERSAL 1
#define LINPHONE_WINDOWS_UWP 1
#elif defined(WINAPI_PARTITION_PHONE_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_PHONE_APP)
#define LINPHONE_WINDOWS_PHONE 1
#elif defined(WINAPI_PARTITION_APP) && WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
#define LINPHONE_WINDOWS_UNIVERSAL 1
#endif
#endif
#endif
#ifdef _MSC_VER
#if (_MSC_VER >= 1900)
#define LINPHONE_MSC_VER_GREATER_19
#endif
#endif

Simon Morlat
committed
#define SKIP_PULSEAUDIO 1
#if _WIN32
#define unlink _unlink
#endif
Simon Morlat
committed
static char *liblinphone_tester_empty_rc_path = NULL;
static int liblinphone_tester_keep_accounts_flag = 0;
Ghislain MARY
committed
static bool_t liblinphone_tester_keep_record_files = FALSE;
static bool_t liblinphone_tester_leak_detector_disabled = FALSE;
bool_t liblinphone_tester_keep_uuid = FALSE;
bool_t liblinphone_tester_tls_support_disabled = FALSE;
Gautier Pelloux-Prayer
committed
int manager_count = 0;
Gautier Pelloux-Prayer
committed
int leaked_objects_count = 0;
const MSAudioDiffParams audio_cmp_params = {10,200};
const char* flexisip_tester_dns_server = "fs-test-3.linphone.org";
bctbx_list_t *flexisip_tester_dns_ip_addresses = NULL;
const char* test_domain="sipopen.example.org";
const char* auth_domain="sip.example.org";
const char* test_username="liblinphone_tester";
const char* test_sha_username="liblinphone_sha_tester";

Simon Morlat
committed
const char* pure_sha256_user="pure_sha256_user";
const char* test_password="secret";
const char* test_route="sip2.linphone.org";
const char *userhostsfile = "tester_hosts";
const char *file_transfer_url="https://transfer.example.org:9444/flexisip-http-file-transfer-server/hft.php";
const char *file_transfer_url_tls_client_auth="https://transfer.example.org:9445/flexisip-http-file-transfer-server/hft.php";
const char *file_transfer_url_digest_auth="https://transfer.example.org:9446/flexisip-http-file-transfer-server/hft.php";
// Get proxy on the server using digest auth on sip.example.org
const char *file_transfer_get_proxy="https://transfer.example.org:9446/flexisip-http-file-transfer-server/download.php";
const char *file_transfer_url_digest_auth_any_domain="https://transfer.example.org:9447/flexisip-http-file-transfer-server/hft.php";
const char *file_transfer_url_small_files="https://transfer.example.org:9448/flexisip-http-file-transfer-server/hft.php";
const char *file_transfer_url_digest_auth_external_domain="https://transfer.external-domain.org:9544/flexisip-http-file-transfer-server/hft.php";
// Get proxy on the server using digest auth on sip.external-domain.org
const char *file_transfer_get_proxy_external_domain="https://transfer.external-domain.org:9544/flexisip-http-file-transfer-server/download.php";
// These lime server authenticate user using Digest auth only on sip.example.org domain
const char *lime_server_c25519_url="https://lime.wildcard1.linphone.org:8443/lime-server-c25519/lime-server.php";
const char *lime_server_c448_url="https://lime.wildcard1.linphone.org:8443/lime-server-c448/lime-server.php";
// These lime server authenticate user using Digest auth only on any auth domain (providing the flexisip base can authenticate the user)
const char *lime_server_any_domain_c25519_url="https://lime.wildcard1.linphone.org:8442/lime-server-c25519/lime-server.php";
const char *lime_server_any_domain_c448_url="https://lime.wildcard1.linphone.org:8442/lime-server-c448/lime-server.php";
// These lime server authenticate user using TLS auth only
const char *lime_server_c25519_tlsauth_req_url="https://lime.wildcard1.linphone.org:8543/lime-server-c25519/lime-server.php";
const char *lime_server_c448_tlsauth_req_url="https://lime.wildcard1.linphone.org:8543/lime-server-c448/lime-server.php";
// These lime server authenticate user using optionnal TLS auth, falling back on digest auth if client did not provide a client certificate
const char *lime_server_c25519_tlsauth_opt_url="https://lime.wildcard1.linphone.org:8544/lime-server-c25519/lime-server.php";
const char *lime_server_c448_tlsauth_opt_url="https://lime.wildcard1.linphone.org:8544/lime-server-c448/lime-server.php";
// Lime server using TLS and digest auth on external-domain
const char *lime_server_c25519_external_url="https://lime.external-domain.org:8643/lime-server-c25519/lime-server.php";
const char *lime_server_c448_external_url="https://lime.external-domain.org:8643/lime-server-c448/lime-server.php";
bool_t liblinphonetester_ipv6 = TRUE;
const char * liblinphone_tester_ipv6_probing_address = "2a01:e00::2";
bool_t liblinphonetester_show_account_manager_logs = FALSE;
bool_t liblinphonetester_no_account_creator = FALSE;
int liblinphonetester_transport_timeout = 9000; /*milliseconds. it is set to such low value to workaround a problem with our Freebox v6 when connecting to Ipv6 addresses.
It was found that the freebox sometimes block SYN-ACK packets, which prevents connection to be succesful.
Thanks to the timeout, it will fallback to IPv4*/
char* message_external_body_url=NULL;
static const char *notify_content="<somexml2>blabla</somexml2>";
Simon Morlat
committed
const char *liblinphone_tester_mire_id="Mire: Mire (synthetic moving picture)";
const char *liblinphone_tester_static_image_id="StaticImage: Static picture";
Simon Morlat
committed
static void network_reachable(LinphoneCore *lc, bool_t reachable) {
jehan
committed
stats* counters;
ms_message("Network reachable [%s]",reachable?"TRUE":"FALSE");
counters = get_stats(lc);
if (reachable)
counters->number_of_NetworkReachableTrue++;
else
counters->number_of_NetworkReachableFalse++;
}
void liblinphone_tester_clock_start(MSTimeSpec *start){
ms_get_cur_time(start);
}
bool_t liblinphone_tester_clock_elapsed(const MSTimeSpec *start, int value_ms){
MSTimeSpec current;
ms_get_cur_time(¤t);
if ((((current.tv_sec-start->tv_sec)*1000LL) + ((current.tv_nsec-start->tv_nsec)/1000000LL))>=value_ms)
return TRUE;
return FALSE;
}
LinphoneAddress * create_linphone_address(const char * domain) {
return create_linphone_address_for_algo(domain,NULL);
}
LinphoneAddress * create_linphone_address_for_algo(const char * domain, const char* username) {
LinphoneAddress *addr = linphone_address_new(NULL);
if (!BC_ASSERT_PTR_NOT_NULL(addr)) return NULL;
/* For clients who support different algorithms, their usernames must be differnet for having diffrent forms of password */
if (username) linphone_address_set_username(addr,username);
else linphone_address_set_username(addr,test_username);
if (username) BC_ASSERT_STRING_EQUAL(username, linphone_address_get_username(addr));
else BC_ASSERT_STRING_EQUAL(test_username, linphone_address_get_username(addr));
if (!domain) domain = test_route;
linphone_address_set_domain(addr,domain);
BC_ASSERT_STRING_EQUAL(domain, linphone_address_get_domain(addr));
linphone_address_set_display_name(addr, NULL);
linphone_address_set_display_name(addr, "Mr Tester");
BC_ASSERT_STRING_EQUAL("Mr Tester", linphone_address_get_display_name(addr));
return addr;
static void auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain) {
stats* counters;

Simon Morlat
committed
ms_message("Auth info requested (deprecated callback) for user id [%s] at realm [%s]\n", username, realm);
counters = get_stats(lc);
counters->number_of_auth_info_requested++;
}
void reset_counters( stats* counters) {
if (counters->last_received_chat_message) linphone_chat_message_unref(counters->last_received_chat_message);
if (counters->last_received_info_message) linphone_info_message_unref(counters->last_received_info_message);
if (counters->dtmf_list_received) bctbx_free(counters->dtmf_list_received);
memset(counters,0,sizeof(stats));
}
static void setup_dns(LinphoneCore *lc, const char *path){
if (flexisip_tester_dns_ip_addresses){
linphone_core_set_dns_servers(lc, flexisip_tester_dns_ip_addresses);
}else if (strcmp(userhostsfile, "none") != 0) {
François Grisez
committed
char *dnsuserhostspath = strchr(userhostsfile, '/') ? ms_strdup(userhostsfile) : ms_strdup_printf("%s/%s", path, userhostsfile);
sal_set_dns_user_hosts_file(linphone_core_get_sal(lc), dnsuserhostspath);
ms_free(dnsuserhostspath);
} else{
bctbx_warning("No dns-hosts file and no flexisip-tester dns server used.");
François Grisez
committed
}
}
void configure_lc(LinphoneCore *lc, const char *path, void *user_data) {
linphone_core_enable_ipv6(lc, liblinphonetester_ipv6);
linphone_core_set_sip_transport_timeout(lc, liblinphonetester_transport_timeout);
linphone_core_set_user_data(lc, user_data);
sal_enable_test_features(linphone_core_get_sal(lc), TRUE);
belle_sip_stack_set_dns_engine(sal_get_stack_impl(linphone_core_get_sal(lc)), BELLE_SIP_DNS_DNS_C); // Make sure we are not using Apple DNS Service during liblinphone tests
setup_dns(lc, path);
}
LinphoneCore *configure_lc_from(LinphoneCoreCbs *cbs, const char *path, LinphoneConfig *config, void *user_data) {
LinphoneCore *lc;
Guillaume BIENKOWSKI
committed
char *ringpath = NULL;
char *ringbackpath = NULL;
char *rootcapath = NULL;
char *nowebcampath = NULL;
Guillaume BIENKOWSKI
committed
// setup dynamic-path assets
ringpath = ms_strdup_printf("%s/sounds/oldphone.wav",path);
ringbackpath = ms_strdup_printf("%s/sounds/ringback.wav", path);
nowebcampath = ms_strdup_printf("%s/images/nowebcamCIF.jpg", path);
rootcapath = ms_strdup_printf("%s/certificates/cn/cafile.pem", path);

Sylvain Berfini
committed
linphone_config_set_string(config, "sound", "remote_ring", ringbackpath);
linphone_config_set_string(config, "sound", "local_ring" , ringpath);
linphone_config_set_string(config, "sip", "root_ca" , rootcapath);
LinphoneCoreManager *mgr = (LinphoneCoreManager *)user_data;
if (mgr && mgr->app_group_id) {
lc = linphone_factory_create_shared_core_with_config(linphone_factory_get(), config, system_context, mgr->app_group_id, mgr->main_core);
} else {
lc = linphone_factory_create_core_with_config_3(linphone_factory_get(), config, system_context);
}
Guillaume BIENKOWSKI
committed
} else {
lc = linphone_factory_create_core_3(linphone_factory_get(), NULL, liblinphone_tester_get_empty_rc(), system_context);
Guillaume BIENKOWSKI
committed
linphone_core_set_ring(lc, ringpath);
linphone_core_set_ringback(lc, ringbackpath);
linphone_core_set_root_ca(lc, rootcapath);
Guillaume BIENKOWSKI
committed
}
if (cbs)
linphone_core_add_callbacks(lc, cbs);
linphone_core_set_static_picture(lc,nowebcampath);
configure_lc(lc, path, user_data);
Guillaume BIENKOWSKI
committed
ms_free(ringpath);
ms_free(ringbackpath);
ms_free(nowebcampath);
ms_free(rootcapath);
return lc;
}
bool_t wait_for_until_interval(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int min,int max,int timeout) {
bctbx_list_t* lcs=NULL;
bool_t result;
if (lc_1)
lcs=bctbx_list_append(lcs,lc_1);
if (lc_2)
lcs=bctbx_list_append(lcs,lc_2);
result=wait_for_list_interval(lcs,counter,min,max,timeout);
bctbx_list_free(lcs);
return result;
}
bool_t wait_for_until(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value,int timeout) {
bctbx_list_t* lcs=NULL;
bool_t result;
if (lc_1)
lcs=bctbx_list_append(lcs,lc_1);
lcs=bctbx_list_append(lcs,lc_2);
result=wait_for_list(lcs,counter,value,timeout);
bctbx_list_free(lcs);
return result;
}
bool_t wait_for(LinphoneCore* lc_1, LinphoneCore* lc_2,int* counter,int value) {
return wait_for_until(lc_1, lc_2,counter,value,10000);
bool_t wait_for_list_interval(bctbx_list_t* lcs,int* counter,int min, int max,int timeout_ms) {
bctbx_list_t* iterator;
MSTimeSpec start;
liblinphone_tester_clock_start(&start);
while ((counter==NULL || *counter<min || *counter>max) && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) {
for (iterator=lcs;iterator!=NULL;iterator=iterator->next) {
linphone_core_iterate((LinphoneCore*)(iterator->data));
}

Julien Wadel
committed
bc_tester_process_events();
#if !defined(LINPHONE_WINDOWS_UWP) && defined(LINPHONE_WINDOWS_DESKTOP)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0,1)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
#endif
ms_usleep(20000);
}
if(counter && (*counter<min || *counter>max)) return FALSE;
else return TRUE;
}
bool_t wait_for_list(bctbx_list_t* lcs,int* counter,int value,int timeout_ms) {
bctbx_list_t* iterator;
liblinphone_tester_clock_start(&start);
while ((counter==NULL || *counter<value) && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) {
for (iterator=lcs;iterator!=NULL;iterator=iterator->next) {
linphone_core_iterate((LinphoneCore*)(iterator->data));
}

Julien Wadel
committed
#ifdef LINPHONE_WINDOWS_UWP
{
bc_tester_process_events();
}
#elif defined(LINPHONE_WINDOWS_DESKTOP)
{
MSG msg;
while (PeekMessage(&msg, NULL, 0, 0,1)){
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
#endif
ms_usleep(20000);
}
if(counter && *counter<value) return FALSE;
else return TRUE;
}
Simon Morlat
committed
bool_t wait_for_stun_resolution(LinphoneCoreManager *m) {
MSTimeSpec start;
int timeout_ms = 10000;
liblinphone_tester_clock_start(&start);
while (linphone_core_get_stun_server_addrinfo(m->lc) == NULL && !liblinphone_tester_clock_elapsed(&start,timeout_ms)) {
Simon Morlat
committed
linphone_core_iterate(m->lc);
ms_usleep(20000);
}
return linphone_core_get_stun_server_addrinfo(m->lc) != NULL;
Simon Morlat
committed
}
static void enable_codec(LinphoneCore* lc,const char* type,int rate) {
bctbx_list_t* codecs=bctbx_list_copy(linphone_core_get_audio_codecs(lc));
bctbx_list_t* codecs_it;
PayloadType* pt;
for (codecs_it=codecs;codecs_it!=NULL;codecs_it=codecs_it->next) {
linphone_core_enable_payload_type(lc,(PayloadType*)codecs_it->data,0);
if ((pt = linphone_core_find_payload_type(lc,type,rate,1))) {
linphone_core_enable_payload_type(lc,pt, TRUE);
bctbx_list_free(codecs);
}
stats * get_stats(LinphoneCore *lc){
LinphoneCoreManager *manager=(LinphoneCoreManager *)linphone_core_get_user_data(lc);
return &manager->stat;
}
LinphoneCoreManager *get_manager(LinphoneCore *lc){
LinphoneCoreManager *manager=(LinphoneCoreManager *)linphone_core_get_user_data(lc);
return manager;
}
Gautier Pelloux-Prayer
committed
bool_t transport_supported(LinphoneTransportType transport) {
if ((transport == LinphoneTransportDtls || transport == LinphoneTransportTls) && liblinphone_tester_tls_support_disabled == TRUE) {
return FALSE;
} else {
Sal *sal = sal_init(NULL);
bool_t supported = sal_transport_available(sal,(SalTransport)transport);
if (!supported) ms_message("TLS transport not supported, falling back to TCP if possible otherwise skipping test.");
sal_uninit(sal);
return supported;
}
Gautier Pelloux-Prayer
committed
}
#ifdef SKIP_PULSEAUDIO
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
static void avoid_pulseaudio_hack(LinphoneCoreManager *mgr){
bctbx_list_t *cards = linphone_core_get_sound_devices_list(mgr->lc);
bctbx_list_t *it;
bool_t capture_set = FALSE, playback_set = FALSE;
bool_t pulseaudio_found = FALSE;
for (it = cards; it != NULL ; it = it->next){
const char * card_id = (const char *)it->data;
if (strstr(card_id, "PulseAudio") != NULL) {
pulseaudio_found = TRUE;
continue;
}
if (!capture_set && linphone_core_sound_device_can_capture(mgr->lc, card_id)){
capture_set = TRUE;
linphone_core_set_capture_device(mgr->lc, card_id);
}
if (!playback_set && linphone_core_sound_device_can_playback(mgr->lc, card_id)){
playback_set = TRUE;
linphone_core_set_playback_device(mgr->lc, card_id);
linphone_core_set_ringer_device(mgr->lc, card_id);
}
if (playback_set && capture_set){
if (pulseaudio_found) ms_warning("PulseAudio is not used in liblinphone_tester because of internal random crashes or hangs.");
break;
}
}
if (!playback_set || !capture_set){
ms_error("Could not find soundcard other than pulseaudio to use during tests. Some tests may crash or hang.");
}
bctbx_list_free(cards);
}
#endif
void linphone_core_manager_setup_dns(LinphoneCoreManager *mgr){
setup_dns(mgr->lc, bc_tester_get_resource_dir_prefix());
}
LinphoneCore *linphone_core_manager_configure_lc(LinphoneCoreManager *mgr) {
LinphoneCore *lc;
char *filepath = mgr->rc_path ? bctbx_strdup_printf("%s/%s", bc_tester_get_resource_dir_prefix(), mgr->rc_path) : NULL;
if (filepath && bctbx_file_exist(filepath) != 0) {
ms_fatal("Could not find file %s in path %s, did you configured resources directory correctly?", mgr->rc_path, bc_tester_get_resource_dir_prefix());
}
LinphoneConfig * config = linphone_factory_create_config_with_factory(linphone_factory_get(), mgr->rc_local, filepath);
linphone_config_set_string(config, "storage", "backend", "sqlite3");
linphone_config_set_string(config, "storage", "uri", mgr->database_path);
linphone_config_set_string(config, "storage", "call_logs_db_uri", mgr->call_logs_database_path);
linphone_config_set_string(config, "storage", "zrtp_secrets_db_uri", mgr->zrtp_secrets_database_path);
linphone_config_set_string(config, "lime", "x3dh_db_path", mgr->lime_database_path);
DanmeiChen
committed
linphone_config_set_bool(config, "misc", "auto_iterate", FALSE);
lc = configure_lc_from(mgr->cbs, bc_tester_get_resource_dir_prefix(), config, mgr);

Simon Morlat
committed
if (filepath) bctbx_free(filepath);
return lc;
}
void linphone_core_manager_configure(LinphoneCoreManager *mgr) {
LinphoneImNotifPolicy *im_notif_policy;
char *hellopath = bc_tester_res("sounds/hello8000.wav");
char *filepath = mgr->rc_path ? bctbx_strdup_printf("%s/%s", bc_tester_get_resource_dir_prefix(), mgr->rc_path) : NULL;
if (filepath && bctbx_file_exist(filepath) != 0) {
ms_fatal("Could not find file %s in path %s, did you configured resources directory correctly?", mgr->rc_path, bc_tester_get_resource_dir_prefix());
}
mgr->lc = linphone_core_manager_configure_lc(mgr);
Simon Morlat
committed
linphone_core_manager_check_accounts(mgr);
im_notif_policy = linphone_core_get_im_notif_policy(mgr->lc);
if (im_notif_policy != NULL) {
/* The IM notification policy can be NULL at this point in case of remote provisioning. */
linphone_im_notif_policy_clear(im_notif_policy);
linphone_im_notif_policy_set_send_is_composing(im_notif_policy, TRUE);
linphone_im_notif_policy_set_recv_is_composing(im_notif_policy, TRUE);
}
Guillaume BIENKOWSKI
committed
linphone_core_set_ringer_device( mgr->lc, "AQ: Audio Queue Device");
linphone_core_set_ringback(mgr->lc, NULL);
#elif __QNX__
linphone_core_set_playback_device(mgr->lc, "QSA: voice");
#elif defined(SKIP_PULSEAUDIO)
{
/* Special trick for linux. Pulseaudio has random hangs, deadlocks or abort while executing test suites.
* It never happens in the linphone app.
* So far we could not identify something bad in our pulseaudio usage. As a workaround, we disable pulseaudio for the tests.*/
avoid_pulseaudio_hack(mgr);
}
Guillaume BIENKOWSKI
committed
#endif
#ifdef VIDEO_ENABLED
{
MSWebCam *cam;
cam = ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(linphone_core_get_ms_factory(mgr->lc)), "Mire: Mire (synthetic moving picture)");
Peio Rigaux
committed
//Usefull especially for encoders not supporting qcif
#ifdef __ANDROID__
MSVideoSize vsize = MS_VIDEO_SIZE_CIF;
linphone_core_set_preferred_video_size(mgr->lc, vsize);
#endif
if (cam == NULL) {
MSWebCamDesc *desc = ms_mire_webcam_desc_get();
if (desc){
cam=ms_web_cam_new(desc);
ms_web_cam_manager_add_cam(ms_factory_get_web_cam_manager(linphone_core_get_ms_factory(mgr->lc)), cam);
}
}
#endif
linphone_core_set_play_file(mgr->lc,hellopath); /*is also used when in pause*/
ms_free(hellopath);
Guillaume BIENKOWSKI
committed
if( manager_count >= 2){
Gautier Pelloux-Prayer
committed
char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",bc_tester_get_writable_dir_prefix(),mgr->lc);
ms_message("Manager for '%s' using files", mgr->rc_path ? mgr->rc_path : "--");
Gautier Pelloux-Prayer
committed
linphone_core_set_use_files(mgr->lc, TRUE);
linphone_core_set_record_file(mgr->lc,recordpath);
ms_free(recordpath);
Guillaume BIENKOWSKI
committed
}
Gautier Pelloux-Prayer
committed
linphone_core_set_user_certificates_path(mgr->lc,bc_tester_get_writable_dir_prefix());
Simon Morlat
committed
/*for now, we need the periodical updates facility to compute bandwidth measurements correctly during tests*/
linphone_core_enable_send_call_stats_periodical_updates(mgr->lc, TRUE);
Gautier Pelloux-Prayer
committed
// clean
if (filepath) bctbx_free(filepath);
static void generate_random_database_path (LinphoneCoreManager *mgr) {
char random_id[32];
belle_sip_random_token(random_id, sizeof random_id);
char *database_path_format = bctbx_strdup_printf("linphone_%s.db", random_id);
mgr->database_path = bc_tester_file(database_path_format);
bctbx_free(database_path_format);
database_path_format = bctbx_strdup_printf("lime_%s.db", random_id);
mgr->lime_database_path = bc_tester_file(database_path_format);
bctbx_free(database_path_format);
char *call_logs_database_path_format = bctbx_strdup_printf("call-history-%s.db", random_id);
mgr->call_logs_database_path = bc_tester_file(call_logs_database_path_format);
bctbx_free(call_logs_database_path_format);
char *zrtp_secrets_database_path_format = bctbx_strdup_printf("zrtp-secrets-%s.db", random_id);
mgr->zrtp_secrets_database_path = bc_tester_file(zrtp_secrets_database_path_format);
bctbx_free(zrtp_secrets_database_path_format);
static void conference_state_changed (LinphoneConference *conference, LinphoneConferenceState newState) {
LinphoneCore *core = linphone_conference_get_core(conference);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
const LinphoneAddress * address = linphone_conference_get_conference_address(conference);
char * address_str = NULL;
if (address) {
address_str = linphone_address_as_string(address);
//ms_message("Conference [%s] state changed: %s", addr_str, linphone_conference_state_to_string(newState));
ms_message("Conference [%s] state changed: %d", address_str, newState);
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
}
if ((newState != LinphoneConferenceStateNone) && (newState != LinphoneConferenceStateInstantiated) && (newState != LinphoneConferenceStateCreationPending)) {
LinphoneParticipant *me = linphone_conference_get_me(conference);
BC_ASSERT_PTR_NOT_NULL(me);
}
switch (newState) {
case LinphoneConferenceStateNone:
break;
case LinphoneConferenceStateInstantiated:
manager->stat.number_of_LinphoneConferenceStateInstantiated++;
break;
case LinphoneConferenceStateCreationPending:
manager->stat.number_of_LinphoneConferenceStateCreationPending++;
break;
case LinphoneConferenceStateCreated:
manager->stat.number_of_LinphoneConferenceStateCreated++;
break;
case LinphoneConferenceStateCreationFailed:
manager->stat.number_of_LinphoneConferenceStateCreationFailed++;
break;
case LinphoneConferenceStateTerminationPending:
manager->stat.number_of_LinphoneConferenceStateTerminationPending++;
break;
case LinphoneConferenceStateTerminated:
manager->stat.number_of_LinphoneConferenceStateTerminated++;
break;
case LinphoneConferenceStateTerminationFailed:
manager->stat.number_of_LinphoneConferenceStateTerminationFailed++;
break;
case LinphoneConferenceStateDeleted:
manager->stat.number_of_LinphoneConferenceStateDeleted++;
break;
default:
ms_error("Invalid Conference state for Conference [%s] EndOfEnum is used ONLY as a guard", address_str ? address_str : "Unknown address");
if (address_str) {
bctbx_free(address_str);
}
}
void core_conference_state_changed (LinphoneCore *core, LinphoneConference *conference, LinphoneConferenceState state) {
if (state == LinphoneConferenceStateInstantiated) {
LinphoneConferenceCbs * cbs = linphone_factory_create_conference_cbs(linphone_factory_get());
linphone_conference_cbs_set_state_changed(cbs, conference_state_changed);
linphone_conference_add_callbacks(conference, cbs);
linphone_conference_cbs_unref(cbs);
}
}
LinphoneStatus add_participant_to_local_conference_through_invite(bctbx_list_t *lcs, LinphoneCoreManager * conf_mgr, bctbx_list_t *participants, const LinphoneCallParams *params) {
stats conf_initial_stats = conf_mgr->stat;
stats * participants_initial_stats = NULL;
bool_t * existing_call = NULL;
bctbx_list_t * participant_addresses = NULL;
int counter = 1;
LinphoneConference * local_conference = linphone_core_get_conference(conf_mgr->lc);
BC_ASSERT_PTR_NOT_NULL(local_conference);
const LinphoneAddress * local_conference_address = linphone_conference_get_conference_address(local_conference);
for (bctbx_list_t *it = participants; it; it = bctbx_list_next(it)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it);
participant_addresses = bctbx_list_append(participant_addresses, m->identity);
// Allocate memory
existing_call = (bool_t*)realloc(existing_call, counter * sizeof(bool_t));
participants_initial_stats = (stats*)realloc(participants_initial_stats, counter * sizeof(stats));
// Append element
participants_initial_stats[counter - 1] = m->stat;
LinphoneCall * conf_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, m->identity);
existing_call[counter - 1] = (conf_call != NULL);
// Increment counter
counter++;
LinphoneAddress *participant_uri = linphone_address_new(linphone_core_get_identity(m->lc));
LinphoneConference * participant_conference = linphone_core_search_conference(m->lc, NULL, participant_uri, local_conference_address, NULL);
linphone_address_unref(participant_uri);
BC_ASSERT_PTR_NULL(participant_conference);
LinphoneStatus status = linphone_conference_invite_participants(local_conference, participant_addresses, params);
if (participants != NULL) {
int idx = 0;
int new_call_cnt = 0;
for (bctbx_list_t *itm = participants; itm; itm = bctbx_list_next(itm)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(itm);
if (existing_call[idx] == FALSE) {
new_call_cnt++;
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallOutgoingProgress,conf_initial_stats.number_of_LinphoneCallOutgoingProgress + new_call_cnt,2000));
if (linphone_core_is_network_reachable(m->lc)) {
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallIncomingReceived,(participants_initial_stats[idx].number_of_LinphoneCallIncomingReceived + 1),10000));
}
}
idx++;
}
}
if (participants_initial_stats) {
ms_free(participants_initial_stats);
}
if (existing_call) {
ms_free(existing_call);
}
if (participant_addresses) {
bctbx_list_free(participant_addresses);
}
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
void check_conference_medias(LinphoneConference * local_conference, LinphoneConference * remote_conference) {
BC_ASSERT_PTR_NOT_NULL(local_conference);
BC_ASSERT_PTR_NOT_NULL(remote_conference);
if (local_conference && remote_conference) {
bctbx_list_t *local_conference_participants = linphone_conference_get_participant_list(local_conference);
LinphoneParticipant * remote_conference_me = linphone_conference_get_me(remote_conference);
const LinphoneAddress * remote_me_address = linphone_participant_get_address(remote_conference_me);
for (bctbx_list_t *itp = local_conference_participants; itp; itp = bctbx_list_next(itp)) {
LinphoneParticipant * p = (LinphoneParticipant *)bctbx_list_get_data(itp);
const LinphoneAddress * p_address = linphone_participant_get_address (p);
bctbx_list_t *local_devices = NULL;
if (linphone_address_equal(p_address, remote_me_address)) {
const bool_t remote_is_in = linphone_conference_is_in(remote_conference);
const LinphoneConferenceParams * remote_params = linphone_conference_get_current_params(remote_conference);
LinphoneMediaDirection audio_direction = ((remote_is_in == FALSE) || (!!linphone_conference_params_is_audio_enabled(remote_params) == FALSE)) ? LinphoneMediaDirectionInactive : LinphoneMediaDirectionSendRecv;
LinphoneMediaDirection video_direction = ((remote_is_in == FALSE) || (!!linphone_conference_params_is_video_enabled(remote_params) == FALSE)) ? LinphoneMediaDirectionInactive : LinphoneMediaDirectionSendRecv;
LinphoneMediaDirection text_direction = ((remote_is_in == FALSE) || (!!linphone_conference_params_is_chat_enabled(remote_params) == FALSE)) ? LinphoneMediaDirectionInactive : LinphoneMediaDirectionSendRecv;
local_devices = linphone_participant_get_devices (p);
for (bctbx_list_t *itd = local_devices; itd; itd = bctbx_list_next(itd)) {
LinphoneParticipantDevice * d = (LinphoneParticipantDevice *)bctbx_list_get_data(itd);
BC_ASSERT_EQUAL(linphone_participant_device_get_audio_direction(d), audio_direction, int, "%0d");
BC_ASSERT_EQUAL(linphone_participant_device_get_video_direction(d), video_direction, int, "%0d");
BC_ASSERT_EQUAL(linphone_participant_device_get_text_direction(d), text_direction, int, "%0d");
}
} else {
LinphoneParticipant * remote_participant = linphone_conference_find_participant(remote_conference, p_address);
BC_ASSERT_PTR_NOT_NULL(remote_participant);
if (remote_participant) {
local_devices = linphone_participant_get_devices (p);
for (bctbx_list_t *itd = local_devices; itd; itd = bctbx_list_next(itd)) {
LinphoneParticipantDevice * d = (LinphoneParticipantDevice *)bctbx_list_get_data(itd);
LinphoneParticipantDevice * remote_device = linphone_participant_find_device (remote_participant, linphone_participant_device_get_address(d));
BC_ASSERT_PTR_NOT_NULL(remote_device);
if (remote_device) {
BC_ASSERT_EQUAL(linphone_participant_device_get_audio_direction(d), linphone_participant_device_get_audio_direction(remote_device), int, "%0d");
BC_ASSERT_EQUAL(linphone_participant_device_get_video_direction(d), linphone_participant_device_get_video_direction(remote_device), int, "%0d");
BC_ASSERT_EQUAL(linphone_participant_device_get_text_direction(d), linphone_participant_device_get_text_direction(remote_device), int, "%0d");
}
}
}
}
if (local_devices) {
bctbx_list_free_with_data(local_devices, (void (*)(void *))linphone_participant_device_unref);
}
}
bctbx_list_free_with_data(local_conference_participants, (void (*)(void *))linphone_participant_unref);
const LinphoneConferenceParams * local_params = linphone_conference_get_current_params(local_conference);
const LinphoneConferenceParams * remote_params = linphone_conference_get_current_params(remote_conference);
BC_ASSERT_EQUAL(linphone_conference_params_is_audio_enabled(local_params), linphone_conference_params_is_audio_enabled(remote_params), int, "%0d");
BC_ASSERT_EQUAL(linphone_conference_params_is_video_enabled(local_params), linphone_conference_params_is_video_enabled(remote_params), int, "%0d");
BC_ASSERT_EQUAL(linphone_conference_params_is_chat_enabled(local_params), linphone_conference_params_is_chat_enabled(remote_params), int, "%0d");
}
}
Andrea Gianarda
committed
static void check_participant_added_to_conference(bctbx_list_t *lcs, LinphoneCoreManager * conf_mgr, stats conf_initial_stats, bctbx_list_t *new_participants, stats* new_participant_initial_stats, bool_t * is_call_paused, bctbx_list_t *participants, stats* participant_initial_stats, LinphoneConference * conference) {
const int no_new_participants = (int)bctbx_list_size(new_participants);
const int no_participants = (int)bctbx_list_size(participants);
int no_participants_without_event_log = 0;
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallStreamsRunning,conf_initial_stats.number_of_LinphoneCallStreamsRunning + no_new_participants,3000));
// Check that me has focus attribute set to true
BC_ASSERT_PTR_NOT_NULL(conference);
if (conference) {
LinphoneParticipant *me = linphone_conference_get_me(conference);
BC_ASSERT_PTR_NOT_NULL(me);
BC_ASSERT_TRUE(linphone_participant_is_focus(me));
}
int * notifyExpected = NULL;
for (int idx = 0; idx < no_participants; idx++) {
notifyExpected = (int*)realloc(notifyExpected, (idx + 1) * sizeof(int));
notifyExpected[idx] = 0;
}
int idx = 0;
bool_t conf_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(conf_mgr->lc), "misc", "conference_event_log_enabled", TRUE );
for (bctbx_list_t *it = new_participants; it; it = bctbx_list_next(it)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it);
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallStreamsRunning,new_participant_initial_stats[idx].number_of_LinphoneCallStreamsRunning + 1 + (is_call_paused[idx]) ? 1 : 0,3000));
// Remote conference creation
BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateCreationPending, new_participant_initial_stats[idx].number_of_LinphoneConferenceStateCreationPending + 1, 5000));
bool_t p_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(m->lc), "misc", "conference_event_log_enabled", TRUE );
if (p_event_log_enabled) {
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneSubscriptionOutgoingProgress,(new_participant_initial_stats[idx].number_of_LinphoneSubscriptionOutgoingProgress + 1),5000));
if (conf_event_log_enabled) {
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionIncomingReceived,(conf_initial_stats.number_of_LinphoneSubscriptionIncomingReceived + idx - no_participants_without_event_log + 1),5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionActive,(conf_initial_stats.number_of_LinphoneSubscriptionActive + idx + 1),5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneSubscriptionActive,new_participant_initial_stats[idx].number_of_LinphoneSubscriptionActive + 1,3000));
BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateCreated, new_participant_initial_stats[idx].number_of_LinphoneConferenceStateCreated + 1, 5000));
}
} else {
no_participants_without_event_log++;
}
// Notify
int idx2 = 0;
for (bctbx_list_t *itm = participants; itm; itm = bctbx_list_next(itm)) {
LinphoneCoreManager * m2 = (LinphoneCoreManager *)bctbx_list_get_data(itm);
bool_t p2_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(m2->lc), "misc", "conference_event_log_enabled", TRUE );
if (p2_event_log_enabled && conf_event_log_enabled) {
if (bctbx_list_find(new_participants,m2)) {
// When a participant is added, it receives the notification only once even though more participants are added at the same time
if (m2 == m) {
// Participant added
notifyExpected[idx2] = notifyExpected[idx2] + 1;
}
} else {
// Participant added
// Participant device added
notifyExpected[idx2] = notifyExpected[idx2] + 2;
}
BC_ASSERT_TRUE(wait_for_list(lcs,&m2->stat.number_of_NotifyReceived,(participant_initial_stats[idx2].number_of_NotifyReceived + notifyExpected[idx2]),3000));
}
idx2++;
}
if (p_event_log_enabled) {
if (conf_event_log_enabled) {
// Number of subscription errors should not change as they the participant should received a notification
BC_ASSERT_EQUAL(m->stat.number_of_LinphoneSubscriptionError,new_participant_initial_stats[idx].number_of_LinphoneSubscriptionError, int, "%0d");
} else {
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneSubscriptionError,(participant_initial_stats[idx].number_of_LinphoneSubscriptionError + 1),3000));
}
}
// Number of subscription terminated should not change as they the participant should received a notification
BC_ASSERT_EQUAL(m->stat.number_of_LinphoneSubscriptionTerminated, new_participant_initial_stats[idx].number_of_LinphoneSubscriptionTerminated, int, "%d");
idx++;
}
int expected_subscriptions = 0;
if (conference) {
expected_subscriptions = linphone_conference_get_participant_count(conference);
for (bctbx_list_t *itm = participants; itm; itm = bctbx_list_next(itm)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(itm);
bool_t event_log_enabled = linphone_config_get_bool(linphone_core_get_config(m->lc), "misc", "conference_event_log_enabled", TRUE );
// If events logs are not enabled, subscribes are not sent
if (!event_log_enabled) {
expected_subscriptions--;
}
}
}
int* subscription_count = ((int *)(conf_mgr->user_info));
BC_ASSERT_TRUE(wait_for_list(lcs,subscription_count, expected_subscriptions,5000));
if (conf_event_log_enabled) {
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionActive,expected_subscriptions,3000));
} else {
BC_ASSERT_EQUAL(conf_mgr->stat.number_of_LinphoneSubscriptionActive,0,int,"%d");
}
BC_ASSERT_EQUAL(conf_mgr->stat.number_of_LinphoneSubscriptionError,conf_initial_stats.number_of_LinphoneSubscriptionError, int, "%0d");
if (conf_event_log_enabled) {
BC_ASSERT_EQUAL(conf_mgr->stat.number_of_LinphoneSubscriptionTerminated, conf_initial_stats.number_of_LinphoneSubscriptionTerminated, int, "%d");
} else {
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionTerminated,(conf_initial_stats.number_of_LinphoneSubscriptionTerminated + no_new_participants),3000));
}
// Add a short wait to ensure that all NOTIFYs are replied
wait_for_list(lcs,NULL,0,1000);
if (!conference) {
conference = linphone_core_get_conference(conf_mgr->lc);
}
BC_ASSERT_PTR_NOT_NULL(conference);
if (conference) {
const LinphoneAddress * local_conference_address = linphone_conference_get_conference_address(conference);
for (bctbx_list_t *it = new_participants; it; it = bctbx_list_next(it)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it);
bool_t p_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(m->lc), "misc", "conference_event_log_enabled", TRUE );
if (p_event_log_enabled && conf_event_log_enabled) {
LinphoneAddress *m_uri = linphone_address_new(linphone_core_get_identity(m->lc));
LinphoneConference * remote_conference = linphone_core_search_conference(m->lc, NULL, m_uri, local_conference_address, NULL);
linphone_address_unref(m_uri);
BC_ASSERT_PTR_NOT_NULL(remote_conference);
if (remote_conference) {
check_conference_medias(conference, remote_conference);
}
}
}
}
}
LinphoneStatus add_calls_to_remote_conference(bctbx_list_t *lcs, LinphoneCoreManager * focus_mgr, LinphoneCoreManager * conf_mgr, bctbx_list_t *new_participants) {
stats conf_initial_stats = conf_mgr->stat;
stats focus_initial_stats = focus_mgr->stat;
LinphoneCall * conf_to_focus_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, focus_mgr->identity);
int counter = 1;
for (bctbx_list_t *it = new_participants; it; it = bctbx_list_next(it)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it);
stats initial_stats = m->stat;
LinphoneCall * conf_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, m->identity);
BC_ASSERT_PTR_NOT_NULL(conf_call);
linphone_core_add_to_conference(conf_mgr->lc,conf_call);
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneConferenceStateCreationPending, initial_stats.number_of_LinphoneConferenceStateCreationPending + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneConferenceStateCreated, initial_stats.number_of_LinphoneConferenceStateCreated + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneSubscriptionOutgoingProgress,(initial_stats.number_of_LinphoneSubscriptionOutgoingProgress + 1),5000));
// BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneSubscriptionIncomingReceived,(focus_initial_stats.number_of_LinphoneSubscriptionIncomingReceived + counter),1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneSubscriptionActive,initial_stats.number_of_LinphoneSubscriptionActive + 1,3000));
// BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneSubscriptionActive,(focus_initial_stats.number_of_LinphoneSubscriptionActive + counter),1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneCallStreamsRunning,(focus_initial_stats.number_of_LinphoneCallStreamsRunning+counter),5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneTransferCallConnected,conf_initial_stats.number_of_LinphoneTransferCallConnected+counter,5000));
// End of call between conference and participant
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallEnd,conf_initial_stats.number_of_LinphoneCallEnd+counter,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallEnd,initial_stats.number_of_LinphoneCallEnd+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallReleased,conf_initial_stats.number_of_LinphoneCallReleased+counter,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallReleased,initial_stats.number_of_LinphoneCallReleased+1,5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_NotifyReceived,(initial_stats.number_of_NotifyReceived + 1),5000));
// Local conference
LinphoneCall * focus_call = linphone_core_get_call_by_remote_address2(focus_mgr->lc, m->identity);
BC_ASSERT_PTR_NOT_NULL(focus_call);
if (focus_call) {
BC_ASSERT_PTR_NOT_NULL(linphone_call_get_conference(focus_call));
BC_ASSERT_TRUE(linphone_call_is_in_conference(focus_call));
}
// Remote conference
LinphoneCall * participant_call = linphone_core_get_call_by_remote_address2(m->lc, focus_mgr->identity);
BC_ASSERT_PTR_NOT_NULL(participant_call);
if (participant_call) {
BC_ASSERT_PTR_NOT_NULL(linphone_call_get_conference(participant_call));
BC_ASSERT_FALSE(linphone_call_is_in_conference(participant_call));
}
counter++;
}
// Remote conference
if (conf_to_focus_call == NULL) {
// Asserts to verify that call between focus and confernece manager is correctly set up
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionOutgoingProgress,(conf_initial_stats.number_of_LinphoneSubscriptionOutgoingProgress + 1),5000));
// BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneSubscriptionIncomingReceived,(focus_initial_stats.number_of_LinphoneSubscriptionIncomingReceived + counter + 1),1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneConferenceStateCreationPending, focus_initial_stats.number_of_LinphoneConferenceStateCreationPending + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneConferenceStateCreated, focus_initial_stats.number_of_LinphoneConferenceStateCreated + 1, 5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionActive,conf_initial_stats.number_of_LinphoneSubscriptionActive + 1,3000));
// BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneSubscriptionActive,(focus_initial_stats.number_of_LinphoneSubscriptionActive + counter + 1),1000));
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallStreamsRunning,(conf_initial_stats.number_of_LinphoneCallStreamsRunning+1),5000));
BC_ASSERT_TRUE(wait_for_list(lcs,&focus_mgr->stat.number_of_LinphoneCallStreamsRunning,(focus_initial_stats.number_of_LinphoneCallStreamsRunning+counter+1),5000));
conf_to_focus_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, focus_mgr->identity);
}
BC_ASSERT_PTR_NOT_NULL(conf_to_focus_call);
BC_ASSERT_PTR_NOT_NULL(linphone_call_get_conference(conf_to_focus_call));
BC_ASSERT_FALSE(linphone_call_is_in_conference(conf_to_focus_call));
// Local conference
LinphoneCall * focus_to_conf_call = linphone_core_get_call_by_remote_address2(focus_mgr->lc, conf_mgr->identity);
BC_ASSERT_PTR_NOT_NULL(focus_to_conf_call);
BC_ASSERT_PTR_NOT_NULL(linphone_call_get_conference(focus_to_conf_call));
BC_ASSERT_TRUE(linphone_call_is_in_conference(focus_to_conf_call));
return 0;
}
LinphoneStatus add_calls_to_local_conference(bctbx_list_t *lcs, LinphoneCoreManager * conf_mgr, LinphoneConference * conference, bctbx_list_t *new_participants, bool_t one_by_one) {
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
stats conf_initial_stats = conf_mgr->stat;
stats* participants_initial_stats = NULL;
bctbx_list_t *participants = NULL;
int counter = 1;
for (bctbx_list_t *it = lcs; it; it = bctbx_list_next(it)) {
LinphoneCore * c = (LinphoneCore *)bctbx_list_get_data(it);
LinphoneCoreManager * m = get_manager(c);
if (m != conf_mgr) {
// Allocate memory
participants_initial_stats = (stats*)realloc(participants_initial_stats, counter * sizeof(stats));
// Append element
participants_initial_stats[counter - 1] = m->stat;
// Increment counter
counter++;
participants = bctbx_list_append(participants, m);
}
}
counter = 1;
stats* new_participants_initial_stats = NULL;
for (bctbx_list_t *it = new_participants; it; it = bctbx_list_next(it)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it);
// Allocate memory
new_participants_initial_stats = (stats*)realloc(new_participants_initial_stats, counter * sizeof(stats));
// Append element
new_participants_initial_stats[counter - 1] = m->stat;
// Increment counter
counter++;
}
bool_t * call_paused = NULL;
counter = 1;
Andrea Gianarda
committed
LinphoneConference * conference_used = NULL;
if (one_by_one) {
for (bctbx_list_t *it = new_participants; it; it = bctbx_list_next(it)) {
LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it);
stats initial_stats = m->stat;
LinphoneCall * conf_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, m->identity);
BC_ASSERT_PTR_NOT_NULL(conf_call);
call_paused = (bool_t*)realloc(call_paused, counter * sizeof(bool_t));
call_paused[counter - 1] = FALSE;
if (conf_call) {
bool_t is_call_paused = (linphone_call_get_state(conf_call) == LinphoneCallStatePaused);
call_paused[counter - 1] = is_call_paused;
if (conference) {
linphone_conference_add_participant(conference,conf_call);
conference_used = conference;
} else {
linphone_core_add_to_conference(conf_mgr->lc,conf_call);
conference_used = linphone_core_get_conference(conf_mgr->lc);
}
if (is_call_paused) {
BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallResuming,conf_initial_stats.number_of_LinphoneCallResuming+1,2000));