tester.c 166.27 KiB
/*
 * 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 <stdlib.h>
#include "linphone/core.h"
#include "linphone/logging.h"
#include "logging-private.h"
#include "liblinphone_tester.h"
#include <bctoolbox/tester.h>
#include <bctoolbox/vfs.h>
#include "tester_utils.h"
#include "belle-sip/sipstack.h"
#include "shared_tester_functions.h"
#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
#define SKIP_PULSEAUDIO 1
#if _WIN32
#define unlink _unlink
#endif
#ifdef __ANDROID__
extern jobject system_context;
#else
void *system_context=0;
#endif
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
static char *liblinphone_tester_empty_rc_path = NULL; static int liblinphone_tester_keep_accounts_flag = 0; 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; int manager_count = 0; 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"; 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>"; const char *liblinphone_tester_mire_id="Mire: Mire (synthetic moving picture)"; const char *liblinphone_tester_static_image_id="StaticImage: Static picture"; static void network_reachable(LinphoneCore *lc, bool_t reachable) { 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);
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
} bool_t liblinphone_tester_clock_elapsed(const MSTimeSpec *start, int value_ms){ MSTimeSpec current; ms_get_cur_time(&current); 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; 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) { 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."); } } 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) {
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
LinphoneCore *lc; char *ringpath = NULL; char *ringbackpath = NULL; char *rootcapath = NULL; char *nowebcampath = NULL; // 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); if (config) { 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); } } else { lc = linphone_factory_create_core_3(linphone_factory_get(), NULL, liblinphone_tester_get_empty_rc(), system_context); linphone_core_set_ring(lc, ringpath); linphone_core_set_ringback(lc, ringbackpath); linphone_core_set_root_ca(lc, rootcapath); } if (cbs) linphone_core_add_callbacks(lc, cbs); #ifdef VIDEO_ENABLED linphone_core_set_static_picture(lc,nowebcampath); #endif configure_lc(lc, path, user_data); 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); if (lc_2) 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); }
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
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)); } 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; MSTimeSpec start; 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)); } #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; } 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)) { linphone_core_iterate(m->lc); ms_usleep(20000); } return linphone_core_get_stun_server_addrinfo(m->lc) != NULL; } 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) {
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
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; } 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; } } #ifdef SKIP_PULSEAUDIO 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) {
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
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); linphone_config_set_bool(config, "misc", "auto_iterate", FALSE); lc = configure_lc_from(mgr->cbs, bc_tester_get_resource_dir_prefix(), config, mgr); linphone_config_unref(config); 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); 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); } #if TARGET_OS_IPHONE 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); } #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)"); //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); } } }
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
#endif linphone_core_set_play_file(mgr->lc,hellopath); /*is also used when in pause*/ ms_free(hellopath); if( manager_count >= 2){ 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 : "--"); linphone_core_set_use_files(mgr->lc, TRUE); linphone_core_set_record_file(mgr->lc,recordpath); ms_free(recordpath); } linphone_core_set_user_certificates_path(mgr->lc,bc_tester_get_writable_dir_prefix()); /*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); // 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); } 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;
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
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"); break; } 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;
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
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); } return status; } 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"); } }
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
} } 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"); } } 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) { // Check subscriptions 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) {
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
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)); } ms_free(notifyExpected); // 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);
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
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++;
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
} // 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) { 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; LinphoneConference * conference_used = NULL; if (one_by_one) {
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
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)); } else { BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallUpdating,conf_initial_stats.number_of_LinphoneCallUpdating+1,5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallUpdatedByRemote,(initial_stats.number_of_LinphoneCallUpdatedByRemote + 1),5000)); } BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallStreamsRunning,initial_stats.number_of_LinphoneCallStreamsRunning + 1,3000)); BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallStreamsRunning,conf_initial_stats.number_of_LinphoneCallStreamsRunning + 1,3000)); // Local conference BC_ASSERT_TRUE(linphone_call_is_in_conference(conf_call)); } // Remote conference LinphoneCall * participant_call = linphone_core_get_current_call(m->lc); BC_ASSERT_PTR_NOT_NULL(participant_call); if (participant_call) { LinphoneConference * pconf = linphone_call_get_conference(participant_call); BC_ASSERT_PTR_NOT_NULL(pconf); BC_ASSERT_FALSE(linphone_call_is_in_conference(participant_call)); if (pconf) { LinphoneParticipant * participant = linphone_conference_get_me(pconf); BC_ASSERT_FALSE(linphone_participant_is_focus (participant)); } } counter++; } } else { bctbx_list_t *calls = NULL; for (bctbx_list_t *it = new_participants; it; it = bctbx_list_next(it)) { LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it); 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; calls = bctbx_list_append(calls, conf_call); } counter++; } if (conference) { conference_used = conference; } else if (linphone_core_get_conference(conf_mgr->lc)) { conference_used = linphone_core_get_conference(conf_mgr->lc); } else { LinphoneConferenceParams *conf_params = linphone_core_create_conference_params(conf_mgr->lc); conference_used = linphone_core_create_conference_with_params(conf_mgr->lc, conf_params); linphone_conference_params_unref(conf_params);
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
linphone_conference_unref(conference_used); /*actually linphone_core_create_conference_with_params() takes a ref for lc->conf_ctx */ } BC_ASSERT_PTR_NOT_NULL(conference_used); linphone_conference_add_participants(conference_used,calls); bctbx_list_free(calls); BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallStreamsRunning,conf_initial_stats.number_of_LinphoneCallStreamsRunning + (int)bctbx_list_size(new_participants),3000)); } check_participant_added_to_conference(lcs, conf_mgr, conf_initial_stats, new_participants, new_participants_initial_stats, call_paused, participants, participants_initial_stats, conference_used); ms_free(call_paused); ms_free(participants_initial_stats); ms_free(new_participants_initial_stats); bctbx_list_free(participants); return 0; } static LinphoneStatus check_participant_removal(bctbx_list_t * lcs, LinphoneCoreManager * conf_mgr, LinphoneCoreManager * participant_mgr, bctbx_list_t *participants, int participant_size, stats conf_initial_stats, stats participant_initial_stats, stats * participants_initial_stats, LinphoneCallState * participants_initial_state, bool_t local_participant_is_in) { // Wait for conferences to be terminated BC_ASSERT_TRUE(wait_for_list(lcs,&participant_mgr->stat.number_of_LinphoneConferenceStateTerminationPending,(participant_initial_stats.number_of_LinphoneConferenceStateTerminationPending + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&participant_mgr->stat.number_of_LinphoneConferenceStateTerminated,(participant_initial_stats.number_of_LinphoneConferenceStateTerminated + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&participant_mgr->stat.number_of_LinphoneConferenceStateDeleted,(participant_initial_stats.number_of_LinphoneConferenceStateDeleted + 1),5000)); bool_t conf_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(conf_mgr->lc), "misc", "conference_event_log_enabled", TRUE ); if (conf_event_log_enabled) { BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionTerminated,conf_initial_stats.number_of_LinphoneSubscriptionTerminated + 1,10000)); } bool_t participant_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(participant_mgr->lc), "misc", "conference_event_log_enabled", TRUE ); if (participant_event_log_enabled) { BC_ASSERT_TRUE(wait_for_list(lcs,&participant_mgr->stat.number_of_LinphoneSubscriptionTerminated,participant_initial_stats.number_of_LinphoneSubscriptionTerminated + 1,3000)); } LinphoneConference * conference = linphone_core_get_conference(conf_mgr->lc); bool_t one_participant_conference_enabled = FALSE; if (conference) { const LinphoneConferenceParams * conf_params = linphone_conference_get_current_params(conference); one_participant_conference_enabled = linphone_conference_params_is_one_participant_conference_enabled(conf_params); } int expected_no_participants = 0; if (((participant_size == 2) && !one_participant_conference_enabled) || (participant_size == 1)) { expected_no_participants = 0; BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneConferenceStateTerminationPending,(conf_initial_stats.number_of_LinphoneConferenceStateTerminationPending + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneConferenceStateTerminated,(conf_initial_stats.number_of_LinphoneConferenceStateTerminated + 1),10000)); BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneConferenceStateDeleted,(conf_initial_stats.number_of_LinphoneConferenceStateDeleted + 1),10000)); conference = linphone_core_get_conference(conf_mgr->lc); BC_ASSERT_PTR_NULL(conference); } else { expected_no_participants = (participant_size - 1); BC_ASSERT_PTR_NOT_NULL(conference); if (conference) { BC_ASSERT_EQUAL(linphone_conference_get_participant_count(conference), expected_no_participants, int, "%d"); BC_ASSERT_EQUAL(linphone_conference_is_in(conference), local_participant_is_in, int, "%d"); } } // Other participants call should not have their state modified if ((participants != NULL) && (one_participant_conference_enabled || (participant_size > 1))) { int idx = 0; for (bctbx_list_t *itm = participants; itm; itm = bctbx_list_next(itm)) { LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(itm);
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
// If removing last participant, then its call is kicked out of conference // - Remote conference is deleted // - parameters are updated if (expected_no_participants == 0) { if (local_participant_is_in) { BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallUpdating,(conf_initial_stats.number_of_LinphoneCallUpdating + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallUpdatedByRemote,(participants_initial_stats[idx].number_of_LinphoneCallUpdatedByRemote + 1),5000)); if (participants_initial_state[idx] == LinphoneCallStreamsRunning) { 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,&m->stat.number_of_LinphoneCallStreamsRunning,(participants_initial_stats[idx].number_of_LinphoneCallStreamsRunning + 1), 5000)); } else if (participants_initial_state[idx] == LinphoneCallPaused) { BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallPausedByRemote,(conf_initial_stats.number_of_LinphoneCallPausedByRemote + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallPaused,(participants_initial_stats[idx].number_of_LinphoneCallPaused + 1), 5000)); } else if (participants_initial_state[idx] == LinphoneCallPausedByRemote) { BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallPaused,(conf_initial_stats.number_of_LinphoneCallPaused + 1), 5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallPausedByRemote,(participants_initial_stats[idx].number_of_LinphoneCallPausedByRemote + 1), 5000)); } else { char str[200]; sprintf(str, "%s - Unhandled participant call remove from conference going to state %s\n", __func__, linphone_call_state_to_string(participants_initial_state[idx])); BC_FAIL(str); } } else { BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallPausing,(conf_initial_stats.number_of_LinphoneCallPausing + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneCallPausedByRemote,(participants_initial_stats[idx].number_of_LinphoneCallPausedByRemote + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallPaused,(conf_initial_stats.number_of_LinphoneCallPaused + 1), 5000)); } BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneConferenceStateTerminationPending,(participants_initial_stats[idx].number_of_LinphoneConferenceStateTerminationPending + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneConferenceStateTerminated,(participants_initial_stats[idx].number_of_LinphoneConferenceStateTerminated + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneConferenceStateDeleted,(participants_initial_stats[idx].number_of_LinphoneConferenceStateDeleted + 1),5000)); LinphoneCall * conf_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, m->identity); BC_ASSERT_PTR_NOT_NULL(conf_call); if (conf_call) { BC_ASSERT_PTR_NULL(linphone_call_get_conference(conf_call)); BC_ASSERT_FALSE(linphone_call_is_in_conference(conf_call)); } LinphoneCall * participant_call = linphone_core_get_call_by_remote_address2(m->lc, conf_mgr->identity); BC_ASSERT_PTR_NOT_NULL(participant_call); if (participant_call) { BC_ASSERT_PTR_NULL(linphone_call_get_conference(participant_call)); BC_ASSERT_FALSE(linphone_call_is_in_conference(participant_call)); } bool_t conf_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(conf_mgr->lc), "misc", "conference_event_log_enabled", TRUE ); if (conf_event_log_enabled) { BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneSubscriptionTerminated,conf_initial_stats.number_of_LinphoneSubscriptionTerminated + 2,10000)); } bool_t m_event_log_enabled = linphone_config_get_bool(linphone_core_get_config(m->lc), "misc", "conference_event_log_enabled", TRUE ); if (m_event_log_enabled) { BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneSubscriptionTerminated,participants_initial_stats[idx].number_of_LinphoneSubscriptionTerminated + 1,3000)); } } else { // Wait for notify of participant device deleted and participant deleted BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_NotifyReceived,(participants_initial_stats[idx].number_of_NotifyReceived + 2),3000)); BC_ASSERT_EQUAL(m->stat.number_of_LinphoneCallStreamsRunning,participants_initial_stats[idx].number_of_LinphoneCallStreamsRunning, int, "%0d"); } BC_ASSERT_EQUAL(m->stat.number_of_LinphoneCallEnd,participants_initial_stats[idx].number_of_LinphoneCallEnd, int, "%0d"); BC_ASSERT_EQUAL(m->stat.number_of_LinphoneCallReleased,participants_initial_stats[idx].number_of_LinphoneCallReleased, int, "%0d"); idx++; } } return 0; }
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
LinphoneStatus remove_participant_from_local_conference(bctbx_list_t *lcs, LinphoneCoreManager * conf_mgr, LinphoneCoreManager * participant_mgr) { stats conf_initial_stats = conf_mgr->stat; stats participant_initial_stats = participant_mgr->stat; LinphoneConference * conference = linphone_core_get_conference(conf_mgr->lc); BC_ASSERT_PTR_NOT_NULL(conference); if (conference) { int participant_size = linphone_conference_get_participant_count(conference); bool_t local_participant_is_in = linphone_conference_is_in (conference); LinphoneConference * local_conference = linphone_core_get_conference(conf_mgr->lc); BC_ASSERT_PTR_NOT_NULL(local_conference); LinphoneAddress * local_conference_address = linphone_address_clone(linphone_conference_get_conference_address(local_conference)); LinphoneAddress *participant_uri = linphone_address_new(linphone_core_get_identity(participant_mgr->lc)); LinphoneConference * participant_conference = linphone_core_search_conference(participant_mgr->lc, NULL, participant_uri, local_conference_address, NULL); linphone_address_unref(participant_uri); BC_ASSERT_PTR_NOT_NULL(participant_conference); stats* participants_initial_stats = NULL; LinphoneCallState* participants_initial_state = 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 != participant_mgr) && (m != conf_mgr)) { // Allocate memory participants_initial_stats = (stats*)realloc(participants_initial_stats, counter * sizeof(stats)); participants_initial_state = (LinphoneCallState*)realloc(participants_initial_state, counter * sizeof(LinphoneCallState)); // Append element participants_initial_stats[counter - 1] = m->stat; LinphoneCall * participant_call = linphone_core_get_call_by_remote_address2(m->lc, conf_mgr->identity); BC_ASSERT_PTR_NOT_NULL(participant_call); participants_initial_state[counter - 1] = linphone_call_get_state(participant_call); // Increment counter counter++; participants = bctbx_list_append(participants, m); } } LinphoneCall * conf_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, participant_mgr->identity); BC_ASSERT_PTR_NOT_NULL(conf_call); bool_t is_conf_call_paused = (linphone_call_get_state(conf_call) == LinphoneCallStatePaused); LinphoneCall * participant_call = linphone_core_get_call_by_remote_address2(participant_mgr->lc, conf_mgr->identity); BC_ASSERT_PTR_NOT_NULL(participant_call); bool_t is_participant_call_paused = (linphone_call_get_state(participant_call) == LinphoneCallStatePaused); linphone_core_remove_from_conference(conf_mgr->lc, conf_call); // If the conference already put the call in pause, then it will not be put in pause again // Calls are paused or updated when removing a participant BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallPausing,(conf_initial_stats.number_of_LinphoneCallPausing + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&conf_mgr->stat.number_of_LinphoneCallPaused,(conf_initial_stats.number_of_LinphoneCallPaused + 1),5000)); // If the conference already put the call in pause, then the participant call is already in the state PausedByRemote // If the participant call was already paused, then it stays in the paused state while accepting the update if (is_conf_call_paused) { BC_ASSERT_TRUE(wait_for_list(lcs,&participant_mgr->stat.number_of_LinphoneCallUpdatedByRemote,(participant_initial_stats.number_of_LinphoneCallUpdatedByRemote + 1),5000)); BC_ASSERT_TRUE(wait_for_list(lcs,&participant_mgr->stat.number_of_LinphoneCallPausedByRemote,(participant_initial_stats.number_of_LinphoneCallPausedByRemote + 1),5000)); } else if (!is_participant_call_paused && !is_conf_call_paused) { } check_participant_removal(lcs, conf_mgr, participant_mgr, participants, participant_size, conf_initial_stats, participant_initial_stats, participants_initial_stats, participants_initial_state, local_participant_is_in); participant_uri = linphone_address_new(linphone_core_get_identity(participant_mgr->lc)); participant_conference = linphone_core_search_conference(participant_mgr->lc, NULL, participant_uri, local_conference_address, NULL);
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
linphone_address_unref(participant_uri); linphone_address_unref(local_conference_address); BC_ASSERT_PTR_NULL(participant_conference); ms_free(participants_initial_stats); ms_free(participants_initial_state); bctbx_list_free(participants); } return 0; } static void finish_terminate_local_conference(bctbx_list_t *lcs, stats* lcm_stats, bool_t* call_is_in_conference, LinphoneCoreManager * conf_mgr, unsigned int no_participants, bool_t core_held_conference) { int idx = 0; 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); unsigned int no_calls = 0; if (m == conf_mgr) { no_calls = no_participants; } else { no_calls = 1; } // Wait for calls to be terminated BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallEnd, lcm_stats[idx].number_of_LinphoneCallEnd + no_calls, 30000)); // Wait for all conferences to be terminated BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateTerminationPending, lcm_stats[idx].number_of_LinphoneConferenceStateTerminationPending + 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateTerminated, lcm_stats[idx].number_of_LinphoneConferenceStateTerminated + 1, 5000)); BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneConferenceStateDeleted, lcm_stats[idx].number_of_LinphoneConferenceStateDeleted + 1, 5000)); bool_t event_log_enabled = linphone_config_get_bool(linphone_core_get_config(m->lc), "misc", "conference_event_log_enabled", TRUE ); // In case of a re-registration, the number of active subscriptions on the local conference side accounts the numbers of subscriptions before and after the re-registration if ((m != conf_mgr) && (m->stat.number_of_LinphoneRegistrationOk == 1) && event_log_enabled) { // If the participant left the conference, then his subscription to the conference was terminated if (call_is_in_conference[idx]) { BC_ASSERT_TRUE(wait_for_list(lcs,&m->stat.number_of_LinphoneSubscriptionTerminated,lcm_stats[idx].number_of_LinphoneSubscriptionTerminated + 1,10000)); } else { BC_ASSERT_EQUAL(m->stat.number_of_LinphoneSubscriptionTerminated,lcm_stats[idx].number_of_LinphoneSubscriptionActive, int, "%0d"); } } BC_ASSERT_TRUE(wait_for_list(lcs, &m->stat.number_of_LinphoneCallReleased, lcm_stats[idx].number_of_LinphoneCallReleased + no_calls, 10000)); if ((m != conf_mgr) || ((m == conf_mgr) && (core_held_conference == TRUE))) { LinphoneConference *conference = linphone_core_get_conference(c); BC_ASSERT_PTR_NULL(conference); } if (m != conf_mgr) { LinphoneCall * participant_call = linphone_core_get_call_by_remote_address2(m->lc, conf_mgr->identity); BC_ASSERT_PTR_NULL(participant_call); LinphoneCall * conference_call = linphone_core_get_call_by_remote_address2(conf_mgr->lc, m->identity); BC_ASSERT_PTR_NULL(conference_call); } idx++; } } static void finish_terminate_remote_conference(bctbx_list_t *lcs, stats* lcm_stats, bool_t* call_is_in_conference, LinphoneCoreManager * conf_mgr, LinphoneCoreManager * focus_mgr, unsigned int no_participants, bool_t core_held_conference) { finish_terminate_local_conference(lcs, lcm_stats, call_is_in_conference, focus_mgr, no_participants+1, core_held_conference); } bctbx_list_t* terminate_participant_call(bctbx_list_t *participants, LinphoneCoreManager * conf_mgr, LinphoneCoreManager * participant_mgr) {
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
LinphoneCall * participant_call = linphone_core_get_call_by_remote_address2(participant_mgr->lc, conf_mgr->identity); BC_ASSERT_PTR_NOT_NULL(participant_call); if (participant_call) { LinphoneConference * local_conference = linphone_core_get_conference(conf_mgr->lc); BC_ASSERT_PTR_NOT_NULL(local_conference); LinphoneAddress * local_conference_address = linphone_address_clone(linphone_conference_get_conference_address(local_conference)); LinphoneAddress *participant_uri = linphone_address_new(linphone_core_get_identity(participant_mgr->lc)); LinphoneConference * participant_conference = linphone_core_search_conference(participant_mgr->lc, NULL, participant_uri, local_conference_address, NULL); linphone_address_unref(participant_uri); BC_ASSERT_PTR_NOT_NULL(participant_conference); stats initial_participant_stats = participant_mgr->stat; stats initial_conf_stats = conf_mgr->stat; stats* initial_other_participants_stats = NULL; LinphoneCallState* initial_other_participants_state = NULL; bctbx_list_t * lcs = NULL; lcs=bctbx_list_append(lcs,conf_mgr->lc); int counter = 1; for (bctbx_list_t *it = participants; it; it = bctbx_list_next(it)) { LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it); if (m != participant_mgr) { // Allocate memory initial_other_participants_stats = (stats*)realloc(initial_other_participants_stats, counter * sizeof(stats)); initial_other_participants_state = (LinphoneCallState*)realloc(initial_other_participants_state, counter * sizeof(LinphoneCallState)); // Append element initial_other_participants_stats[counter - 1] = m->stat; LinphoneCall * participant_call = linphone_core_get_call_by_remote_address2(m->lc, conf_mgr->identity); BC_ASSERT_PTR_NOT_NULL(participant_call); if (participant_call) { initial_other_participants_state[counter - 1] = linphone_call_get_state(participant_call); } else { initial_other_participants_state[counter - 1] = LinphoneCallStateIdle; } // Increment counter counter++; } lcs=bctbx_list_append(lcs,m->lc); } LinphoneConference * conference = linphone_core_get_conference(conf_mgr->lc); BC_ASSERT_PTR_NOT_NULL(conference); int participant_size = -1; bool_t local_participant_is_in = TRUE; if (conference) { participant_size = linphone_conference_get_participant_count(conference); local_participant_is_in = linphone_conference_is_in (conference); } linphone_core_terminate_call(participant_mgr->lc, participant_call); participants = bctbx_list_remove(participants, participant_mgr); BC_ASSERT_TRUE(wait_for(conf_mgr->lc,participant_mgr->lc,&participant_mgr->stat.number_of_LinphoneCallEnd,(initial_participant_stats.number_of_LinphoneCallEnd + 1))); BC_ASSERT_TRUE(wait_for(conf_mgr->lc,participant_mgr->lc,&conf_mgr->stat.number_of_LinphoneCallEnd,(initial_conf_stats.number_of_LinphoneCallEnd + 1))); BC_ASSERT_TRUE(wait_for(conf_mgr->lc,participant_mgr->lc,&participant_mgr->stat.number_of_LinphoneCallReleased,(initial_participant_stats.number_of_LinphoneCallReleased + 1))); BC_ASSERT_TRUE(wait_for(conf_mgr->lc,participant_mgr->lc,&conf_mgr->stat.number_of_LinphoneCallReleased,(initial_conf_stats.number_of_LinphoneCallReleased + 1))); check_participant_removal(lcs, conf_mgr, participant_mgr, participants, participant_size, initial_conf_stats, initial_participant_stats, initial_other_participants_stats, initial_other_participants_state, local_participant_is_in); bctbx_list_free(lcs); if (initial_other_participants_stats) {
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
ms_free(initial_other_participants_stats); } if (initial_other_participants_state) { ms_free(initial_other_participants_state); } participant_uri = linphone_address_new(linphone_core_get_identity(participant_mgr->lc)); participant_conference = linphone_core_search_conference(participant_mgr->lc, NULL, participant_uri, local_conference_address, NULL); linphone_address_unref(participant_uri); linphone_address_unref(local_conference_address); BC_ASSERT_PTR_NULL(participant_conference); } return participants; } LinphoneStatus terminate_conference(bctbx_list_t *participants, LinphoneCoreManager * conf_mgr, LinphoneConference * conference, LinphoneCoreManager * focus_mgr) { bctbx_list_t* lcs=NULL; stats* lcm_stats = NULL; bool_t* call_is_in_conference = NULL; LinphoneCall* conf_call=NULL; LinphoneCall* participant_call=NULL; int no_participant_left_conference = 0; int counter = 1; for (bctbx_list_t *it = participants; it; it = bctbx_list_next(it)) { LinphoneCoreManager * m = (LinphoneCoreManager *)bctbx_list_get_data(it); // Allocate memory lcm_stats = (stats*)realloc(lcm_stats, counter * sizeof(stats)); call_is_in_conference = (bool_t*)realloc(call_is_in_conference, counter * sizeof(bool_t)); lcs=bctbx_list_append(lcs,m->lc); if (focus_mgr) { conf_call=linphone_core_get_call_by_remote_address2(focus_mgr->lc,m->identity); participant_call=linphone_core_get_call_by_remote_address2(m->lc,focus_mgr->identity); } else { conf_call=linphone_core_get_call_by_remote_address2(conf_mgr->lc,m->identity); participant_call=linphone_core_get_call_by_remote_address2(m->lc,conf_mgr->identity); } BC_ASSERT_PTR_NOT_NULL(conf_call); BC_ASSERT_PTR_NOT_NULL(participant_call); // Append element lcm_stats[counter - 1] = m->stat; if (conf_call) { call_is_in_conference[counter - 1] = linphone_call_is_in_conference(conf_call); if (!linphone_call_is_in_conference(conf_call)) no_participant_left_conference++; } else { call_is_in_conference[counter - 1] = FALSE; } // Increment counter counter++; } lcs=bctbx_list_append(lcs,conf_mgr->lc); lcm_stats = (stats*)realloc(lcm_stats, counter * sizeof(stats)); lcm_stats[counter - 1] = conf_mgr->stat; call_is_in_conference = (bool_t*)realloc(call_is_in_conference, counter * sizeof(bool_t)); if (focus_mgr) { conf_call=linphone_core_get_call_by_remote_address2(focus_mgr->lc,conf_mgr->identity); participant_call=linphone_core_get_call_by_remote_address2(conf_mgr->lc,focus_mgr->identity);
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
BC_ASSERT_PTR_NOT_NULL(conf_call); BC_ASSERT_PTR_NOT_NULL(participant_call); if (conf_call) { call_is_in_conference[counter - 1] = linphone_call_is_in_conference(conf_call); if (!linphone_call_is_in_conference(conf_call)) no_participant_left_conference++; } else { call_is_in_conference[counter - 1] = FALSE; } counter++; lcs=bctbx_list_append(lcs,focus_mgr->lc); lcm_stats = (stats*)realloc(lcm_stats, counter * sizeof(stats)); lcm_stats[counter - 1] = focus_mgr->stat; call_is_in_conference = (bool_t*)realloc(call_is_in_conference, counter * sizeof(bool_t)); call_is_in_conference[counter - 1] = FALSE; } else { call_is_in_conference[counter - 1] = FALSE; } LinphoneConference *conferenceToDestroy = conference; if (!conferenceToDestroy) { conferenceToDestroy = linphone_core_get_conference(conf_mgr->lc); } BC_ASSERT_PTR_NOT_NULL(conferenceToDestroy); if (conferenceToDestroy) { unsigned int no_participants = linphone_conference_get_participant_count(conferenceToDestroy) + no_participant_left_conference; if (conferenceToDestroy) { bool_t core_held_conference = (conferenceToDestroy == linphone_core_get_conference(conf_mgr->lc)); linphone_conference_terminate(conferenceToDestroy); if (focus_mgr) { finish_terminate_remote_conference(lcs, lcm_stats, call_is_in_conference, conf_mgr, focus_mgr, no_participants, core_held_conference); } else { finish_terminate_local_conference(lcs, lcm_stats, call_is_in_conference, conf_mgr, no_participants, core_held_conference); } } } ms_free(call_is_in_conference); ms_free(lcm_stats); bctbx_list_free(lcs); return 0; } #if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) #pragma GCC diagnostic push #endif #ifdef _MSC_VER #pragma warning(disable : 4996) #else #pragma GCC diagnostic ignored "-Wdeprecated-declarations" #endif void linphone_core_manager_init2(LinphoneCoreManager *mgr, const char* rc_file, const char* phone_alias) { mgr->number_of_bcunit_error_at_creation = bc_get_number_of_failures(); mgr->cbs = linphone_factory_create_core_cbs(linphone_factory_get()); linphone_core_cbs_set_registration_state_changed(mgr->cbs, registration_state_changed); linphone_core_cbs_set_auth_info_requested(mgr->cbs, auth_info_requested); linphone_core_cbs_set_call_state_changed(mgr->cbs, call_state_changed); linphone_core_cbs_set_message_received(mgr->cbs, message_received); linphone_core_cbs_set_is_composing_received(mgr->cbs, is_composing_received); linphone_core_cbs_set_new_subscription_requested(mgr->cbs, new_subscription_requested); linphone_core_cbs_set_notify_presence_received(mgr->cbs, notify_presence_received); linphone_core_cbs_set_notify_presence_received_for_uri_or_tel(mgr->cbs, notify_presence_received_for_uri_or_tel); linphone_core_cbs_set_transfer_state_changed(mgr->cbs, linphone_transfer_state_changed); linphone_core_cbs_set_info_received(mgr->cbs, info_message_received); linphone_core_cbs_set_subscription_state_changed(mgr->cbs, linphone_subscription_state_change); linphone_core_cbs_set_notify_received(mgr->cbs, linphone_notify_received); linphone_core_cbs_set_subscribe_received(mgr->cbs, linphone_subscribe_received); linphone_core_cbs_set_publish_state_changed(mgr->cbs, linphone_publish_state_changed); linphone_core_cbs_set_configuring_status(mgr->cbs, linphone_configuration_status);
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
linphone_core_cbs_set_call_encryption_changed(mgr->cbs, linphone_call_encryption_changed); linphone_core_cbs_set_network_reachable(mgr->cbs, network_reachable); linphone_core_cbs_set_dtmf_received(mgr->cbs, dtmf_received); linphone_core_cbs_set_call_stats_updated(mgr->cbs, call_stats_updated); linphone_core_cbs_set_global_state_changed(mgr->cbs, global_state_changed); linphone_core_cbs_set_message_sent(mgr->cbs, liblinphone_tester_chat_room_msg_sent); linphone_core_cbs_set_first_call_started(mgr->cbs, first_call_started); linphone_core_cbs_set_last_call_ended(mgr->cbs, last_call_ended); linphone_core_cbs_set_audio_device_changed(mgr->cbs, audio_device_changed); linphone_core_cbs_set_audio_devices_list_updated(mgr->cbs, audio_devices_list_updated); linphone_core_cbs_set_imee_user_registration(mgr->cbs, liblinphone_tester_x3dh_user_created); linphone_core_cbs_set_conference_state_changed(mgr->cbs, core_conference_state_changed); mgr->phone_alias = phone_alias ? ms_strdup(phone_alias) : NULL; reset_counters(&mgr->stat); manager_count++; } void linphone_core_manager_init_with_db(LinphoneCoreManager *mgr, const char* rc_file, const char* phone_alias, const char* linphone_db, const char *lime_db, const char *call_logs_db, const char *zrtp_secrets_db) { linphone_core_manager_init2(mgr, rc_file, phone_alias); if (rc_file) mgr->rc_path = ms_strdup_printf("rcfiles/%s", rc_file); if (linphone_db == NULL && lime_db == NULL) { generate_random_database_path(mgr); } else { mgr->database_path = bctbx_strdup(linphone_db); mgr->lime_database_path = bctbx_strdup(lime_db); mgr->call_logs_database_path = ms_strdup(call_logs_db); mgr->zrtp_secrets_database_path = ms_strdup(zrtp_secrets_db); } linphone_core_manager_configure(mgr); } void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, const char* phone_alias) { linphone_core_manager_init_with_db(mgr, rc_file, phone_alias, NULL, NULL, NULL, NULL); } void linphone_core_manager_init_shared(LinphoneCoreManager *mgr, const char* rc_file, const char* phone_alias, LinphoneCoreManager *mgr_to_copy) { linphone_core_manager_init2(mgr, rc_file, phone_alias); if (mgr_to_copy == NULL) { if (rc_file) mgr->rc_path = ms_strdup_printf("rcfiles/%s", rc_file); generate_random_database_path(mgr); } else { mgr->rc_path = ms_strdup(mgr_to_copy->rc_path); mgr->database_path = ms_strdup(mgr_to_copy->database_path); mgr->lime_database_path = ms_strdup(mgr_to_copy->lime_database_path); mgr->call_logs_database_path = ms_strdup(mgr_to_copy->call_logs_database_path); mgr->zrtp_secrets_database_path = ms_strdup(mgr_to_copy->zrtp_secrets_database_path); } linphone_core_manager_configure(mgr); } #if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4) #pragma GCC diagnostic pop #endif void linphone_core_manager_start(LinphoneCoreManager *mgr, bool_t check_for_proxies) { LinphoneProxyConfig* proxy; int proxy_count; if (linphone_core_start(mgr->lc) == -1) { ms_error("Core [%p] failed to start", mgr->lc); } /*BC_ASSERT_EQUAL(bctbx_list_size(linphone_core_get_proxy_config_list(lc)),proxy_count, int, "%d");*/ if (check_for_proxies){ /**/ proxy_count=(int)bctbx_list_size(linphone_core_get_proxy_config_list(mgr->lc)); }else{ proxy_count=0;
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
/*this is to prevent registration to go on*/ linphone_core_set_network_reachable(mgr->lc, FALSE); } if (proxy_count){ #define REGISTER_TIMEOUT 20 /* seconds */ int success = wait_for_until(mgr->lc,NULL,&mgr->stat.number_of_LinphoneRegistrationOk, proxy_count,(REGISTER_TIMEOUT * 1000 * proxy_count)); if( !success ){ ms_error("Did not register after %d seconds for %d proxies", REGISTER_TIMEOUT, proxy_count); } } BC_ASSERT_EQUAL(mgr->stat.number_of_LinphoneRegistrationOk,proxy_count, int, "%d"); enable_codec(mgr->lc,"PCMU",8000); proxy = linphone_core_get_default_proxy_config(mgr->lc); if (proxy) { if (mgr->identity){ linphone_address_unref(mgr->identity); } mgr->identity = linphone_address_clone(linphone_proxy_config_get_identity_address(proxy)); linphone_address_clean(mgr->identity); } linphone_core_manager_wait_for_stun_resolution(mgr); if (!check_for_proxies){ /*now that stun server resolution is done, we can start registering*/ linphone_core_set_network_reachable(mgr->lc, TRUE); }else wait_for_until(mgr->lc, NULL, NULL, 0, 20);// process events that are in main queue (fix: DNS timeout when loading linphone database) } LinphoneCoreManager* linphone_core_manager_create2(const char* rc_file, const char* phone_alias) { LinphoneCoreManager *manager = ms_new0(LinphoneCoreManager, 1); linphone_core_manager_init(manager, rc_file, phone_alias); return manager; } LinphoneCoreManager* linphone_core_manager_create(const char* rc_file) { return linphone_core_manager_create2(rc_file, NULL); } LinphoneCoreManager* linphone_core_manager_new4(const char* rc_file, int check_for_proxies, const char* phone_alias, const char* contact_params, int expires) { /* This function is for testing purposes. */ LinphoneCoreManager *manager = ms_new0(LinphoneCoreManager, 1); linphone_core_manager_init(manager, rc_file, phone_alias); LinphoneProxyConfig *config = linphone_core_get_default_proxy_config(manager->lc); linphone_proxy_config_edit(config); linphone_proxy_config_set_contact_parameters(config, contact_params); linphone_proxy_config_set_expires(config, expires); linphone_proxy_config_done(config); linphone_core_manager_start(manager, check_for_proxies); return manager; } LinphoneCoreManager* linphone_core_manager_new3(const char* rc_file, bool_t check_for_proxies, const char* phone_alias) { LinphoneCoreManager *manager = linphone_core_manager_create2(rc_file, phone_alias); linphone_core_manager_start(manager, check_for_proxies); return manager; } LinphoneCoreManager* linphone_core_manager_new_with_proxies_check(const char* rc_file, bool_t check_for_proxies) { return linphone_core_manager_new3(rc_file, check_for_proxies, NULL); } LinphoneCoreManager *linphone_core_manager_new(const char *rc_file) { return linphone_core_manager_new_with_proxies_check(rc_file, TRUE); }
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
void linphone_core_start_process_remote_notification (LinphoneCoreManager *mgr, const char *callid) { LinphoneCall *incomingCall = linphone_core_get_call_by_callid(mgr->lc, callid); if (!incomingCall) { incomingCall = linphone_call_new_incoming_with_callid(mgr->lc, callid); linphone_call_start_basic_incoming_notification(incomingCall); linphone_call_start_push_incoming_notification(incomingCall); linphone_core_ensure_registered(mgr->lc); } } /* same as new but insert the rc_local in the core manager before the init and provide path to db files */ LinphoneCoreManager* linphone_core_manager_create_local(const char* rc_factory, const char* rc_local, const char *linphone_db, const char *lime_db, const char *call_logs_db, const char *zrtp_secrets_db) { LinphoneCoreManager *manager = ms_new0(LinphoneCoreManager, 1); manager->rc_local = bctbx_strdup(rc_local); linphone_core_manager_init_with_db(manager, rc_factory, NULL, linphone_db, lime_db, call_logs_db, zrtp_secrets_db); return manager; } LinphoneCoreManager* linphone_core_manager_new_local(const char* rc_factory, const char* rc_local, const char *linphone_db, const char *lime_db, const char *call_logs_db, const char *zrtp_secrets_db) { LinphoneCoreManager *manager = linphone_core_manager_create_local(rc_factory, rc_local, linphone_db, lime_db, call_logs_db, zrtp_secrets_db); linphone_core_manager_start(manager, TRUE); return manager; } /** * Create a LinphoneCoreManager that holds a shared Core. * mgr_to_copy is used to create a second LinphoneCoreManager with the same identity. * If mgr_to_copy has a value, rc_file parameter is ignored. */ LinphoneCoreManager* linphone_core_manager_create_shared(const char *rc_file, const char *app_group_id, bool_t main_core, LinphoneCoreManager *mgr_to_copy) { LinphoneCoreManager *manager = ms_new0(LinphoneCoreManager, 1); manager->app_group_id = ms_strdup(app_group_id); manager->main_core = main_core; linphone_core_manager_init_shared(manager, rc_file, NULL, mgr_to_copy); return manager; } void linphone_core_manager_stop(LinphoneCoreManager *mgr) { if (mgr->lc) { const char *record_file = linphone_core_get_record_file(mgr->lc); if (!liblinphone_tester_keep_record_files && record_file && ortp_file_exist(record_file)==0) { if ((bc_get_number_of_failures() - mgr->number_of_bcunit_error_at_creation)>0) { ms_error("Test has failed, keeping recorded file [%s]", record_file); } else { unlink(record_file); } } linphone_core_stop(mgr->lc); linphone_core_unref(mgr->lc); mgr->lc = NULL; } } void linphone_core_manager_uninit_after_stop_async(LinphoneCoreManager *mgr) { if (mgr->lc) { const char *record_file = linphone_core_get_record_file(mgr->lc); if (!liblinphone_tester_keep_record_files && record_file && ortp_file_exist(record_file)==0) { if ((bc_get_number_of_failures() - mgr->number_of_bcunit_error_at_creation)>0) { ms_error("Test has failed, keeping recorded file [%s]", record_file); } else { unlink(record_file); } } linphone_core_unref(mgr->lc); mgr->lc = NULL;
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
} } void linphone_core_manager_reinit(LinphoneCoreManager *mgr) { char *uuid = NULL; if (mgr->lc) { if (linphone_config_get_string(linphone_core_get_config(mgr->lc), "misc", "uuid", NULL)) uuid = bctbx_strdup(linphone_config_get_string(linphone_core_get_config(mgr->lc), "misc", "uuid", NULL)); linphone_core_set_network_reachable(mgr->lc, FALSE); // to avoid unregister linphone_core_unref(mgr->lc); mgr->lc = NULL; } linphone_core_manager_configure(mgr); reset_counters(&mgr->stat); // Make sure gruu is preserved linphone_config_set_string(linphone_core_get_config(mgr->lc), "misc", "uuid", uuid); if (uuid) bctbx_free(uuid); } void linphone_core_manager_restart(LinphoneCoreManager *mgr, bool_t check_for_proxies) { linphone_core_manager_reinit(mgr); linphone_core_manager_start(mgr, check_for_proxies); } void linphone_core_manager_uninit2(LinphoneCoreManager *mgr, bool_t unlinkDb) { int old_log_level = linphone_core_get_log_level_mask(); linphone_core_set_log_level(ORTP_ERROR); if (mgr->phone_alias) { ms_free(mgr->phone_alias); } if (mgr->identity) { linphone_address_unref(mgr->identity); } if (mgr->rc_path) bctbx_free(mgr->rc_path); if (mgr->database_path) { if (unlinkDb == TRUE) { unlink(mgr->database_path); } bc_free(mgr->database_path); } if (mgr->lime_database_path) { if (unlinkDb == TRUE) { unlink(mgr->lime_database_path); } bc_free(mgr->lime_database_path); } if (mgr->call_logs_database_path) { if (unlinkDb == TRUE) { unlink(mgr->call_logs_database_path); } bc_free(mgr->call_logs_database_path); } if (mgr->zrtp_secrets_database_path) { if (unlinkDb == TRUE) { unlink(mgr->zrtp_secrets_database_path); } bc_free(mgr->zrtp_secrets_database_path); } if (mgr->app_group_id) bctbx_free(mgr->app_group_id); if (mgr->cbs) linphone_core_cbs_unref(mgr->cbs); if (mgr->rc_local) { bctbx_free(mgr->rc_local); mgr->rc_local = NULL; }
1821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
reset_counters(&mgr->stat); manager_count--; linphone_core_set_log_level_mask(old_log_level); } void linphone_core_manager_uninit(LinphoneCoreManager *mgr) { linphone_core_manager_uninit2(mgr, TRUE); } void linphone_core_manager_wait_for_stun_resolution(LinphoneCoreManager *mgr) { LinphoneNatPolicy *nat_policy = linphone_core_get_nat_policy(mgr->lc); if ((nat_policy != NULL) && (linphone_nat_policy_get_stun_server(nat_policy) != NULL) && (linphone_nat_policy_stun_enabled(nat_policy) || linphone_nat_policy_turn_enabled(nat_policy)) && (linphone_nat_policy_ice_enabled(nat_policy))) { /*before we go, ensure that the stun server is resolved, otherwise all ice related test will fail*/ BC_ASSERT_TRUE(wait_for_stun_resolution(mgr)); } } void linphone_core_manager_uninit3(LinphoneCoreManager* mgr) { if (mgr->lc && linphone_core_get_global_state(mgr->lc) != LinphoneGlobalOff && !linphone_core_is_network_reachable(mgr->lc)) { int previousNbRegistrationOk = mgr->stat.number_of_LinphoneRegistrationOk; linphone_core_set_network_reachable(mgr->lc, TRUE); wait_for_until(mgr->lc, NULL, &mgr->stat.number_of_LinphoneRegistrationOk, previousNbRegistrationOk + 1, 2000); } linphone_core_manager_stop(mgr); linphone_core_manager_uninit(mgr); } void linphone_core_manager_destroy(LinphoneCoreManager* mgr) { linphone_core_manager_uninit3(mgr); ms_free(mgr); } void linphone_core_manager_destroy_after_stop_async(LinphoneCoreManager* mgr) { if (mgr->lc && !linphone_core_is_network_reachable(mgr->lc)) { int previousNbRegistrationOk = mgr->stat.number_of_LinphoneRegistrationOk; linphone_core_set_network_reachable(mgr->lc, TRUE); wait_for_until(mgr->lc, NULL, &mgr->stat.number_of_LinphoneRegistrationOk, previousNbRegistrationOk + 1, 2000); } linphone_core_manager_uninit_after_stop_async(mgr); linphone_core_manager_uninit(mgr); ms_free(mgr); } void linphone_core_manager_delete_chat_room (LinphoneCoreManager *mgr, LinphoneChatRoom *cr, bctbx_list_t *coresList) { stats mgrStats = mgr->stat; if (cr) { linphone_core_delete_chat_room(mgr->lc, cr); BC_ASSERT_TRUE(wait_for_list(coresList, &mgr->stat.number_of_LinphoneConferenceStateDeleted, mgrStats.number_of_LinphoneConferenceStateDeleted + 1, 10000)); } } int liblinphone_tester_ipv6_available(void){ if (liblinphonetester_ipv6) { struct addrinfo *ai=bctbx_ip_address_to_addrinfo(AF_INET6,SOCK_STREAM,liblinphone_tester_ipv6_probing_address,53); if (ai){ struct sockaddr_storage ss; struct addrinfo src; socklen_t slen=sizeof(ss); char localip[128]; int port=0; belle_sip_get_src_addr_for(ai->ai_addr,(socklen_t)ai->ai_addrlen,(struct sockaddr*) &ss,&slen,4444); src.ai_addr=(struct sockaddr*) &ss; src.ai_addrlen=slen; bctbx_addrinfo_to_ip_address(&src,localip, sizeof(localip),&port); freeaddrinfo(ai); return strcmp(localip,"::1")!=0; }
1891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
} return FALSE; } int liblinphone_tester_ipv4_available(void){ struct addrinfo *ai=bctbx_ip_address_to_addrinfo(AF_INET,SOCK_STREAM,"212.27.40.240",53); if (ai){ struct sockaddr_storage ss; struct addrinfo src; socklen_t slen=sizeof(ss); char localip[128]; int port=0; belle_sip_get_src_addr_for(ai->ai_addr,(socklen_t)ai->ai_addrlen,(struct sockaddr*) &ss,&slen,4444); src.ai_addr=(struct sockaddr*) &ss; src.ai_addrlen=slen; bctbx_addrinfo_to_ip_address(&src,localip, sizeof(localip),&port); freeaddrinfo(ai); return strcmp(localip,"127.0.0.1")!=0; } return FALSE; } void liblinphone_tester_keep_accounts( int keep ){ liblinphone_tester_keep_accounts_flag = keep; } void liblinphone_tester_keep_recorded_files(int keep){ liblinphone_tester_keep_record_files = keep; } void liblinphone_tester_disable_leak_detector(int disabled){ liblinphone_tester_leak_detector_disabled = disabled; } void liblinphone_tester_clear_accounts(void){ account_manager_destroy(); } static int linphone_core_manager_get_max_audio_bw_base(const int array[],int array_size) { int i,result=0; for (i=0; i<array_size; i++) { result = MAX(result,array[i]); } return result; } static int linphone_core_manager_get_mean_audio_bw_base(const int array[],int array_size) { int i,result=0; for (i=0; i<array_size; i++) { result += array[i]; } return result/array_size; } int linphone_core_manager_get_max_audio_down_bw(const LinphoneCoreManager *mgr) { return linphone_core_manager_get_max_audio_bw_base(mgr->stat.audio_download_bandwidth , sizeof(mgr->stat.audio_download_bandwidth)/sizeof(int)); } int linphone_core_manager_get_max_audio_up_bw(const LinphoneCoreManager *mgr) { return linphone_core_manager_get_max_audio_bw_base(mgr->stat.audio_upload_bandwidth , sizeof(mgr->stat.audio_upload_bandwidth)/sizeof(int)); } int linphone_core_manager_get_mean_audio_down_bw(const LinphoneCoreManager *mgr) { return linphone_core_manager_get_mean_audio_bw_base(mgr->stat.audio_download_bandwidth , sizeof(mgr->stat.audio_download_bandwidth)/sizeof(int)); } int linphone_core_manager_get_mean_audio_up_bw(const LinphoneCoreManager *mgr) { return linphone_core_manager_get_mean_audio_bw_base(mgr->stat.audio_upload_bandwidth , sizeof(mgr->stat.audio_upload_bandwidth)/sizeof(int));
1961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
} void liblinphone_tester_before_each(void) { if (!liblinphone_tester_leak_detector_disabled){ belle_sip_object_enable_leak_detector(TRUE); leaked_objects_count = belle_sip_object_get_object_count(); } } static char* all_leaks_buffer = NULL; void liblinphone_tester_after_each(void) { linphone_factory_clean(); if (!liblinphone_tester_leak_detector_disabled){ int leaked_objects = belle_sip_object_get_object_count() - leaked_objects_count; if (leaked_objects > 0) { char* format = ms_strdup_printf("%d object%s leaked in suite [%s] test [%s], please fix that!", leaked_objects, leaked_objects>1?"s were":" was", bc_tester_current_suite_name(), bc_tester_current_test_name()); belle_sip_object_dump_active_objects(); belle_sip_object_flush_active_objects(); bc_tester_printf(ORTP_MESSAGE, format); ms_error("%s", format); all_leaks_buffer = ms_strcat_printf(all_leaks_buffer, "\n%s", format); ms_free(format); } // prevent any future leaks { const char **tags = bc_tester_current_test_tags(); int leaks_expected = (tags && ((tags[0] && !strcmp(tags[0], "LeaksMemory")) || (tags[1] && !strcmp(tags[1], "LeaksMemory")))); // if the test is NOT marked as leaking memory and it actually is, we should make it fail if (!leaks_expected && leaked_objects > 0) { BC_FAIL("This test is leaking memory!"); // and reciprocally } else if (leaks_expected && leaked_objects == 0) { BC_FAIL("This test is not leaking anymore, please remove LeaksMemory tag!"); } } } if (manager_count != 0) { ms_fatal("%d Linphone core managers are still alive!", manager_count); } } void liblinphone_tester_uninit(void) { // show all leaks that happened during the test if (all_leaks_buffer) { bc_tester_printf(ORTP_MESSAGE, all_leaks_buffer); ms_free(all_leaks_buffer); all_leaks_buffer = NULL; } bc_tester_uninit(); bctbx_uninit_logger(); } void compare_files(const char *path1, const char *path2) { uint8_t *buf1; uint8_t *buf2; bctbx_vfs_file_t* f1 = bctbx_file_open(bctbx_vfs_get_default(), path1, "r"); bctbx_vfs_file_t* f2 = bctbx_file_open(bctbx_vfs_get_default(), path2, "r"); BC_ASSERT_PTR_NOT_NULL(f1); BC_ASSERT_PTR_NOT_NULL(f2); if (f1 == NULL || f2 == NULL) return; int64_t s1 = bctbx_file_size(f1);
2031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
int64_t s2 = bctbx_file_size(f2); BC_ASSERT_TRUE(s1==s2); BC_ASSERT_TRUE(s1 != BCTBX_VFS_ERROR); if (s1 != s2 || s1 == BCTBX_VFS_ERROR) return; ssize_t fileSize = (ssize_t)s1; buf1 = bctbx_malloc(fileSize); buf2 = bctbx_malloc(fileSize); BC_ASSERT_TRUE(bctbx_file_read(f1, buf1, (size_t)fileSize, 0) == fileSize); BC_ASSERT_TRUE(bctbx_file_read(f2, buf2, (size_t)fileSize, 0) == fileSize); bctbx_file_close(f1); bctbx_file_close(f2); if (buf1 && buf2){ BC_ASSERT_EQUAL(memcmp(buf1, buf2, (size_t)fileSize), 0, int, "%d"); } if (buf1) ms_free(buf1); if (buf2) ms_free(buf2); } void registration_state_changed(struct _LinphoneCore *lc, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message){ stats* counters; ms_message("New registration state %s for user id [%s] at proxy [%s]\n" ,linphone_registration_state_to_string(cstate) ,linphone_proxy_config_get_identity(cfg) ,linphone_proxy_config_get_addr(cfg)); counters = get_stats(lc); switch (cstate) { case LinphoneRegistrationNone:counters->number_of_LinphoneRegistrationNone++;break; case LinphoneRegistrationProgress:counters->number_of_LinphoneRegistrationProgress++;break; case LinphoneRegistrationOk:counters->number_of_LinphoneRegistrationOk++;break; case LinphoneRegistrationCleared:counters->number_of_LinphoneRegistrationCleared++;break; case LinphoneRegistrationFailed:counters->number_of_LinphoneRegistrationFailed++;break; default: BC_FAIL("unexpected event");break; } } void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg){ stats* counters = get_stats(lc); if (linphone_call_is_op_configured(call)) { LinphoneCallLog *calllog = linphone_call_get_call_log(call); char* to=linphone_address_as_string(linphone_call_log_get_to_address(calllog)); char* from=linphone_address_as_string(linphone_call_log_get_from_address(calllog)); const LinphoneAddress *to_addr = linphone_call_get_to_address(call); const LinphoneAddress *remote_addr = linphone_call_get_remote_address(call); //const LinphoneAddress *from_addr = linphone_call_get_from_address(call); BC_ASSERT_PTR_NOT_NULL(to_addr); //BC_ASSERT_PTR_NOT_NULL(from_addr); BC_ASSERT_PTR_NOT_NULL(remote_addr); ms_message(" %s call from [%s] to [%s], new state is [%s]" ,linphone_call_log_get_dir(calllog)==LinphoneCallIncoming?"Incoming":"Outgoing" ,from ,to ,linphone_call_state_to_string(cstate)); ms_free(to); ms_free(from); } switch (cstate) { case LinphoneCallIncomingReceived:counters->number_of_LinphoneCallIncomingReceived++;break; case LinphoneCallPushIncomingReceived:counters->number_of_LinphoneCallPushIncomingReceived++;break; case LinphoneCallOutgoingInit :counters->number_of_LinphoneCallOutgoingInit++;break;
2101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170
case LinphoneCallOutgoingProgress :counters->number_of_LinphoneCallOutgoingProgress++;break; case LinphoneCallOutgoingRinging :counters->number_of_LinphoneCallOutgoingRinging++;break; case LinphoneCallOutgoingEarlyMedia :counters->number_of_LinphoneCallOutgoingEarlyMedia++;break; case LinphoneCallConnected :counters->number_of_LinphoneCallConnected++;break; case LinphoneCallStreamsRunning :counters->number_of_LinphoneCallStreamsRunning++;break; case LinphoneCallPausing :counters->number_of_LinphoneCallPausing++;break; case LinphoneCallPaused :counters->number_of_LinphoneCallPaused++;break; case LinphoneCallResuming :counters->number_of_LinphoneCallResuming++;break; case LinphoneCallRefered :counters->number_of_LinphoneCallRefered++;break; case LinphoneCallError :counters->number_of_LinphoneCallError++;break; case LinphoneCallEnd :counters->number_of_LinphoneCallEnd++;break; case LinphoneCallPausedByRemote :counters->number_of_LinphoneCallPausedByRemote++;break; case LinphoneCallUpdatedByRemote :counters->number_of_LinphoneCallUpdatedByRemote++;break; case LinphoneCallIncomingEarlyMedia :counters->number_of_LinphoneCallIncomingEarlyMedia++;break; case LinphoneCallUpdating :counters->number_of_LinphoneCallUpdating++;break; case LinphoneCallReleased :counters->number_of_LinphoneCallReleased++;break; case LinphoneCallEarlyUpdating: counters->number_of_LinphoneCallEarlyUpdating++;break; case LinphoneCallEarlyUpdatedByRemote: counters->number_of_LinphoneCallEarlyUpdatedByRemote++;break; default: BC_FAIL("unexpected event");break; } } void message_received(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage* msg) { char* from=linphone_address_as_string(linphone_chat_message_get_from_address(msg)); stats* counters; const char *text=linphone_chat_message_get_text(msg); const char *external_body_url=linphone_chat_message_get_external_body_url(msg); ms_message("Message from [%s] is [%s] , external URL [%s]",from?from:"" ,text?text:"" ,external_body_url?external_body_url:""); ms_free(from); counters = get_stats(lc); counters->number_of_LinphoneMessageReceived++; if (counters->last_received_chat_message) { linphone_chat_message_unref(counters->last_received_chat_message); } counters->last_received_chat_message=linphone_chat_message_ref(msg); LinphoneContent * content = linphone_chat_message_get_file_transfer_information(msg); if (content) counters->number_of_LinphoneMessageReceivedWithFile++; else if (linphone_chat_message_get_external_body_url(msg)) { counters->number_of_LinphoneMessageExtBodyReceived++; if (message_external_body_url) { BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_external_body_url(msg),message_external_body_url); message_external_body_url=NULL; } } if (linphone_config_get_bool(linphone_core_get_config(lc), "net", "bad_net", 0)) { sal_set_send_error(linphone_core_get_sal(lc), 1500); } } void is_composing_received(LinphoneCore *lc, LinphoneChatRoom *room) { stats *counters = get_stats(lc); if (linphone_chat_room_is_remote_composing(room)) { counters->number_of_LinphoneIsComposingActiveReceived++; } else { counters->number_of_LinphoneIsComposingIdleReceived++; } } void new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url){ stats* counters; const LinphoneAddress *addr = linphone_friend_get_address(lf); struct addrinfo *ai; const char *domain; char *ipaddr;
2171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
if (addr != NULL) { char* from=linphone_address_as_string(addr); ms_message("New subscription request from [%s] url [%s]",from,url); ms_free(from); } counters = get_stats(lc); counters->number_of_NewSubscriptionRequest++; domain = linphone_address_get_domain(addr); if (domain[0] == '['){ ipaddr = ms_strdup(domain+1); ipaddr[strlen(ipaddr)] = '\0'; }else ipaddr = ms_strdup(domain); ai = bctbx_ip_address_to_addrinfo(strchr(domain, ':') != NULL ? AF_INET6 : AF_INET, SOCK_DGRAM, ipaddr, 4444); ms_free(ipaddr); if (ai){/* this SUBSCRIBE comes from friend without registered SIP account, don't attempt to subscribe, it will fail*/ ms_message("Disabling subscription because friend has numeric host."); linphone_friend_enable_subscribes(lf, FALSE); bctbx_freeaddrinfo(ai); } linphone_core_add_friend(lc,lf); /*accept subscription*/ } void notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf) { stats* counters; unsigned int i; const LinphoneAddress *addr = linphone_friend_get_address(lf); if (addr != NULL) { char* from=linphone_address_as_string(addr); ms_message("New Notify request from [%s] ",from); ms_free(from); } counters = get_stats(lc); counters->number_of_NotifyPresenceReceived++; counters->last_received_presence = linphone_friend_get_presence_model(lf); if (linphone_presence_model_get_basic_status(counters->last_received_presence) == LinphonePresenceBasicStatusOpen) { counters->number_of_LinphonePresenceBasicStatusOpen++; } else if (linphone_presence_model_get_basic_status(counters->last_received_presence) == LinphonePresenceBasicStatusClosed) { counters->number_of_LinphonePresenceBasicStatusClosed++; } else { ms_error("Unexpected basic status [%i]",linphone_presence_model_get_basic_status(counters->last_received_presence)); } if (counters->last_received_presence && linphone_presence_model_get_nb_activities(counters->last_received_presence) > 0) { for (i=0;counters->last_received_presence&&i<linphone_presence_model_get_nb_activities(counters->last_received_presence); i++) { LinphonePresenceActivity *activity = linphone_presence_model_get_nth_activity(counters->last_received_presence, i); switch (linphone_presence_activity_get_type(activity)) { case LinphonePresenceActivityAppointment: counters->number_of_LinphonePresenceActivityAppointment++; break; case LinphonePresenceActivityAway: counters->number_of_LinphonePresenceActivityAway++; break; case LinphonePresenceActivityBreakfast: counters->number_of_LinphonePresenceActivityBreakfast++; break; case LinphonePresenceActivityBusy: counters->number_of_LinphonePresenceActivityBusy++; break; case LinphonePresenceActivityDinner: counters->number_of_LinphonePresenceActivityDinner++; break; case LinphonePresenceActivityHoliday: counters->number_of_LinphonePresenceActivityHoliday++; break; case LinphonePresenceActivityInTransit: counters->number_of_LinphonePresenceActivityInTransit++; break; case LinphonePresenceActivityLookingForWork: counters->number_of_LinphonePresenceActivityLookingForWork++; break; case LinphonePresenceActivityLunch: counters->number_of_LinphonePresenceActivityLunch++; break; case LinphonePresenceActivityMeal: counters->number_of_LinphonePresenceActivityMeal++; break; case LinphonePresenceActivityMeeting: counters->number_of_LinphonePresenceActivityMeeting++; break; case LinphonePresenceActivityOnThePhone:
2241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310
counters->number_of_LinphonePresenceActivityOnThePhone++; break; case LinphonePresenceActivityOther: counters->number_of_LinphonePresenceActivityOther++; break; case LinphonePresenceActivityPerformance: counters->number_of_LinphonePresenceActivityPerformance++; break; case LinphonePresenceActivityPermanentAbsence: counters->number_of_LinphonePresenceActivityPermanentAbsence++; break; case LinphonePresenceActivityPlaying: counters->number_of_LinphonePresenceActivityPlaying++; break; case LinphonePresenceActivityPresentation: counters->number_of_LinphonePresenceActivityPresentation++; break; case LinphonePresenceActivityShopping: counters->number_of_LinphonePresenceActivityShopping++; break; case LinphonePresenceActivitySleeping: counters->number_of_LinphonePresenceActivitySleeping++; break; case LinphonePresenceActivitySpectator: counters->number_of_LinphonePresenceActivitySpectator++; break; case LinphonePresenceActivitySteering: counters->number_of_LinphonePresenceActivitySteering++; break; case LinphonePresenceActivityTravel: counters->number_of_LinphonePresenceActivityTravel++; break; case LinphonePresenceActivityTV: counters->number_of_LinphonePresenceActivityTV++; break; case LinphonePresenceActivityUnknown: counters->number_of_LinphonePresenceActivityUnknown++; break; case LinphonePresenceActivityVacation: counters->number_of_LinphonePresenceActivityVacation++; break; case LinphonePresenceActivityWorking: counters->number_of_LinphonePresenceActivityWorking++; break; case LinphonePresenceActivityWorship: counters->number_of_LinphonePresenceActivityWorship++; break; } } } else { if (linphone_presence_model_get_basic_status(counters->last_received_presence) == LinphonePresenceBasicStatusOpen) counters->number_of_LinphonePresenceActivityOnline++; else counters->number_of_LinphonePresenceActivityOffline++; } } void notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *lf, const char *uri_or_tel, const LinphonePresenceModel *presence) { stats *counters = get_stats(lc); ms_message("Presence notification for URI or phone number [%s]", uri_or_tel); counters->number_of_NotifyPresenceReceivedForUriOrTel++; } void _check_friend_result_list(LinphoneCore *lc, const bctbx_list_t *resultList, const unsigned int index, const char* uri, const char* phone) { if (index >= (unsigned int)bctbx_list_size(resultList)) { ms_error("Attempt to access result to an outbound index"); return; } const LinphoneSearchResult *sr = bctbx_list_nth_data(resultList, index); const LinphoneFriend *lf = linphone_search_result_get_friend(sr); if (lf || linphone_search_result_get_address(sr)) { const LinphoneAddress *la = (linphone_search_result_get_address(sr)) ? linphone_search_result_get_address(sr) : linphone_friend_get_address(lf); if (la) { char* fa = linphone_address_as_string_uri_only(la); BC_ASSERT_STRING_EQUAL(fa , uri); free(fa); return; } else if (phone) { const LinphonePresenceModel *presence = linphone_friend_get_presence_model_for_uri_or_tel(lf, phone); if (BC_ASSERT_PTR_NOT_NULL(presence)) { char *contact = linphone_presence_model_get_contact(presence); BC_ASSERT_STRING_EQUAL(contact, uri); free(contact); return; }
2311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
} } else { const bctbx_list_t *callLog = linphone_core_get_call_logs(lc); const bctbx_list_t *f; for (f = callLog ; f != NULL ; f = bctbx_list_next(f)) { LinphoneCallLog *log = (LinphoneCallLog*)(f->data); const LinphoneAddress *addr = (linphone_call_log_get_dir(log) == LinphoneCallIncoming) ? linphone_call_log_get_from_address(log) : linphone_call_log_get_to_address(log); if (addr) { char *addrUri = linphone_address_as_string_uri_only(addr); if (addrUri && strcmp(addrUri, uri) == 0) { bctbx_free(addrUri); return; } if (addrUri) bctbx_free(addrUri); } } } BC_ASSERT(FALSE); ms_error("Address NULL and Presence NULL"); } void linphone_transfer_state_changed(LinphoneCore *lc, LinphoneCall *transfered, LinphoneCallState new_call_state) { LinphoneCallLog *clog = linphone_call_get_call_log(transfered); char* to=linphone_address_as_string(linphone_call_log_get_to_address(clog)); char* from=linphone_address_as_string(linphone_call_log_get_from_address(clog)); stats* counters; ms_message("Transferred call from [%s] to [%s], new state is [%s]",from,to,linphone_call_state_to_string(new_call_state)); ms_free(to); ms_free(from); counters = get_stats(lc); switch (new_call_state) { case LinphoneCallOutgoingInit :counters->number_of_LinphoneTransferCallOutgoingInit++;break; case LinphoneCallOutgoingProgress :counters->number_of_LinphoneTransferCallOutgoingProgress++;break; case LinphoneCallOutgoingRinging :counters->number_of_LinphoneTransferCallOutgoingRinging++;break; case LinphoneCallOutgoingEarlyMedia :counters->number_of_LinphoneTransferCallOutgoingEarlyMedia++;break; case LinphoneCallConnected :counters->number_of_LinphoneTransferCallConnected++;break; case LinphoneCallStreamsRunning :counters->number_of_LinphoneTransferCallStreamsRunning++;break; case LinphoneCallError :counters->number_of_LinphoneTransferCallError++;break; default: BC_FAIL("unexpected event");break; } } void info_message_received(LinphoneCore *lc, LinphoneCall* call, const LinphoneInfoMessage *msg){ stats* counters = get_stats(lc); if (counters->last_received_info_message) { linphone_info_message_unref(counters->last_received_info_message); } counters->last_received_info_message=linphone_info_message_copy(msg); counters->number_of_inforeceived++; } void linphone_subscription_state_change(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { stats* counters = get_stats(lc); LinphoneCoreManager *mgr=get_manager(lc); LinphoneContent* content; const LinphoneAddress* from_addr = linphone_event_get_from(lev); char* from = linphone_address_as_string(from_addr); const LinphoneAddress* to_addr = linphone_event_get_to(lev); char* to = linphone_address_as_string(to_addr); content = linphone_core_create_content(lc); linphone_content_set_type(content,"application"); linphone_content_set_subtype(content,"somexml2"); linphone_content_set_buffer(content,(const uint8_t *)notify_content,strlen(notify_content)); ms_message("Subscription state [%s] from [%s] to [%s]",linphone_subscription_state_to_string(state),from,to); ms_free(from);
2381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450
ms_free(to); switch(state){ case LinphoneSubscriptionNone: break; case LinphoneSubscriptionIncomingReceived: counters->number_of_LinphoneSubscriptionIncomingReceived++; mgr->lev=lev; break; case LinphoneSubscriptionOutgoingProgress: counters->number_of_LinphoneSubscriptionOutgoingProgress++; break; case LinphoneSubscriptionPending: counters->number_of_LinphoneSubscriptionPending++; break; case LinphoneSubscriptionActive: counters->number_of_LinphoneSubscriptionActive++; if (linphone_event_get_subscription_dir(lev)==LinphoneSubscriptionIncoming){ mgr->lev=lev; if(strcmp(linphone_event_get_name(lev), "conference") == 0) { // TODO : Get LocalConfEventHandler and call handler->subscribeReceived(lev) } else { linphone_event_notify(lev,content); } } break; case LinphoneSubscriptionTerminated: counters->number_of_LinphoneSubscriptionTerminated++; if (lev == mgr->lev) { mgr->lev=NULL; } break; case LinphoneSubscriptionError: counters->number_of_LinphoneSubscriptionError++; if (lev == mgr->lev) { mgr->lev=NULL; } break; case LinphoneSubscriptionExpiring: counters->number_of_LinphoneSubscriptionExpiring++; if (lev == mgr->lev) { mgr->lev=NULL; } break; } linphone_content_unref(content); } void linphone_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content){ LinphoneCoreManager *mgr; const char * ua = linphone_event_get_custom_header(lev, "User-Agent"); if (!BC_ASSERT_PTR_NOT_NULL(content)) return; if (!linphone_content_is_multipart(content) && (!ua || !strstr(ua, "flexisip"))) { /*disable check for full presence server support*/ /*hack to disable content checking for list notify */ BC_ASSERT_STRING_EQUAL(linphone_content_get_utf8_text(content), notify_content); } mgr = get_manager(lc); mgr->stat.number_of_NotifyReceived++; } void linphone_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content) { LinphoneCoreManager *mgr = get_manager(lc); if (!mgr->decline_subscribe) linphone_event_accept_subscription(lev); else linphone_event_deny_subscription(lev, LinphoneReasonDeclined); } void linphone_publish_state_changed(LinphoneCore *lc, LinphoneEvent *ev, LinphonePublishState state) { stats* counters = get_stats(lc);
2451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
const LinphoneAddress* from_addr = linphone_event_get_from(ev); char* from = linphone_address_as_string(from_addr); ms_message("Publish state [%s] from [%s]",linphone_publish_state_to_string(state),from); ms_free(from); switch(state){ case LinphonePublishProgress: counters->number_of_LinphonePublishProgress++; break; case LinphonePublishOk: /*make sure custom header access API is working*/ BC_ASSERT_PTR_NOT_NULL(linphone_event_get_custom_header(ev,"From")); counters->number_of_LinphonePublishOk++; break; case LinphonePublishError: counters->number_of_LinphonePublishError++; break; case LinphonePublishExpiring: counters->number_of_LinphonePublishExpiring++; break; case LinphonePublishCleared: counters->number_of_LinphonePublishCleared++;break; default: break; } } void linphone_configuration_status(LinphoneCore *lc, LinphoneConfiguringState status, const char *message) { stats* counters; ms_message("Configuring state = %i with message %s", status, message?message:""); counters = get_stats(lc); if (status == LinphoneConfiguringSkipped) { counters->number_of_LinphoneConfiguringSkipped++; } else if (status == LinphoneConfiguringFailed) { counters->number_of_LinphoneConfiguringFailed++; } else if (status == LinphoneConfiguringSuccessful) { counters->number_of_LinphoneConfiguringSuccessful++; } } void linphone_call_encryption_changed(LinphoneCore *lc, LinphoneCall *call, bool_t on, const char *authentication_token) { LinphoneCallLog *calllog = linphone_call_get_call_log(call); char* to=linphone_address_as_string(linphone_call_log_get_to_address(calllog)); char* from=linphone_address_as_string(linphone_call_log_get_from_address(calllog)); stats* counters; ms_message(" %s call from [%s] to [%s], is now [%s]",linphone_call_log_get_dir(calllog)==LinphoneCallIncoming?"Incoming":"Outgoing" ,from ,to ,(on?"encrypted":"unencrypted")); ms_free(to); ms_free(from); counters = get_stats(lc); if (on) counters->number_of_LinphoneCallEncryptedOn++; else counters->number_of_LinphoneCallEncryptedOff++; } void dtmf_received(LinphoneCore *lc, LinphoneCall *call, int dtmf) { stats* counters = get_stats(lc); char** dst = &counters->dtmf_list_received; *dst = *dst ? ms_strcat_printf(*dst, "%c", dtmf) : ms_strdup_printf("%c", dtmf); counters->dtmf_count++; } bool_t rtcp_is_type(const mblk_t *m, rtcp_type_t type){ const rtcp_common_header_t *ch=rtcp_get_common_header(m); return (ch!=NULL && rtcp_common_header_get_packet_type(ch)==type); } void rtcp_received(stats* counters, mblk_t *packet) { do{ if (rtcp_is_type(packet, RTCP_RTPFB)){ if (rtcp_RTPFB_get_type(packet) == RTCP_RTPFB_TMMBR) { counters->number_of_tmmbr_received++; counters->last_tmmbr_value_received = (int)rtcp_RTPFB_tmmbr_get_max_bitrate(packet);
2521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590
} } }while (rtcp_next_packet(packet)); rtcp_rewind(packet); } void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallStats *lstats) { const int updated = _linphone_call_stats_get_updated(lstats); stats *counters = get_stats(lc); counters->number_of_LinphoneCallStatsUpdated++; if (updated & LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) { counters->number_of_rtcp_received++; if (_linphone_call_stats_rtcp_received_via_mux(lstats)){ counters->number_of_rtcp_received_via_mux++; } rtcp_received(counters, _linphone_call_stats_get_received_rtcp(lstats)); BC_ASSERT_TRUE(_linphone_call_stats_has_received_rtcp(lstats)); } if (updated & LINPHONE_CALL_STATS_SENT_RTCP_UPDATE ) { counters->number_of_rtcp_sent++; BC_ASSERT_TRUE(_linphone_call_stats_has_sent_rtcp(lstats)); } if (updated & LINPHONE_CALL_STATS_PERIODICAL_UPDATE ) { const int tab_size = sizeof counters->audio_download_bandwidth / sizeof(int); LinphoneCallStats *call_stats; int index; int type = linphone_call_stats_get_type(lstats); if (type != LINPHONE_CALL_STATS_AUDIO && type != LINPHONE_CALL_STATS_VIDEO) return; // Avoid out of bounds if type is TEXT. index = (counters->current_bandwidth_index[type]++) % tab_size; if (type == LINPHONE_CALL_STATS_AUDIO) { call_stats = linphone_call_get_audio_stats(call); counters->audio_download_bandwidth[index] = (int)linphone_call_stats_get_download_bandwidth(call_stats); counters->audio_upload_bandwidth[index] = (int)linphone_call_stats_get_upload_bandwidth(call_stats); } else { call_stats = linphone_call_get_video_stats(call); counters->video_download_bandwidth[index] = (int)linphone_call_stats_get_download_bandwidth(call_stats); counters->video_upload_bandwidth[index] = (int)linphone_call_stats_get_upload_bandwidth(call_stats); } linphone_call_stats_unref(call_stats); } } void liblinphone_tester_chat_message_msg_state_changed(LinphoneChatMessage *msg, LinphoneChatMessageState state) { LinphoneCore *lc = linphone_chat_message_get_core(msg); stats *counters = get_stats(lc); switch (state) { case LinphoneChatMessageStateIdle: return; case LinphoneChatMessageStateDelivered: counters->number_of_LinphoneMessageDelivered++; return; case LinphoneChatMessageStateNotDelivered: counters->number_of_LinphoneMessageNotDelivered++; return; case LinphoneChatMessageStateInProgress: counters->number_of_LinphoneMessageInProgress++; return; case LinphoneChatMessageStateFileTransferError: counters->number_of_LinphoneMessageNotDelivered++; counters->number_of_LinphoneMessageFileTransferError++; return; case LinphoneChatMessageStateFileTransferDone: counters->number_of_LinphoneMessageFileTransferDone++; return; case LinphoneChatMessageStateDeliveredToUser:
2591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660
counters->number_of_LinphoneMessageDeliveredToUser++; return; case LinphoneChatMessageStateDisplayed: counters->number_of_LinphoneMessageDisplayed++; return; case LinphoneChatMessageStateFileTransferInProgress: counters->number_of_LinphoneMessageFileTransferInProgress++; return; } ms_error("Unexpected state [%s] for msg [%p]",linphone_chat_message_state_to_string(state), msg); } void liblinphone_tester_chat_room_msg_sent(LinphoneCore *lc, LinphoneChatRoom *room, LinphoneChatMessage *msg) { stats *counters = get_stats(lc); counters->number_of_LinphoneMessageSent++; } void liblinphone_tester_x3dh_user_created(LinphoneCore *lc, const bool_t status, const char* userId, const char *info) { stats *counters = get_stats(lc); if (status == TRUE) { counters->number_of_X3dhUserCreationSuccess++; } else { counters->number_of_X3dhUserCreationFailure++; } } void liblinphone_tester_chat_message_ephemeral_timer_started (LinphoneChatMessage *msg) { LinphoneCore *lc = linphone_chat_message_get_core(msg); stats *counters = get_stats(lc); counters->number_of_LinphoneMessageEphemeralTimerStarted++; } void liblinphone_tester_chat_message_ephemeral_deleted (LinphoneChatMessage *msg) { LinphoneCore *lc = linphone_chat_message_get_core(msg); stats *counters = get_stats(lc); counters->number_of_LinphoneMessageEphemeralDeleted++; } /* * function called when the file transfer is initiated. file content should be feed into object LinphoneContent * */ LinphoneBuffer * tester_file_transfer_send(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t size){ LinphoneBuffer *lb; size_t file_size; size_t size_to_send; uint8_t *buf; FILE *file_to_send = linphone_content_get_user_data(content); // If a file path is set, we should NOT call the on_send callback ! BC_ASSERT_PTR_NULL(linphone_chat_message_get_file_transfer_filepath(msg)); BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int, "%d"); BC_ASSERT_PTR_NOT_NULL(file_to_send); if (file_to_send == NULL){ return NULL; } fseek(file_to_send, 0, SEEK_END); file_size = ftell(file_to_send); fseek(file_to_send, (long)offset, SEEK_SET); size_to_send = MIN(size, file_size - offset); buf = ms_malloc(size_to_send); if (fread(buf, sizeof(uint8_t), size_to_send, file_to_send) != size_to_send){ // reaching end of file, close it fclose(file_to_send); linphone_content_set_user_data(content, NULL); } lb = linphone_buffer_new_from_data(buf, size_to_send); ms_free(buf); return lb; }
2661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730
void tester_file_transfer_send_2(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t size, LinphoneBuffer *lb){ size_t file_size; size_t size_to_send; uint8_t *buf; FILE *file_to_send = linphone_content_get_user_data(content); // If a file path is set, we should NOT call the on_send callback ! BC_ASSERT_PTR_NULL(linphone_chat_message_get_file_transfer_filepath(msg)); BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int, "%d"); BC_ASSERT_PTR_NOT_NULL(file_to_send); if (file_to_send == NULL){ return; } fseek(file_to_send, 0, SEEK_END); file_size = ftell(file_to_send); fseek(file_to_send, (long)offset, SEEK_SET); size_to_send = MIN(size, file_size - offset); buf = ms_malloc(size_to_send); if (fread(buf, sizeof(uint8_t), size_to_send, file_to_send) != size_to_send){ // reaching end of file, close it fclose(file_to_send); linphone_content_set_user_data(content, NULL); } linphone_buffer_set_content(lb, buf, size_to_send); ms_free(buf); } /** * function invoked to report file transfer progress. * */ void file_transfer_progress_indication(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t total) { const LinphoneAddress *from_address = linphone_chat_message_get_from_address(msg); const LinphoneAddress *to_address = linphone_chat_message_get_to_address(msg); int progress = (int)((offset * 100)/total); LinphoneCore *lc = linphone_chat_message_get_core(msg); stats *counters = get_stats(lc); char *address = linphone_address_as_string(linphone_chat_message_is_outgoing(msg) ? to_address : from_address); if (progress == 0) { counters->number_of_LinphoneFileTransfer = 0; } counters->number_of_LinphoneFileTransfer++; BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int, "%d"); bctbx_message( "File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", progress, linphone_chat_message_is_outgoing(msg) ? "sent" : "received", linphone_content_get_type(content), linphone_content_get_subtype(content), linphone_chat_message_is_outgoing(msg) ? "to" : "from", address ); counters->progress_of_LinphoneFileTransfer = progress; if (progress == 100) { counters->number_of_LinphoneFileTransferDownloadSuccessful++; BC_ASSERT_LOWER(counters->number_of_LinphoneFileTransfer, 100, int, "%d"); } free(address); } void file_transfer_progress_indication_2(LinphoneChatMessage *msg, LinphoneContent* content, size_t offset, size_t total) { const LinphoneAddress *from_address = linphone_chat_message_get_from_address(msg); const LinphoneAddress *to_address = linphone_chat_message_get_to_address(msg); int progress = (int)((offset * 100)/total); LinphoneCore *lc = linphone_chat_message_get_core(msg); stats *counters = get_stats(lc); char *address = linphone_address_as_string(linphone_chat_message_is_outgoing(msg) ? to_address : from_address);
2731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800
BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int, "%d"); bctbx_message( "File transfer [%d%%] %s of type [%s/%s] %s [%s] \n", progress, linphone_chat_message_is_outgoing(msg) ? "sent" : "received", linphone_content_get_type(content), linphone_content_get_subtype(content), linphone_chat_message_is_outgoing(msg) ? "to" : "from", address ); counters->progress_of_LinphoneFileTransfer = progress; if (progress == 100) { counters->number_of_LinphoneFileTransferDownloadSuccessful++; } free(address); } /** * function invoked when a file transfer is received. * */ void file_transfer_received(LinphoneChatMessage *msg, LinphoneContent* content, const LinphoneBuffer *buffer){ FILE* file=NULL; BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int, "%d"); if (!linphone_content_get_user_data(content)) { // If a file path is set, we should NOT call the on_recv callback ! BC_ASSERT_PTR_NULL(linphone_chat_message_get_file_transfer_filepath(msg)); char receive_file_name[255]; char random_part[10]; belle_sip_random_token(random_part, sizeof(random_part)-1); snprintf(receive_file_name,sizeof(receive_file_name),"receive_file-%s.dump",random_part); char *receive_file = bc_tester_file(receive_file_name); /*first chunk, creating file*/ file = fopen(receive_file,"wb"); linphone_content_set_user_data(content,(void*)file); /*store fd for next chunks*/ linphone_chat_message_set_file_transfer_filepath(msg,receive_file); bc_free(receive_file); } file = (FILE*)linphone_content_get_user_data(content); BC_ASSERT_PTR_NOT_NULL(file); if (linphone_buffer_is_empty(buffer)) { /* tranfer complete */ struct stat st; linphone_content_set_user_data(content, NULL); fclose(file); BC_ASSERT_TRUE(stat(linphone_chat_message_get_file_transfer_filepath(msg), &st)==0); BC_ASSERT_EQUAL((int)linphone_content_get_file_size(content), (int)st.st_size, int, "%i"); } else { /* store content on a file*/ if (fwrite(linphone_buffer_get_content(buffer),linphone_buffer_get_size(buffer),1,file)==0){ ms_error("file_transfer_received(): write() failed: %s",strerror(errno)); } } } void global_state_changed(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) { stats *counters = get_stats(lc); switch (gstate) { case LinphoneGlobalOn: counters->number_of_LinphoneGlobalOn++; break; case LinphoneGlobalReady: counters->number_of_LinphoneGlobalReady++; break; case LinphoneGlobalOff: counters->number_of_LinphoneGlobalOff++; break;
2801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870
case LinphoneGlobalStartup: counters->number_of_LinphoneGlobalStartup++; break; case LinphoneGlobalShutdown: counters->number_of_LinphoneGlobalShutdown++; break; case LinphoneGlobalConfiguring: counters->number_of_LinphoneGlobalConfiguring++; break; } } void first_call_started(LinphoneCore *lc) { stats *counters = get_stats(lc); counters->number_of_LinphoneCoreFirstCallStarted++; } void last_call_ended(LinphoneCore *lc) { stats *counters = get_stats(lc); counters->number_of_LinphoneCoreLastCallEnded++; } void audio_device_changed(LinphoneCore *lc, LinphoneAudioDevice *device) { stats *counters = get_stats(lc); counters->number_of_LinphoneCoreAudioDeviceChanged++; } void audio_devices_list_updated(LinphoneCore *lc) { stats *counters = get_stats(lc); counters->number_of_LinphoneCoreAudioDevicesListUpdated++; } void setup_sdp_handling(const LinphoneCallTestParams* params, LinphoneCoreManager* mgr ){ if( params->sdp_removal ){ sal_default_set_sdp_handling(linphone_core_get_sal(mgr->lc), SalOpSDPSimulateRemove); } else if( params->sdp_simulate_error ){ sal_default_set_sdp_handling(linphone_core_get_sal(mgr->lc), SalOpSDPSimulateError); } } bool_t search_matching_srtp_suite(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr) { const MSCryptoSuite *callee_suites = linphone_core_get_srtp_crypto_suites_array(callee_mgr->lc); const MSCryptoSuite *caller_suites = linphone_core_get_srtp_crypto_suites_array(caller_mgr->lc); bool_t crypto_suite_found = FALSE; if (caller_suites && callee_suites) { for (size_t i = 0; (callee_suites != NULL) && (callee_suites[i] != MS_CRYPTO_SUITE_INVALID); i++) { for (size_t j = 0; (caller_suites != NULL) && (caller_suites[j] != MS_CRYPTO_SUITE_INVALID); j++) { crypto_suite_found |= (callee_suites[i] == caller_suites[j]); } } } return crypto_suite_found; } void check_stream_encryption(LinphoneCall * call) { const LinphoneCallParams* call_params = linphone_call_get_current_params(call); if (!linphone_call_params_rtp_bundle_enabled(call_params)) { const LinphoneMediaEncryption enc = linphone_call_params_get_media_encryption(call_params); MediaStream *astream = linphone_call_get_stream(call, LinphoneStreamTypeAudio); if (astream && audio_stream_started((AudioStream*)astream)) { if (enc == LinphoneMediaEncryptionNone) { BC_ASSERT_FALSE(media_stream_secured(astream)); } else if (enc == LinphoneMediaEncryptionSRTP) { BC_ASSERT_TRUE(media_stream_secured(astream) == is_srtp_secured(call, LinphoneStreamTypeAudio)); } else { BC_ASSERT_TRUE(media_stream_secured(astream)); } } #ifdef VIDEO_ENABLED MediaStream *vstream = linphone_call_get_stream(call, LinphoneStreamTypeVideo);
2871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940
if (vstream && video_stream_started((VideoStream *)vstream)) { if (enc == LinphoneMediaEncryptionNone) { BC_ASSERT_FALSE(media_stream_secured(vstream)); } else if (enc == LinphoneMediaEncryptionSRTP) { BC_ASSERT_TRUE(media_stream_secured(vstream) == is_srtp_secured(call, LinphoneStreamTypeVideo)); } else { BC_ASSERT_TRUE(media_stream_secured(vstream)); } } #endif } } /* * CAUTION this function is error prone. you should not use it anymore in new tests. * Creating callee call params before the call is actually received is not the good way * to use the Liblinphone API. Indeed, call params used for receiving calls shall be created by linphone_core_create_call_params() by passing * the call object for which params are to be created. * This function should be used only in test case where the programmer exactly knows the caller params, and then can deduce how * callee params will be set by linphone_core_create_call_params(). * This function was developped at a time where the use of the API about incoming params was not yet clarified. * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so * it is not a so good idea to build new tests based on this function. **/ bool_t call_with_params2(LinphoneCoreManager* caller_mgr ,LinphoneCoreManager* callee_mgr , const LinphoneCallTestParams *caller_test_params , const LinphoneCallTestParams *callee_test_params , bool_t build_callee_params) { int retry=0; stats initial_caller=caller_mgr->stat; stats initial_callee=callee_mgr->stat; bool_t result=FALSE; const LinphoneCallParams *caller_params = caller_test_params->base; const LinphoneCallParams *callee_params = callee_test_params->base; bool_t did_receive_call; LinphoneCall *callee_call=NULL; LinphoneCall *caller_call=NULL; /* TODO: This should be handled correctly inside the liblinphone library but meanwhile handle this here. */ linphone_core_manager_wait_for_stun_resolution(caller_mgr); linphone_core_manager_wait_for_stun_resolution(callee_mgr); setup_sdp_handling(caller_test_params, caller_mgr); setup_sdp_handling(callee_test_params, callee_mgr); if (!caller_params){ BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity))); }else{ BC_ASSERT_PTR_NOT_NULL((caller_call=linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params))); } BC_ASSERT_PTR_NULL(linphone_call_get_remote_params(caller_call)); /*assert that remote params are NULL when no response is received yet*/ //test ios simulator needs more time, 3s plus for connectng the network did_receive_call = wait_for_until(callee_mgr->lc ,caller_mgr->lc ,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived ,initial_callee.number_of_LinphoneCallIncomingReceived+1, 12000); BC_ASSERT_EQUAL(did_receive_call, !callee_test_params->sdp_simulate_error, int, "%d"); sal_default_set_sdp_handling(linphone_core_get_sal(caller_mgr->lc), SalOpSDPNormal); sal_default_set_sdp_handling(linphone_core_get_sal(caller_mgr->lc), SalOpSDPNormal); if (!did_receive_call) return 0; if (linphone_core_get_calls_nb(callee_mgr->lc)<=1) BC_ASSERT_TRUE(linphone_core_is_incoming_invite_pending(callee_mgr->lc)); BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress,initial_caller.number_of_LinphoneCallOutgoingProgress+1, int, "%d"); while (caller_mgr->stat.number_of_LinphoneCallOutgoingRinging!=(initial_caller.number_of_LinphoneCallOutgoingRinging + 1)
2941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010
&& caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia!=(initial_caller.number_of_LinphoneCallOutgoingEarlyMedia +1) && retry++ < 100) { linphone_core_iterate(caller_mgr->lc); linphone_core_iterate(callee_mgr->lc); ms_usleep(20000); } BC_ASSERT_TRUE((caller_mgr->stat.number_of_LinphoneCallOutgoingRinging==initial_caller.number_of_LinphoneCallOutgoingRinging+1) ||(caller_mgr->stat.number_of_LinphoneCallOutgoingEarlyMedia==initial_caller.number_of_LinphoneCallOutgoingEarlyMedia+1)); if (linphone_core_get_calls_nb(callee_mgr->lc) == 1) BC_ASSERT_PTR_NOT_NULL(linphone_core_get_current_call_remote_address(callee_mgr->lc)); /*only relevant if one call, otherwise, not always set*/ callee_call=linphone_core_get_call_by_remote_address2(callee_mgr->lc,caller_mgr->identity); if(!linphone_core_get_current_call(caller_mgr->lc) || (!callee_call && !linphone_core_get_current_call(callee_mgr->lc)) /*for privacy case*/) { return 0; } else if (caller_mgr->identity){ LinphoneAddress* callee_from=linphone_address_clone(caller_mgr->identity); linphone_address_set_port(callee_from,0); /*remove port because port is never present in from header*/ if (linphone_call_params_get_privacy(linphone_call_get_current_params(linphone_core_get_current_call(caller_mgr->lc))) == LinphonePrivacyNone) { /*don't check in case of p asserted id*/ if (!linphone_config_get_int(linphone_core_get_config(callee_mgr->lc),"sip","call_logs_use_asserted_id_instead_of_from",0)) { BC_ASSERT_PTR_NOT_NULL(callee_call); BC_ASSERT_TRUE(linphone_address_weak_equal(callee_from,linphone_call_get_remote_address(callee_call))); } } else { BC_ASSERT_FALSE(linphone_address_weak_equal(callee_from,linphone_call_get_remote_address(linphone_core_get_current_call(callee_mgr->lc)))); } linphone_address_unref(callee_from); } LinphoneCoreToneManagerStats *callee_stats = linphone_core_get_tone_manager_stats(callee_mgr->lc); if (callee_stats->number_of_startRingbackTone == callee_stats->number_of_stopRingbackTone) { BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(callee_mgr->lc)->number_of_startRingtone, callee_mgr->stat.number_of_LinphoneCallIncomingReceived, int, "%d"); } else { // in this case, the call is currently in RingbackTone so the Ringtone should not start BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(callee_mgr->lc)->number_of_startRingtone, callee_mgr->stat.number_of_LinphoneCallIncomingReceived-1, int, "%d"); } BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(caller_mgr->lc)->number_of_startRingbackTone, caller_mgr->stat.number_of_LinphoneCallOutgoingRinging, int, "%d"); // Local call parameters are available after moving to OutgoingRinging if (!caller_params && caller_call){ caller_params = linphone_call_get_params(caller_call); } bool_t caller_capability_negotiations_enabled = linphone_call_params_capability_negotiations_enabled(caller_params); bool_t caller_capability_negotiation_reinvite_enabled = linphone_call_params_is_capability_negotiation_reinvite_enabled(caller_params); const LinphoneMediaEncryption caller_local_enc = linphone_call_params_get_media_encryption(caller_params); const bool_t caller_mand_enc = linphone_call_params_mandatory_media_encryption_enabled (caller_params); bctbx_list_t* caller_supported_encs = linphone_call_params_get_supported_encryptions (caller_params); if (callee_params){ linphone_call_accept_with_params(callee_call,callee_params); }else if (build_callee_params){ LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,callee_call); ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(default_params)); linphone_call_accept_with_params(callee_call,default_params); linphone_call_params_unref(default_params); callee_params = linphone_call_get_params(callee_call); }else if (callee_call) { callee_params = linphone_call_get_params(callee_call); linphone_call_accept(callee_call); } else { LinphoneCall * callee_mgr_current_call = linphone_core_get_current_call(callee_mgr->lc); callee_params = linphone_call_get_params(callee_mgr_current_call); linphone_call_accept(callee_mgr_current_call); }
3011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080
bool_t callee_capability_negotiations_enabled = linphone_call_params_capability_negotiations_enabled(callee_params); bool_t callee_capability_negotiation_reinvite_enabled = linphone_call_params_is_capability_negotiation_reinvite_enabled(callee_params); const LinphoneMediaEncryption callee_local_enc = linphone_call_params_get_media_encryption(callee_params); const bool_t callee_mand_enc = linphone_call_params_mandatory_media_encryption_enabled (callee_params); LinphoneMediaEncryption matched_enc = LinphoneMediaEncryptionNone; if (caller_mand_enc) { matched_enc = caller_local_enc; } else if (callee_mand_enc) { matched_enc = callee_local_enc; } else if (caller_capability_negotiations_enabled && callee_capability_negotiations_enabled) { bool_t enc_check_result = FALSE; // Find first encryption listed in the list of supported encryptions of the caller that is supported by the callee for(bctbx_list_t * enc = caller_supported_encs;enc!=NULL;enc=enc->next){ matched_enc = (LinphoneMediaEncryption)((intptr_t)(bctbx_list_get_data(enc))); enc_check_result |= (linphone_call_params_is_media_encryption_supported (callee_params, matched_enc) || (callee_local_enc == matched_enc)); if (enc_check_result) { break; } } if (enc_check_result && (matched_enc == LinphoneMediaEncryptionSRTP)) { enc_check_result = search_matching_srtp_suite(caller_mgr, callee_mgr); } if (!enc_check_result) { if (caller_local_enc == callee_local_enc) { matched_enc = caller_local_enc; } else { BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallError,(initial_caller.number_of_LinphoneCallError+1))); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,(initial_caller.number_of_LinphoneCallReleased+1))); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,(initial_callee.number_of_LinphoneCallReleased+1))); return FALSE; } } } else { if ((callee_local_enc != LinphoneMediaEncryptionNone) || (caller_local_enc != LinphoneMediaEncryptionNone)) { if ((callee_local_enc == LinphoneMediaEncryptionZRTP) || (caller_local_enc == LinphoneMediaEncryptionZRTP)) { matched_enc = LinphoneMediaEncryptionZRTP; } else if ((callee_local_enc == LinphoneMediaEncryptionDTLS) || (caller_local_enc == LinphoneMediaEncryptionDTLS)) { matched_enc = LinphoneMediaEncryptionDTLS; } else { matched_enc = LinphoneMediaEncryptionSRTP; } } } if (caller_supported_encs) { bctbx_list_free(caller_supported_encs); } BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1)); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_caller.number_of_LinphoneCallConnected+1)); result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000) && wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(callee_mgr->lc)->number_of_stopRingtone, callee_mgr->stat.number_of_LinphoneCallIncomingReceived, int, "%d"); BC_ASSERT_EQUAL(linphone_core_get_tone_manager_stats(caller_mgr->lc)->number_of_stopRingbackTone, caller_mgr->stat.number_of_LinphoneCallOutgoingRinging, int, "%d"); if (result != 0) { if ((matched_enc == LinphoneMediaEncryptionDTLS) || (matched_enc == LinphoneMediaEncryptionZRTP)) { BC_ASSERT_TRUE(wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_caller.number_of_LinphoneCallEncryptedOn+1,10000)); BC_ASSERT_TRUE(wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEncryptedOn,initial_callee.number_of_LinphoneCallEncryptedOn+1,10000)); } caller_call = linphone_core_get_current_call(caller_mgr->lc); BC_ASSERT_PTR_NOT_NULL(caller_call); const LinphoneCallParams* caller_call_param = linphone_call_get_current_params(caller_call); const LinphoneMediaEncryption caller_enc = linphone_call_params_get_media_encryption(caller_call_param); callee_call = linphone_core_get_current_call(callee_mgr->lc);
3081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150
BC_ASSERT_PTR_NOT_NULL(callee_call); const LinphoneCallParams* callee_call_param = linphone_call_get_current_params(callee_call); const LinphoneMediaEncryption callee_enc = linphone_call_params_get_media_encryption(callee_call_param); // Ensure that encryption on both sides is the same BC_ASSERT_EQUAL(caller_enc,matched_enc, int, "%d"); BC_ASSERT_EQUAL(callee_enc,matched_enc, int, "%d"); BC_ASSERT_EQUAL(caller_enc,callee_enc, int, "%d"); if (matched_enc == LinphoneMediaEncryptionZRTP) { const char * callee_token = linphone_call_get_authentication_token(callee_call); const char * caller_token = linphone_call_get_authentication_token(caller_call); BC_ASSERT_PTR_NOT_NULL(callee_token); BC_ASSERT_PTR_NOT_NULL(caller_token); if (caller_token && callee_token){ BC_ASSERT_STRING_EQUAL(callee_token, caller_token); BC_ASSERT_TRUE(strlen(callee_token)>0); BC_ASSERT_TRUE(strlen(caller_token)>0); } } const bool_t calleeSendIceReInvite = linphone_config_get_int(linphone_core_get_config(callee_mgr->lc), "sip", "update_call_when_ice_completed", TRUE); const bool_t callerSendIceReInvite = linphone_config_get_int(linphone_core_get_config(caller_mgr->lc), "sip", "update_call_when_ice_completed", TRUE); const bool_t calleeSendIceReInviteWithDtls = linphone_config_get_int(linphone_core_get_config(callee_mgr->lc), "sip", "update_call_when_ice_completed_with_dtls", FALSE); const bool_t callerSendIceReInviteWithDtls = linphone_config_get_int(linphone_core_get_config(caller_mgr->lc), "sip", "update_call_when_ice_completed_with_dtls", FALSE); LinphoneNatPolicy * caller_policy = linphone_core_get_nat_policy(caller_mgr->lc); LinphoneNatPolicy * callee_policy = linphone_core_get_nat_policy(callee_mgr->lc); bool_t capability_negotiation_reinvite_enabled = linphone_core_sdp_200_ack_enabled(caller_mgr->lc) ? callee_capability_negotiation_reinvite_enabled : caller_capability_negotiation_reinvite_enabled; /*wait ice and/or capability negotiation re-invite*/ // If caller sets mandatory encryption, potential configurations are not added to the SDP as there is no choice to be made if (!caller_mand_enc && caller_capability_negotiations_enabled && callee_capability_negotiations_enabled && (caller_local_enc != caller_enc) && capability_negotiation_reinvite_enabled) { // Capability negotiation re-invite BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+2)); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+2)); } else if (linphone_nat_policy_ice_enabled(caller_policy) && linphone_nat_policy_ice_enabled(callee_policy) && calleeSendIceReInvite && callerSendIceReInvite && ((caller_enc != LinphoneMediaEncryptionDTLS) || (calleeSendIceReInviteWithDtls && callerSendIceReInviteWithDtls))) { BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+2)); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+2)); } else if (linphone_nat_policy_ice_enabled(caller_policy)) { /* check no ice re-invite received*/ BC_ASSERT_FALSE(wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+2,2000)); BC_ASSERT_FALSE(wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+2,2000)); } check_stream_encryption(caller_call); check_stream_encryption(callee_call); if (caller_enc == LinphoneMediaEncryptionDTLS ) { LinphoneCall *call = linphone_core_get_current_call(caller_mgr->lc); if(!BC_ASSERT_PTR_NOT_NULL(call)) return FALSE; AudioStream *astream = (AudioStream *)linphone_call_get_stream(call, LinphoneStreamTypeAudio); #ifdef VIDEO_ENABLED VideoStream *vstream = (VideoStream *)linphone_call_get_stream(call, LinphoneStreamTypeVideo); #endif if (astream) BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&astream->ms.sessions)); #ifdef VIDEO_ENABLED if (vstream && video_stream_started(vstream)) BC_ASSERT_TRUE(ms_media_stream_sessions_get_encryption_mandatory(&vstream->ms.sessions)); #endif } } return result;
3151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220
} /* * CAUTION this function is error prone. you should not use it anymore in new tests. * Creating callee call params before the call is actually received is not the good way * to use the Liblinphone API. Indeed, call params used for receiving calls shall be created by linphone_core_create_call_params() by passing * the call object for which params are to be created. * This function should be used only in test case where the programmer exactly knows the caller params, and then can deduce how * callee params will be set by linphone_core_create_call_params(). * This function was developped at a time where the use of the API about incoming params was not yet clarified. * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so * it is not a so good idea to build new tests based on this function. **/ bool_t call_with_params(LinphoneCoreManager* caller_mgr ,LinphoneCoreManager* callee_mgr ,const LinphoneCallParams *caller_params ,const LinphoneCallParams *callee_params){ LinphoneCallTestParams caller_test_params = {0}, callee_test_params = {0}; caller_test_params.base = (LinphoneCallParams*)caller_params; callee_test_params.base = (LinphoneCallParams*)callee_params; return call_with_params2(caller_mgr,callee_mgr,&caller_test_params,&callee_test_params,FALSE); } /* * CAUTION this function is error prone. you should not use it anymore in new tests. * Creating callee call params before the call is actually received is not the good way * to use the Liblinphone API. Indeed, call params used for receiving calls shall be created by linphone_core_create_call_params() by passing * the call object for which params are to be created. * This function should be used only in test case where the programmer exactly knows the caller params, and then can deduce how * callee params will be set by linphone_core_create_call_params(). * This function was developped at a time where the use of the API about incoming params was not yet clarified. * Tests relying on this function are then not testing the correct way to use the api (through linphone_core_create_call_params()), and so * it is not a so good idea to build new tests based on this function. **/ bool_t call_with_test_params(LinphoneCoreManager* caller_mgr ,LinphoneCoreManager* callee_mgr ,const LinphoneCallTestParams *caller_test_params ,const LinphoneCallTestParams *callee_test_params){ return call_with_params2(caller_mgr,callee_mgr,caller_test_params,callee_test_params,FALSE); } bool_t call_with_caller_params(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr, const LinphoneCallParams *params) { return call_with_params(caller_mgr,callee_mgr,params,NULL); } bool_t call(LinphoneCoreManager* caller_mgr,LinphoneCoreManager* callee_mgr){ return call_with_params(caller_mgr,callee_mgr,NULL,NULL); } void end_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){ int previous_count_1 = m1->stat.number_of_LinphoneCallEnd; int previous_count_2 = m2->stat.number_of_LinphoneCallEnd; linphone_core_terminate_all_calls(m1->lc); BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallEnd,previous_count_1+1)); BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallEnd,previous_count_2+1)); BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m1->stat.number_of_LinphoneCallReleased,previous_count_1+1)); BC_ASSERT_TRUE(wait_for(m1->lc,m2->lc,&m2->stat.number_of_LinphoneCallReleased,previous_count_2+1)); } static void linphone_conference_server_call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *msg) { LinphoneCoreCbs *cbs = linphone_core_get_current_callbacks(lc); LinphoneConferenceServer *conf_srv = (LinphoneConferenceServer *)linphone_core_cbs_get_user_data(cbs); switch(cstate) { case LinphoneCallIncomingReceived: linphone_call_accept(call); break; case LinphoneCallStreamsRunning: if(linphone_call_get_conference(call) == NULL) {
3221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290
linphone_core_add_to_conference(lc, call); linphone_core_leave_conference(lc); if(conf_srv->first_call == NULL) conf_srv->first_call = call; } break; case LinphoneCallEnd: if(call == conf_srv->first_call) { if(linphone_core_get_conference(lc)) { linphone_core_terminate_conference(lc); } conf_srv->first_call = NULL; } break; default: break; } } static void linphone_conference_server_refer_received(LinphoneCore *core, const char *refer_to) { char method[20]; LinphoneAddress *refer_to_addr = linphone_address_new(refer_to); char *uri; LinphoneCall *call; if(refer_to_addr == NULL) return; strncpy(method, linphone_address_get_method_param(refer_to_addr), sizeof(method)); method[sizeof(method) - 1] = '\0'; if(strcmp(method, "BYE") == 0) { linphone_address_clean(refer_to_addr); uri = linphone_address_as_string_uri_only(refer_to_addr); call = linphone_core_find_call_from_uri(core, uri); if(call) linphone_call_terminate(call); ms_free(uri); } linphone_address_unref(refer_to_addr); } static void linphone_conference_server_registration_state_changed( LinphoneCore *core, LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const char *message ) { LinphoneCoreCbs *cbs = linphone_core_get_current_callbacks(core); LinphoneConferenceServer *m = (LinphoneConferenceServer *)linphone_core_cbs_get_user_data(cbs); if(cfg == linphone_core_get_default_proxy_config(core)) { m->reg_state = cstate; } } static void linphone_subscribe_received_internal(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content) { int *subscription_received = (int*)(((LinphoneCoreManager *)linphone_core_get_user_data(lc))->user_info); *subscription_received += 1; } static void linphone_notify_received_internal(LinphoneCore *lc, LinphoneEvent *lev, const char *eventname, const LinphoneContent *content){ LinphoneCoreManager *mgr = get_manager(lc); mgr->stat.number_of_NotifyReceived++; } LinphoneConferenceServer* linphone_conference_server_new(const char *rc_file, bool_t do_registration) { LinphoneConferenceServer *conf_srv = (LinphoneConferenceServer *)ms_new0(LinphoneConferenceServer, 1); LinphoneCoreManager *lm = (LinphoneCoreManager *)conf_srv; LinphoneProxyConfig *proxy; conf_srv->cbs = linphone_factory_create_core_cbs(linphone_factory_get()); linphone_core_cbs_set_subscription_state_changed(conf_srv->cbs, linphone_subscription_state_change); linphone_core_cbs_set_subscribe_received(conf_srv->cbs, linphone_subscribe_received_internal); linphone_core_cbs_set_notify_received(conf_srv->cbs, linphone_notify_received_internal); linphone_core_cbs_set_call_state_changed(conf_srv->cbs, linphone_conference_server_call_state_changed);
3291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360
linphone_core_cbs_set_refer_received(conf_srv->cbs, linphone_conference_server_refer_received); linphone_core_cbs_set_registration_state_changed(conf_srv->cbs, linphone_conference_server_registration_state_changed); linphone_core_cbs_set_user_data(conf_srv->cbs, conf_srv); conf_srv->reg_state = LinphoneRegistrationNone; linphone_core_manager_init(lm, rc_file,NULL); if (!do_registration) { proxy = linphone_core_get_default_proxy_config(lm->lc); linphone_proxy_config_edit(proxy); linphone_proxy_config_enable_register(proxy,FALSE); linphone_proxy_config_done(proxy); } linphone_core_add_callbacks(lm->lc, conf_srv->cbs); linphone_core_manager_start(lm, do_registration); return conf_srv; } static void configure_core_for_conference_callbacks(LinphoneCoreManager *lcm, LinphoneCoreCbs *cbs) { _linphone_core_add_callbacks(lcm->lc, cbs, TRUE); linphone_core_set_user_data(lcm->lc, lcm); } void setup_mgr_for_conference(LinphoneCoreManager *mgr) { LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); // Add subscribe and notify received here as when a participant is added, we must wait for its notify is the call goes to StreamRunning linphone_core_cbs_set_subscription_state_changed(cbs, linphone_subscription_state_change); linphone_core_cbs_set_subscribe_received(cbs, linphone_subscribe_received_internal); linphone_core_cbs_set_notify_received(cbs, linphone_notify_received_internal); configure_core_for_conference_callbacks(mgr, cbs); linphone_core_cbs_unref(cbs); linphone_core_set_user_data(mgr->lc, mgr); int* subscription_received = (int *)ms_new0(int, 1); *subscription_received = 0; mgr->user_info = subscription_received; } LinphoneCoreManager *create_mgr_for_conference(const char * rc_file, bool_t check_for_proxies) { LinphoneCoreManager *mgr = linphone_core_manager_new_with_proxies_check(rc_file, check_for_proxies); setup_mgr_for_conference(mgr); return mgr; } void linphone_conference_server_destroy(LinphoneConferenceServer *conf_srv) { linphone_core_cbs_unref(conf_srv->cbs); linphone_core_manager_destroy((LinphoneCoreManager *)conf_srv); } const char *liblinphone_tester_get_empty_rc(void){ if (liblinphone_tester_empty_rc_path == NULL){ liblinphone_tester_empty_rc_path = bc_tester_res("rcfiles/empty_rc"); } return liblinphone_tester_empty_rc_path; } /* * Copy file "from" to file "to". * Destination file is truncated if existing. * Return 0 on success, positive value on error. */ int liblinphone_tester_copy_file(const char *from, const char *to) { FILE *in, *out; char buf[256]; size_t n;
3361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430
/* Open "from" file for reading */ in=fopen(from, "rb"); if ( in == NULL ) { ms_error("Can't open %s for reading: %s\n",from,strerror(errno)); return 1; } /* Open "to" file for writing (will truncate existing files) */ out=fopen(to, "wb"); if ( out == NULL ) { ms_error("Can't open %s for writing: %s\n",to,strerror(errno)); fclose(in); return 2; } /* Copy data from "in" to "out" */ while ( (n=fread(buf, sizeof(char), sizeof(buf), in)) > 0 ) { if ( ! fwrite(buf, 1, n, out) ) { ms_error("Could not write in %s: %s\n",to,strerror(errno)); fclose(in); fclose(out); return 3; } } fclose(in); fclose(out); return 0; } /* * Read a file and set its content in a buffer * caller must then free the buffer * return size read */ size_t liblinphone_tester_load_text_file_in_buffer(const char *filePath, char **buffer) { FILE *fp = fopen(filePath, "r"); if ( fp == NULL ) { ms_error("Can't open %s for reading: %s\n",filePath,strerror(errno)); return 0; } /* get the size to read */ if (fseek(fp, 0L, SEEK_END) == 0) { long bufsize = ftell(fp); *buffer = bctbx_malloc(sizeof(char) * (bufsize + 1)); // +1 to add a '\0' /* rewind */ fseek(fp, 0L, SEEK_SET); /* read */ size_t readSize = fread(*buffer, sizeof(char), bufsize, fp); if ( ferror( fp ) != 0 ) { bctbx_free(*buffer); fclose(fp); return 0; } else { (*buffer)[readSize++] = '\0'; fclose(fp); return readSize; } } fclose(fp); return 0; }
3431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500
static const int flowControlIntervalMs = 5000; static const int flowControlThresholdMs = 40; static int dummy_set_sample_rate(MSFilter *obj, void *data) { return 0; } static int dummy_get_sample_rate(MSFilter *obj, void *data) { int *n = (int*)data; *n = 44100; return 0; } static int dummy_set_nchannels(MSFilter *obj, void *data) { return 0; } static int dummy_get_nchannels(MSFilter *obj, void *data) { int *n = (int*)data; *n = 1; return 0; } static MSFilterMethod dummy_snd_card_methods[] = { {MS_FILTER_SET_SAMPLE_RATE, dummy_set_sample_rate}, {MS_FILTER_GET_SAMPLE_RATE, dummy_get_sample_rate}, {MS_FILTER_SET_NCHANNELS, dummy_set_nchannels}, {MS_FILTER_GET_NCHANNELS, dummy_get_nchannels}, {0,NULL} }; struct _DummyOutputContext { MSFlowControlledBufferizer buffer; int samplerate; int nchannels; ms_mutex_t mutex; }; typedef struct _DummyOutputContext DummyOutputContext; static void dummy_snd_write_init(MSFilter *obj){ DummyOutputContext *octx = (DummyOutputContext *)ms_new0(DummyOutputContext, 1); octx->samplerate = 44100; ms_flow_controlled_bufferizer_init(&octx->buffer, obj, octx->samplerate, 1); ms_mutex_init(&octx->mutex,NULL); octx->nchannels = 1; obj->data = octx; } static void dummy_snd_write_uninit(MSFilter *obj){ DummyOutputContext *octx = (DummyOutputContext*)obj->data; ms_flow_controlled_bufferizer_uninit(&octx->buffer); ms_mutex_destroy(&octx->mutex); free(octx); } static void dummy_snd_write_process(MSFilter *obj) { DummyOutputContext *octx = (DummyOutputContext*) obj->data; ms_mutex_lock(&octx->mutex); // Retrieve data and put them in the filter bugffer ready to be played ms_flow_controlled_bufferizer_put_from_queue(&octx->buffer, obj->inputs[0]); ms_mutex_unlock(&octx->mutex); } MSFilterDesc dummy_filter_write_desc = {
3501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570
MS_FILTER_PLUGIN_ID, "DummyPlayer", "dummy player", MS_FILTER_OTHER, NULL, 1, 0, dummy_snd_write_init, NULL, dummy_snd_write_process, NULL, dummy_snd_write_uninit, dummy_snd_card_methods }; static MSFilter *dummy_snd_card_create_writer(MSSndCard *card) { MSFilter *f = ms_factory_create_filter_from_desc(ms_snd_card_get_factory(card), &dummy_filter_write_desc); DummyOutputContext *octx = (DummyOutputContext*)(f->data); ms_flow_controlled_bufferizer_set_samplerate(&octx->buffer, octx->samplerate); ms_flow_controlled_bufferizer_set_nchannels(&octx->buffer, octx->nchannels); ms_flow_controlled_bufferizer_set_max_size_ms(&octx->buffer, flowControlThresholdMs); ms_flow_controlled_bufferizer_set_flow_control_interval_ms(&octx->buffer, flowControlIntervalMs); return f; } struct _DummyInputContext { queue_t q; MSFlowControlledBufferizer buffer; int samplerate; int nchannels; ms_mutex_t mutex; }; typedef struct _DummyInputContext DummyInputContext; static void dummy_snd_read_init(MSFilter *obj){ DummyInputContext *ictx = (DummyInputContext *)ms_new0(DummyInputContext, 1); ictx->samplerate = 44100; ms_flow_controlled_bufferizer_init(&ictx->buffer, obj, ictx->samplerate, 1); ms_mutex_init(&ictx->mutex,NULL); qinit(&ictx->q); ictx->nchannels = 1; obj->data = ictx; } static void dummy_snd_read_uninit(MSFilter *obj){ DummyInputContext *ictx = (DummyInputContext*)obj->data; flushq(&ictx->q,0); ms_flow_controlled_bufferizer_uninit(&ictx->buffer); ms_mutex_destroy(&ictx->mutex); free(ictx); } static void dummy_snd_read_process(MSFilter *obj) { DummyInputContext *ictx = (DummyInputContext*) obj->data; mblk_t *m; ms_mutex_lock(&ictx->mutex); // Retrieve data and put them in the filter output queue while ((m = getq(&ictx->q)) != NULL) { ms_queue_put(obj->outputs[0], m); } ms_mutex_unlock(&ictx->mutex); }
3571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640
MSFilterDesc dummy_filter_read_desc = { MS_FILTER_PLUGIN_ID, "DummyRecorder", "dummy recorder", MS_FILTER_OTHER, NULL, 0, 1, dummy_snd_read_init, NULL, dummy_snd_read_process, NULL, dummy_snd_read_uninit, dummy_snd_card_methods }; static MSFilter *dummy_snd_card_create_reader(MSSndCard *card) { MSFilter *f = ms_factory_create_filter_from_desc(ms_snd_card_get_factory(card), &dummy_filter_read_desc); DummyInputContext *ictx = (DummyInputContext*)(f->data); ms_flow_controlled_bufferizer_set_samplerate(&ictx->buffer, ictx->samplerate); ms_flow_controlled_bufferizer_set_nchannels(&ictx->buffer, ictx->nchannels); ms_flow_controlled_bufferizer_set_max_size_ms(&ictx->buffer, flowControlThresholdMs); ms_flow_controlled_bufferizer_set_flow_control_interval_ms(&ictx->buffer, flowControlIntervalMs); return f; } static void dummy_test_snd_card_detect(MSSndCardManager *m); MSSndCardDesc dummy_test_snd_card_desc = { "dummyTest", dummy_test_snd_card_detect, NULL, NULL, NULL, NULL, NULL, NULL, dummy_snd_card_create_reader, dummy_snd_card_create_writer, NULL }; static MSSndCard* create_dummy_test_snd_card(void) { MSSndCard* sndcard; sndcard = ms_snd_card_new(&dummy_test_snd_card_desc); sndcard->data = NULL; sndcard->name = ms_strdup(DUMMY_TEST_SOUNDCARD); sndcard->capabilities = MS_SND_CARD_CAP_PLAYBACK | MS_SND_CARD_CAP_CAPTURE; sndcard->latency = 0; sndcard->device_type = MS_SND_CARD_DEVICE_TYPE_BLUETOOTH; return sndcard; } static void dummy_test_snd_card_detect(MSSndCardManager *m) { ms_snd_card_manager_prepend_card(m, create_dummy_test_snd_card()); } static void dummy2_test_snd_card_detect(MSSndCardManager *m); MSSndCardDesc dummy2_test_snd_card_desc = { "dummyTest2", dummy2_test_snd_card_detect, NULL, NULL, NULL, NULL, NULL,
3641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710
NULL, dummy_snd_card_create_reader, dummy_snd_card_create_writer, NULL }; static MSSndCard* create_dummy2_test_snd_card(void) { MSSndCard* sndcard; sndcard = ms_snd_card_new(&dummy2_test_snd_card_desc); sndcard->data = NULL; sndcard->name = ms_strdup(DUMMY2_TEST_SOUNDCARD); sndcard->capabilities = MS_SND_CARD_CAP_PLAYBACK | MS_SND_CARD_CAP_CAPTURE; sndcard->latency = 0; sndcard->device_type = MS_SND_CARD_DEVICE_TYPE_BLUETOOTH; return sndcard; } static void dummy2_test_snd_card_detect(MSSndCardManager *m) { ms_snd_card_manager_prepend_card(m, create_dummy2_test_snd_card()); } static void dummy3_test_snd_card_detect(MSSndCardManager *m); MSSndCardDesc dummy3_test_snd_card_desc = { "dummyTest3", dummy3_test_snd_card_detect, NULL, NULL, NULL, NULL, NULL, NULL, dummy_snd_card_create_reader, dummy_snd_card_create_writer, NULL }; static MSSndCard* create_dummy3_test_snd_card(void) { MSSndCard* sndcard; sndcard = ms_snd_card_new(&dummy3_test_snd_card_desc); sndcard->data = NULL; sndcard->name = ms_strdup(DUMMY3_TEST_SOUNDCARD); sndcard->capabilities = MS_SND_CARD_CAP_PLAYBACK | MS_SND_CARD_CAP_CAPTURE; sndcard->latency = 0; sndcard->device_type = MS_SND_CARD_DEVICE_TYPE_BLUETOOTH; return sndcard; } static void dummy3_test_snd_card_detect(MSSndCardManager *m) { ms_snd_card_manager_prepend_card(m, create_dummy3_test_snd_card()); } static void dummy_playback_test_snd_card_detect(MSSndCardManager *m); MSSndCardDesc dummy_playback_test_snd_card_desc = { "dummyPlaybackTest", dummy_playback_test_snd_card_detect, NULL, NULL, NULL, NULL, NULL, NULL, dummy_snd_card_create_reader, dummy_snd_card_create_writer, NULL }; static MSSndCard* create_dummy_playback_test_snd_card(void) { MSSndCard* sndcard;
3711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780
sndcard = ms_snd_card_new(&dummy_playback_test_snd_card_desc); sndcard->data = NULL; sndcard->name = ms_strdup(DUMMY_PLAYBACK_TEST_SOUNDCARD); sndcard->capabilities = MS_SND_CARD_CAP_PLAYBACK; sndcard->latency = 0; sndcard->device_type = MS_SND_CARD_DEVICE_TYPE_BLUETOOTH; return sndcard; } static void dummy_playback_test_snd_card_detect(MSSndCardManager *m) { ms_snd_card_manager_prepend_card(m, create_dummy_playback_test_snd_card()); } static void dummy_capture_test_snd_card_detect(MSSndCardManager *m); MSSndCardDesc dummy_capture_test_snd_card_desc = { "dummyCaptureTest", dummy_capture_test_snd_card_detect, NULL, NULL, NULL, NULL, NULL, NULL, dummy_snd_card_create_reader, dummy_snd_card_create_writer, NULL }; static MSSndCard* create_dummy_capture_test_snd_card(void) { MSSndCard* sndcard; sndcard = ms_snd_card_new(&dummy_capture_test_snd_card_desc); sndcard->data = NULL; sndcard->name = ms_strdup(DUMMY_CAPTURE_TEST_SOUNDCARD); sndcard->capabilities = MS_SND_CARD_CAP_CAPTURE; sndcard->latency = 0; sndcard->device_type = MS_SND_CARD_DEVICE_TYPE_BLUETOOTH; return sndcard; } static void dummy_capture_test_snd_card_detect(MSSndCardManager *m) { ms_snd_card_manager_prepend_card(m, create_dummy_capture_test_snd_card()); } void set_lime_curve_tls(const int curveId, LinphoneCoreManager *manager, bool_t tls_auth_server, bool_t req) { if (curveId == 448) { // Change the curve setting before the server URL linphone_config_set_string(linphone_core_get_config(manager->lc),"lime","curve","c448"); // changing the url will restart the encryption engine allowing to also use the changed curve config if (tls_auth_server == TRUE) { if (req==TRUE) { linphone_core_set_lime_x3dh_server_url(manager->lc, lime_server_c448_tlsauth_req_url); } else { linphone_core_set_lime_x3dh_server_url(manager->lc, lime_server_c448_tlsauth_opt_url); } } else { linphone_core_set_lime_x3dh_server_url(manager->lc, lime_server_c448_url); } } else { // Change the curve setting before the server URL linphone_config_set_string(linphone_core_get_config(manager->lc),"lime","curve","c25519"); // changing the url will restart the encryption engine allowing to also use the changed curve config if (tls_auth_server == TRUE) { if (req == TRUE) { linphone_core_set_lime_x3dh_server_url(manager->lc, lime_server_c25519_tlsauth_req_url); } else { linphone_core_set_lime_x3dh_server_url(manager->lc, lime_server_c25519_tlsauth_opt_url); } } else { linphone_core_set_lime_x3dh_server_url(manager->lc, lime_server_c25519_url);
37813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833
} } } void set_lime_curve(const int curveId, LinphoneCoreManager *manager) { set_lime_curve_tls(curveId, manager, FALSE, FALSE); } void set_lime_curve_list_tls(const int curveId, bctbx_list_t *managerList, bool_t tls_auth_server, bool_t req) { bctbx_list_t *item = managerList; for (item = managerList; item; item = bctbx_list_next(item)) { set_lime_curve_tls(curveId, (LinphoneCoreManager *)(bctbx_list_get_data(item)), tls_auth_server, req); } } void set_lime_curve_list(const int curveId, bctbx_list_t *managerList) { set_lime_curve_list_tls (curveId, managerList, FALSE, FALSE); } void enable_stun_in_core(LinphoneCoreManager * mgr, const bool_t enable_ice) { LinphoneCore * lc = mgr->lc; LinphoneNatPolicy *nat_policy = linphone_core_get_nat_policy(lc); char *stun_server = NULL; char *stun_server_username = NULL; if (nat_policy != NULL) { nat_policy = linphone_nat_policy_ref(nat_policy); stun_server = ms_strdup(linphone_nat_policy_get_stun_server(nat_policy)); stun_server_username = ms_strdup(linphone_nat_policy_get_stun_server_username(nat_policy)); linphone_nat_policy_clear(nat_policy); } else { nat_policy = linphone_core_create_nat_policy(lc); stun_server = ms_strdup(linphone_core_get_stun_server(lc)); } linphone_nat_policy_enable_stun(nat_policy, TRUE); if (enable_ice) { linphone_nat_policy_enable_ice(nat_policy, TRUE); } if (stun_server_username != NULL) { linphone_nat_policy_set_stun_server_username(nat_policy, stun_server_username); ms_free(stun_server_username); } if (stun_server != NULL) { linphone_nat_policy_set_stun_server(nat_policy, stun_server); ms_free(stun_server); } linphone_core_set_nat_policy(lc, nat_policy); linphone_nat_policy_unref(nat_policy); }