-
Sylvain Berfini authored0c593598
/*
* Copyright (c) 2010-2022 Belledonne Communications SARL.
*
* This file is part of Liblinphone
* (see https://gitlab.linphone.org/BC/public/liblinphone).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "bctoolbox/crypto.h"
#include <bctoolbox/defs.h>
#include "liblinphone_tester.h"
#include "linphone/api/c-chat-room-params.h"
#include "linphone/api/c-types.h"
#include "linphone/core.h"
#include "linphone/wrapper_utils.h"
#include "tester_utils.h"
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
#pragma GCC diagnostic push
#endif
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#endif
const char *sFactoryUri = "sip:conference-factory@conf.example.org";
static bool_t wait_for_chat_room_participants(bctbx_list_t *lcs, LinphoneChatRoom *chat, int value, int timeout_ms) {
bctbx_list_t *iterator;
MSTimeSpec start;
liblinphone_tester_clock_start(&start);
while ((linphone_chat_room_get_nb_participants(chat) < 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 (linphone_chat_room_get_nb_participants(chat) < value) return FALSE;
else return TRUE;
}
void chat_room_session_state_changed(LinphoneChatRoom *cr, LinphoneCallState cstate, BCTBX_UNUSED(const char *msg)) {
LinphoneCore *lc = linphone_chat_room_get_core(cr);
stats *counters = get_stats(lc);
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
switch (cstate) {
case LinphoneCallIncomingReceived:
counters->number_of_LinphoneChatRoomSessionIncomingReceived++;
break;
case LinphoneCallPushIncomingReceived:
counters->number_of_LinphoneChatRoomSessionPushIncomingReceived++;
break;
case LinphoneCallOutgoingInit:
counters->number_of_LinphoneChatRoomSessionOutgoingInit++;
break;
case LinphoneCallOutgoingProgress:
counters->number_of_LinphoneChatRoomSessionOutgoingProgress++;
break;
case LinphoneCallOutgoingRinging:
counters->number_of_LinphoneChatRoomSessionOutgoingRinging++;
break;
case LinphoneCallOutgoingEarlyMedia:
counters->number_of_LinphoneChatRoomSessionOutgoingEarlyMedia++;
break;
case LinphoneCallConnected:
counters->number_of_LinphoneChatRoomSessionConnected++;
break;
case LinphoneCallStreamsRunning:
counters->number_of_LinphoneChatRoomSessionStreamsRunning++;
break;
case LinphoneCallPausing:
counters->number_of_LinphoneChatRoomSessionPausing++;
break;
case LinphoneCallPaused:
counters->number_of_LinphoneChatRoomSessionPaused++;
break;
case LinphoneCallResuming:
counters->number_of_LinphoneChatRoomSessionResuming++;
break;
case LinphoneCallRefered:
counters->number_of_LinphoneChatRoomSessionRefered++;
break;
case LinphoneCallError:
counters->number_of_LinphoneChatRoomSessionError++;
break;
case LinphoneCallEnd:
counters->number_of_LinphoneChatRoomSessionEnd++;
break;
case LinphoneCallPausedByRemote:
counters->number_of_LinphoneChatRoomSessionPausedByRemote++;
break;
case LinphoneCallUpdatedByRemote:
counters->number_of_LinphoneChatRoomSessionUpdatedByRemote++;
break;
case LinphoneCallIncomingEarlyMedia:
counters->number_of_LinphoneChatRoomSessionIncomingEarlyMedia++;
break;
case LinphoneCallUpdating:
counters->number_of_LinphoneChatRoomSessionUpdating++;
break;
case LinphoneCallReleased:
counters->number_of_LinphoneChatRoomSessionReleased++;
break;
case LinphoneCallEarlyUpdating:
counters->number_of_LinphoneChatRoomSessionEarlyUpdating++;
break;
case LinphoneCallEarlyUpdatedByRemote:
counters->number_of_LinphoneChatRoomSessionEarlyUpdatedByRemote++;
break;
default:
BC_FAIL("unexpected event");
break;
}
}
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
static void chat_room_is_composing_received(LinphoneChatRoom *cr,
BCTBX_UNUSED(const LinphoneAddress *remoteAddr),
bool_t isComposing) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
if (isComposing) manager->stat.number_of_LinphoneIsComposingActiveReceived++;
else manager->stat.number_of_LinphoneIsComposingIdleReceived++;
}
static void undecryptable_message_received(LinphoneChatRoom *room, BCTBX_UNUSED(LinphoneChatMessage *msg)) {
get_stats(linphone_chat_room_get_core(room))->number_of_LinphoneMessageUndecryptable++;
}
static void chat_room_participant_added(LinphoneChatRoom *cr, BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_participants_added++;
}
static void chat_room_participant_admin_status_changed(LinphoneChatRoom *cr,
BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_participant_admin_statuses_changed++;
}
static void chat_room_participant_removed(LinphoneChatRoom *cr, BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_participants_removed++;
}
static void chat_room_participant_device_added(LinphoneChatRoom *cr, BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_participant_devices_added++;
}
static void chat_room_participant_device_removed(LinphoneChatRoom *cr,
BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_participant_devices_removed++;
}
static void chat_room_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
const LinphoneAddress *addr = linphone_chat_room_get_conference_address(cr);
if (addr) {
char *addr_str = linphone_address_as_string(addr);
ms_message("ChatRoom [%s] state changed: %s", addr_str, linphone_chat_room_state_to_string(newState));
bctbx_free(addr_str);
}
switch (newState) {
case LinphoneChatRoomStateNone:
break;
case LinphoneChatRoomStateInstantiated:
manager->stat.number_of_LinphoneConferenceStateInstantiated++;
break;
case LinphoneChatRoomStateCreationPending:
manager->stat.number_of_LinphoneConferenceStateCreationPending++;
break;
case LinphoneChatRoomStateCreated:
manager->stat.number_of_LinphoneConferenceStateCreated++;
break;
case LinphoneChatRoomStateCreationFailed:
manager->stat.number_of_LinphoneConferenceStateCreationFailed++;
break;
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
case LinphoneChatRoomStateTerminationPending:
manager->stat.number_of_LinphoneConferenceStateTerminationPending++;
break;
case LinphoneChatRoomStateTerminated:
manager->stat.number_of_LinphoneConferenceStateTerminated++;
break;
case LinphoneChatRoomStateTerminationFailed:
manager->stat.number_of_LinphoneConferenceStateTerminationFailed++;
break;
case LinphoneChatRoomStateDeleted:
manager->stat.number_of_LinphoneConferenceStateDeleted++;
break;
default:
ms_error("Invalid ChatRoom state for Chatroom [%s] EndOfEnum is used ONLY as a guard",
linphone_address_as_string(addr));
break;
}
}
static void chat_room_security_event(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
switch (linphone_event_log_get_security_event_type(event_log)) {
case LinphoneSecurityEventTypeNone:
break;
case LinphoneSecurityEventTypeSecurityLevelDowngraded:
manager->stat.number_of_SecurityLevelDowngraded++;
break;
case LinphoneSecurityEventTypeParticipantMaxDeviceCountExceeded:
manager->stat.number_of_ParticipantMaxDeviceCountExceeded++;
break;
case LinphoneSecurityEventTypeEncryptionIdentityKeyChanged:
manager->stat.number_of_EncryptionIdentityKeyChanged++;
break;
case LinphoneSecurityEventTypeManInTheMiddleDetected:
manager->stat.number_of_ManInTheMiddleDetected++;
break;
}
}
static void chat_room_subject_changed(LinphoneChatRoom *cr, BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_subject_changed++;
}
static void chat_room_conference_joined(LinphoneChatRoom *cr, BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_LinphoneChatRoomConferenceJoined++;
}
static void chat_room_message_ephemeral(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
switch (linphone_event_log_get_type(event_log)) {
case LinphoneEventLogTypeConferenceEphemeralMessageLifetimeChanged:
manager->stat.number_of_LinphoneChatRoomEphemeralLifetimeChanged++;
break;
case LinphoneEventLogTypeConferenceEphemeralMessageEnabled:
manager->stat.number_of_LinphoneChatRoomEphemeralMessageEnabled++;
break;
case LinphoneEventLogTypeConferenceEphemeralMessageDisabled:
manager->stat.number_of_LinphoneChatRoomEphemeralMessageDisabled++;
break;
default:
break;
}
}
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
static void chat_room_message_ephemeral_started(LinphoneChatRoom *cr, BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_LinphoneChatRoomEphemeralTimerStarted++;
}
static void chat_room_message_ephemeral_deleted(LinphoneChatRoom *cr, BCTBX_UNUSED(const LinphoneEventLog *event_log)) {
LinphoneCore *core = linphone_chat_room_get_core(cr);
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_LinphoneChatRoomEphemeralDeleted++;
}
void setup_chat_room_callbacks(LinphoneChatRoomCbs *cbs) {
linphone_chat_room_cbs_set_session_state_changed(cbs, chat_room_session_state_changed);
linphone_chat_room_cbs_set_is_composing_received(cbs, chat_room_is_composing_received);
linphone_chat_room_cbs_set_participant_added(cbs, chat_room_participant_added);
linphone_chat_room_cbs_set_participant_admin_status_changed(cbs, chat_room_participant_admin_status_changed);
linphone_chat_room_cbs_set_participant_removed(cbs, chat_room_participant_removed);
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_cbs_set_security_event(cbs, chat_room_security_event);
linphone_chat_room_cbs_set_subject_changed(cbs, chat_room_subject_changed);
linphone_chat_room_cbs_set_participant_device_added(cbs, chat_room_participant_device_added);
linphone_chat_room_cbs_set_participant_device_removed(cbs, chat_room_participant_device_removed);
linphone_chat_room_cbs_set_undecryptable_message_received(cbs, undecryptable_message_received);
linphone_chat_room_cbs_set_conference_joined(cbs, chat_room_conference_joined);
linphone_chat_room_cbs_set_ephemeral_event(cbs, chat_room_message_ephemeral);
linphone_chat_room_cbs_set_ephemeral_message_timer_started(cbs, chat_room_message_ephemeral_started);
linphone_chat_room_cbs_set_ephemeral_message_deleted(cbs, chat_room_message_ephemeral_deleted);
}
void core_chat_room_state_changed(BCTBX_UNUSED(LinphoneCore *core), LinphoneChatRoom *cr, LinphoneChatRoomState state) {
if (state == LinphoneChatRoomStateInstantiated) {
LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
setup_chat_room_callbacks(cbs);
linphone_chat_room_add_callbacks(cr, cbs);
linphone_chat_room_cbs_unref(cbs);
}
}
void core_chat_room_subject_changed(LinphoneCore *core, BCTBX_UNUSED(LinphoneChatRoom *cr)) {
LinphoneCoreManager *manager = (LinphoneCoreManager *)linphone_core_get_user_data(core);
manager->stat.number_of_core_chat_room_subject_changed++;
}
void configure_core_for_conference(LinphoneCore *core,
const char *username,
const LinphoneAddress *factoryAddr,
bool_t server) {
const char *identity = linphone_core_get_identity(core);
LinphoneAddress *addr = linphone_address_new(identity);
linphone_address_set_username(
addr, (username) ? username : linphone_address_get_username(addr)); // What's the point if !username?
char *newIdentity = linphone_address_as_string_uri_only(addr);
linphone_address_unref(addr);
linphone_core_set_primary_contact(core, newIdentity);
bctbx_free(newIdentity);
linphone_core_enable_conference_server(core, server);
linphone_core_enable_rtp_bundle(core, TRUE);
LinphoneAccount *account = linphone_core_get_default_account(core);
const LinphoneAccountParams *account_params = linphone_account_get_params(account);
LinphoneAccountParams *new_account_params = linphone_account_params_clone(account_params);
linphone_account_params_enable_rtp_bundle(new_account_params, TRUE);
linphone_account_set_params(account, new_account_params);
linphone_account_params_unref(new_account_params);
BC_ASSERT_TRUE(linphone_account_params_rtp_bundle_enabled(linphone_account_get_params(account)));
if (factoryAddr) {
char *factoryUri = linphone_address_as_string(factoryAddr);
LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(core);
linphone_proxy_config_edit(proxy);
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
linphone_proxy_config_set_conference_factory_uri(proxy, factoryUri);
linphone_proxy_config_done(proxy);
bctbx_free(factoryUri);
}
}
void _configure_core_for_conference(LinphoneCoreManager *lcm, const LinphoneAddress *factoryAddr) {
configure_core_for_conference(lcm->lc, NULL, factoryAddr, FALSE);
}
void _configure_core_for_audio_video_conference(LinphoneCoreManager *lcm, const LinphoneAddress *factoryAddr) {
if (factoryAddr) {
LinphoneAccount *account = linphone_core_get_default_account(lcm->lc);
LinphoneAccountParams *params = linphone_account_params_clone(linphone_account_get_params(account));
linphone_account_params_set_audio_video_conference_factory_address(params, factoryAddr);
linphone_account_set_params(account, params);
linphone_account_params_unref(params);
}
}
void configure_core_for_callbacks(LinphoneCoreManager *lcm, LinphoneCoreCbs *cbs) {
// Remove is-composing callback from the core, we use our own on the chat room
linphone_core_cbs_set_is_composing_received(lcm->cbs, NULL);
linphone_core_add_callbacks(lcm->lc, cbs);
linphone_core_set_user_data(lcm->lc, lcm);
}
void _start_core(LinphoneCoreManager *lcm) {
linphone_core_manager_start(lcm, TRUE);
}
LinphoneChatMessage *_send_message_ephemeral(LinphoneChatRoom *chatRoom, const char *message, bool_t isEphemeral) {
LinphoneChatMessage *msg = linphone_chat_room_create_message_from_utf8(chatRoom, message);
LinphoneChatMessageCbs *msgCbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(msgCbs, liblinphone_tester_chat_message_msg_state_changed);
if (isEphemeral) {
linphone_chat_message_cbs_set_ephemeral_message_timer_started(
msgCbs, liblinphone_tester_chat_message_ephemeral_timer_started);
linphone_chat_message_cbs_set_ephemeral_message_deleted(msgCbs,
liblinphone_tester_chat_message_ephemeral_deleted);
}
linphone_chat_message_send(msg);
return msg;
}
LinphoneChatMessage *_send_message(LinphoneChatRoom *chatRoom, const char *message) {
return _send_message_ephemeral(chatRoom, message, FALSE);
}
static void fill_content_buffer(LinphoneContent *content, const char *sendFilePath) {
FILE *file_to_send = NULL;
size_t file_size;
file_to_send = fopen(sendFilePath, "rb");
BC_ASSERT_PTR_NOT_NULL(file_to_send);
fseek(file_to_send, 0, SEEK_END);
file_size = ftell(file_to_send);
fseek(file_to_send, 0, SEEK_SET);
uint8_t *buf = ms_malloc(file_size);
size_t read = fread(buf, sizeof(uint8_t), file_size, file_to_send);
BC_ASSERT_EQUAL((int)read, (int)file_size, int, "%d");
linphone_content_set_buffer(content, buf, file_size);
linphone_content_set_size(content, file_size); /*total size to be transfered*/
fclose(file_to_send);
}
void _send_file_plus_text(
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
LinphoneChatRoom *cr, const char *sendFilepath, const char *sendFilepath2, const char *text, bool_t use_buffer) {
LinphoneChatMessage *msg;
LinphoneChatMessageCbs *cbs;
LinphoneContent *content = linphone_core_create_content(linphone_chat_room_get_core(cr));
belle_sip_object_set_name(BELLE_SIP_OBJECT(content), "sintel trailer content");
linphone_content_set_type(content, "video");
linphone_content_set_subtype(content, "mkv");
linphone_content_set_name(content, "sintel_trailer_opus_h264.mkv");
if (use_buffer) {
fill_content_buffer(content, sendFilepath);
} else {
linphone_content_set_file_path(content, sendFilepath);
}
msg = linphone_chat_room_create_empty_message(cr);
linphone_chat_message_add_file_content(msg, content);
linphone_content_unref(content);
if (text) linphone_chat_message_add_utf8_text_content(msg, text);
if (sendFilepath2) {
LinphoneContent *content2 = linphone_core_create_content(linphone_chat_room_get_core(cr));
belle_sip_object_set_name(BELLE_SIP_OBJECT(content2), "ahbahouaismaisbon content");
linphone_content_set_type(content2, "audio");
linphone_content_set_subtype(content2, "wav");
linphone_content_set_name(content2, "ahbahouaismaisbon.wav");
if (use_buffer) {
fill_content_buffer(content2, sendFilepath2);
} else {
linphone_content_set_file_path(content2, sendFilepath2);
}
linphone_chat_message_add_file_content(msg, content2);
linphone_content_unref(content2);
}
cbs = linphone_factory_create_chat_message_cbs(linphone_factory_get());
linphone_chat_message_cbs_set_file_transfer_send_chunk(cbs, tester_file_transfer_send_2);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication_2);
linphone_chat_message_add_callbacks(msg, cbs);
linphone_chat_message_cbs_unref(cbs);
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
}
void _send_file(LinphoneChatRoom *cr, const char *sendFilepath, const char *sendFilepath2, bool_t use_buffer) {
_send_file_plus_text(cr, sendFilepath, sendFilepath2, NULL, use_buffer);
}
void _receive_file_plus_text(bctbx_list_t *coresList,
LinphoneCoreManager *lcm,
stats *receiverStats,
const char *receive_filepath,
const char *sendFilepath,
const char *sendFilepath2,
const char *text,
bool_t use_buffer) {
if (BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_LinphoneMessageReceivedWithFile,
receiverStats->number_of_LinphoneMessageReceivedWithFile + 1,
liblinphone_tester_sip_timeout))) {
LinphoneChatMessageCbs *cbs;
LinphoneChatMessage *msg = lcm->stat.last_received_chat_message;
const char *downloaded_file = NULL;
if (!use_buffer) {
downloaded_file = receive_filepath;
}
if (text) {
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
BC_ASSERT_TRUE(linphone_chat_message_has_text_content(msg));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_utf8_text(msg), text);
}
cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_cbs_set_file_transfer_recv(cbs, file_transfer_received);
linphone_chat_message_cbs_set_file_transfer_progress_indication(cbs, file_transfer_progress_indication_2);
BC_ASSERT_PTR_NOT_NULL(linphone_chat_message_get_external_body_url(msg));
LinphoneContent *fileTransferContent = linphone_chat_message_get_file_transfer_information(msg);
BC_ASSERT_TRUE(linphone_content_is_file_transfer(fileTransferContent));
if (!use_buffer) {
linphone_content_set_file_path(fileTransferContent, downloaded_file);
}
linphone_chat_message_download_content(msg, fileTransferContent);
BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int,
"%d");
// Cancel the download
wait_for_list(coresList, NULL, 0, 400);
char *downloaded_file_temp = bctbx_concat(downloaded_file, ".copy", NULL);
remove(downloaded_file_temp);
liblinphone_tester_copy_file(downloaded_file, downloaded_file_temp);
linphone_chat_message_cancel_file_transfer(msg);
liblinphone_tester_copy_file(downloaded_file_temp, downloaded_file);
remove(downloaded_file_temp);
bctbx_free(downloaded_file_temp);
linphone_chat_message_download_content(msg, fileTransferContent);
if (BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_LinphoneMessageFileTransferDone,
receiverStats->number_of_LinphoneMessageFileTransferDone + 1,
liblinphone_tester_sip_timeout))) {
if (use_buffer) {
// file_transfer_received function store file name into file_transfer_filepath
downloaded_file = bctbx_strdup(linphone_chat_message_get_file_transfer_filepath(msg));
}
compare_files(sendFilepath, downloaded_file);
}
if (sendFilepath2) {
remove(downloaded_file);
LinphoneContent *fileTransferContent2 = linphone_chat_message_get_file_transfer_information(msg);
BC_ASSERT_TRUE(linphone_content_is_file_transfer(fileTransferContent2));
if (!use_buffer) {
linphone_content_set_file_path(fileTransferContent2, downloaded_file);
}
linphone_chat_message_download_content(msg, fileTransferContent2);
BC_ASSERT_EQUAL(linphone_chat_message_get_state(msg), LinphoneChatMessageStateFileTransferInProgress, int,
"%d");
if (BC_ASSERT_TRUE(wait_for_list(coresList, &lcm->stat.number_of_LinphoneMessageFileTransferDone,
receiverStats->number_of_LinphoneMessageFileTransferDone + 2,
liblinphone_tester_sip_timeout))) {
if (use_buffer) {
// file_transfer_received function store file name into file_transfer_filepath
downloaded_file = bctbx_strdup(linphone_chat_message_get_file_transfer_filepath(msg));
}
compare_files(sendFilepath2, downloaded_file);
}
}
}
}
void _receive_file(bctbx_list_t *coresList,
LinphoneCoreManager *lcm,
stats *receiverStats,
const char *receive_filepath,
const char *sendFilepath,
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
const char *sendFilepath2,
bool_t use_buffer) {
_receive_file_plus_text(coresList, lcm, receiverStats, receive_filepath, sendFilepath, sendFilepath2, NULL,
use_buffer);
}
// Configure list of core manager for conference and add the listener
static bctbx_list_t *_init_core_for_conference_with_factory_uri(bctbx_list_t *coreManagerList,
const char *factoryUri,
const char *groupchat_version) {
LinphoneAddress *factoryAddr = linphone_address_new(factoryUri);
bctbx_list_for_each2(coreManagerList, (void (*)(void *, void *))_configure_core_for_conference,
(void *)factoryAddr);
linphone_address_unref(factoryAddr);
if (groupchat_version) {
bctbx_list_t *it;
char *spec = bctbx_strdup_printf("groupchat/%s", groupchat_version);
for (it = coreManagerList; it != NULL; it = it->next) {
LinphoneCoreManager *mgr = (LinphoneCoreManager *)it->data;
linphone_core_remove_linphone_spec(mgr->lc, "groupchat");
linphone_core_add_linphone_spec(mgr->lc, spec);
}
bctbx_free(spec);
}
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
linphone_core_cbs_set_chat_room_state_changed(cbs, core_chat_room_state_changed);
linphone_core_cbs_set_chat_room_subject_changed(cbs, core_chat_room_subject_changed);
bctbx_list_for_each2(coreManagerList, (void (*)(void *, void *))configure_core_for_callbacks, (void *)cbs);
linphone_core_cbs_unref(cbs);
bctbx_list_t *coresList = NULL;
bctbx_list_t *item = coreManagerList;
for (item = coreManagerList; item; item = bctbx_list_next(item))
coresList = bctbx_list_append(coresList, ((LinphoneCoreManager *)(bctbx_list_get_data(item)))->lc);
return coresList;
}
bctbx_list_t *init_core_for_conference_with_factory_uri(bctbx_list_t *coreManagerList, const char *factoryUri) {
return _init_core_for_conference_with_factory_uri(coreManagerList, factoryUri, NULL);
}
bctbx_list_t *init_core_for_conference(bctbx_list_t *coreManagerList) {
return init_core_for_conference_with_factory_uri(coreManagerList, sFactoryUri);
}
bctbx_list_t *init_core_for_conference_with_groupchat_version(bctbx_list_t *coreManagerList,
const char *groupchat_version) {
return _init_core_for_conference_with_factory_uri(coreManagerList, sFactoryUri, groupchat_version);
}
void start_core_for_conference(bctbx_list_t *coreManagerList) {
bctbx_list_for_each(coreManagerList, (void (*)(void *))_start_core);
}
static LinphoneChatRoom *check_has_chat_room_client_side(bctbx_list_t *lcs,
LinphoneCoreManager *lcm,
BCTBX_UNUSED(stats *initialStats),
const LinphoneAddress *confAddr,
const char *subject,
int participantNumber,
bool_t isAdmin) {
char *deviceIdentity = linphone_core_get_device_identity(lcm->lc);
LinphoneAddress *localAddr = linphone_address_new(deviceIdentity);
bctbx_free(deviceIdentity);
LinphoneChatRoom *chatRoom = linphone_core_find_chat_room(lcm->lc, confAddr, localAddr);
linphone_address_unref(localAddr);
BC_ASSERT_PTR_NOT_NULL(chatRoom);
if (chatRoom) {
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
BC_ASSERT_TRUE(
wait_for_chat_room_participants(lcs, chatRoom, participantNumber, liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(chatRoom), participantNumber, int, "%d");
LinphoneParticipant *participant = linphone_chat_room_get_me(chatRoom);
BC_ASSERT_PTR_NOT_NULL(participant);
if (!(linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesOneToOne))
BC_ASSERT(isAdmin == linphone_participant_is_admin(participant));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(chatRoom), subject);
if (linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesBasic) {
BC_ASSERT_FALSE(linphone_chat_room_can_handle_participants(chatRoom));
} else {
BC_ASSERT_TRUE(linphone_chat_room_can_handle_participants(chatRoom));
}
}
return chatRoom;
}
LinphoneChatRoom *check_creation_chat_room_client_side(bctbx_list_t *lcs,
LinphoneCoreManager *lcm,
stats *initialStats,
const LinphoneAddress *confAddr,
const char *subject,
int participantNumber,
bool_t isAdmin) {
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneConferenceStateCreationPending,
initialStats->number_of_LinphoneConferenceStateCreationPending + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneConferenceStateCreated,
initialStats->number_of_LinphoneConferenceStateCreated + 1,
liblinphone_tester_sip_timeout));
if (linphone_core_is_network_reachable(lcm->lc)) {
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomConferenceJoined,
initialStats->number_of_LinphoneChatRoomConferenceJoined + 1,
liblinphone_tester_sip_timeout));
}
return check_has_chat_room_client_side(lcs, lcm, initialStats, confAddr, subject, participantNumber, isAdmin);
}
void check_create_chat_room_client_side(bctbx_list_t *lcs,
LinphoneCoreManager *lcm,
LinphoneChatRoom *chatRoom,
stats *initialStats,
bctbx_list_t *participantsAddresses,
const char *initialSubject,
int expectedParticipantSize) {
const LinphoneChatRoomParams *params = linphone_chat_room_get_current_params(chatRoom);
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneConferenceStateInstantiated,
initialStats->number_of_LinphoneConferenceStateInstantiated + 1, 100));
BC_ASSERT_PTR_NOT_NULL(params);
if (linphone_chat_room_params_encryption_enabled(params)) {
BC_ASSERT_EQUAL(linphone_chat_room_get_security_level(chatRoom), LinphoneChatRoomSecurityLevelEncrypted,
LinphoneChatRoomSecurityLevel, "%i");
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesEncrypted);
}
// Check that the chat room is correctly created on Marie's side and that the participants are added
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneConferenceStateCreationPending,
initialStats->number_of_LinphoneConferenceStateCreationPending + 1,
liblinphone_tester_sip_timeout));
LinphoneParticipant *participant = linphone_chat_room_get_me(chatRoom);
BC_ASSERT_PTR_NOT_NULL(participant);
if (expectedParticipantSize == 0) {
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneConferenceStateCreationFailed,
initialStats->number_of_LinphoneConferenceStateCreationFailed + 1,
liblinphone_tester_sip_timeout));
if (participant) BC_ASSERT_FALSE(linphone_participant_is_admin(participant));
} else {
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
if (linphone_core_is_network_reachable(lcm->lc)) {
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneConferenceStateCreated,
initialStats->number_of_LinphoneConferenceStateCreated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(lcs, &lcm->stat.number_of_LinphoneChatRoomConferenceJoined,
initialStats->number_of_LinphoneChatRoomConferenceJoined + 1,
liblinphone_tester_sip_timeout));
// FIXME: Small hack to handle situation where the core resubscribes to the chat room
wait_for_list(lcs, NULL, 0, 1000);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(chatRoom),
(expectedParticipantSize >= 0) ? expectedParticipantSize
: ((int)bctbx_list_size(participantsAddresses)),
int, "%d");
if (participant) BC_ASSERT_TRUE(linphone_participant_is_admin(participant));
}
}
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(chatRoom), initialSubject);
if (linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesBasic) {
BC_ASSERT_FALSE(linphone_chat_room_can_handle_participants(chatRoom));
} else {
BC_ASSERT_TRUE(linphone_chat_room_can_handle_participants(chatRoom));
}
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
}
LinphoneChatRoom *create_chat_room_client_side_with_params(bctbx_list_t *lcs,
LinphoneCoreManager *lcm,
stats *initialStats,
bctbx_list_t *participantsAddresses,
const char *initialSubject,
LinphoneChatRoomParams *params) {
LinphoneChatRoom *chatRoom =
linphone_core_create_chat_room_2(lcm->lc, params, initialSubject, participantsAddresses);
check_create_chat_room_client_side(lcs, lcm, chatRoom, initialStats, participantsAddresses, initialSubject,
(int)bctbx_list_size(participantsAddresses));
linphone_chat_room_unref(chatRoom);
return chatRoom;
}
LinphoneChatRoom *
create_chat_room_client_side_with_expected_number_of_participants(bctbx_list_t *lcs,
LinphoneCoreManager *lcm,
stats *initialStats,
bctbx_list_t *participantsAddresses,
const char *initialSubject,
int expectedParticipantSize,
bool_t encrypted,
LinphoneChatRoomEphemeralMode mode) {
int participantsAddressesSize = (int)bctbx_list_size(participantsAddresses);
LinphoneChatRoomParams *params = linphone_core_create_default_chat_room_params(lcm->lc);
linphone_chat_room_params_enable_encryption(params, encrypted);
linphone_chat_room_params_set_ephemeral_mode(params, mode);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
linphone_chat_room_params_enable_group(params, participantsAddressesSize > 1 ? TRUE : FALSE);
LinphoneChatRoom *chatRoom =
linphone_core_create_chat_room_2(lcm->lc, params, initialSubject, participantsAddresses);
linphone_chat_room_params_unref(params);
if (!chatRoom) return NULL;
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
check_create_chat_room_client_side(lcs, lcm, chatRoom, initialStats, participantsAddresses, initialSubject,
expectedParticipantSize);
linphone_chat_room_unref(chatRoom);
return chatRoom;
}
LinphoneChatRoom *create_chat_room_with_params(bctbx_list_t *lcs,
LinphoneCoreManager *lcm,
stats *initialStats,
bctbx_list_t *participantsAddresses,
const char *initialSubject,
LinphoneChatRoomParams *params) {
int participantsAddressesSize = (int)bctbx_list_size(participantsAddresses);
if (!params) return NULL;
LinphoneChatRoom *chatRoom =
linphone_core_create_chat_room_2(lcm->lc, params, initialSubject, participantsAddresses);
check_create_chat_room_client_side(lcs, lcm, chatRoom, initialStats, participantsAddresses, initialSubject,
participantsAddressesSize);
linphone_chat_room_unref(chatRoom);
return chatRoom;
}
LinphoneChatRoom *create_chat_room_client_side(bctbx_list_t *lcs,
LinphoneCoreManager *lcm,
stats *initialStats,
bctbx_list_t *participantsAddresses,
const char *initialSubject,
bool_t encrypted,
LinphoneChatRoomEphemeralMode mode) {
return create_chat_room_client_side_with_expected_number_of_participants(
lcs, lcm, initialStats, participantsAddresses, initialSubject, (int)bctbx_list_size(participantsAddresses),
encrypted, mode);
}
static void group_chat_room_params(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
bctbx_list_t *coresManagerList = bctbx_list_append(NULL, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *participantsAddresses = NULL;
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
LinphoneChatRoom *marieCr = NULL;
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
LinphoneChatRoomParams *params = linphone_core_create_default_chat_room_params(marie->lc);
// Should create a basic chatroom
linphone_chat_room_params_enable_encryption(params, FALSE);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendBasic);
linphone_chat_room_params_enable_group(params, FALSE);
marieCr = linphone_core_create_chat_room_2(marie->lc, params, "Basic chat room subject", participantsAddresses);
BC_ASSERT_PTR_NOT_NULL(marieCr);
if (marieCr) {
BC_ASSERT_PTR_NOT_NULL(linphone_chat_room_get_current_params(marieCr));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic);
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
linphone_chat_room_unref(marieCr);
}
// Should create a one-to-one flexisip chat
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
linphone_chat_room_params_enable_group(params, FALSE);
marieCr = linphone_core_create_chat_room_2(marie->lc, params, "One to one client group chat room subject",
participantsAddresses);
BC_ASSERT_PTR_NOT_NULL(marieCr);
if (marieCr) {
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_chat_room_unref(marieCr);
}
// Should create a group flexisip chat
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
linphone_chat_room_params_enable_group(params, TRUE);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
marieCr = linphone_core_create_chat_room_2(marie->lc, params, "Group chat room subject", participantsAddresses);
BC_ASSERT_PTR_NOT_NULL(marieCr);
if (marieCr) {
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_FALSE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_chat_room_unref(marieCr);
}
// Should create an encrypted group flexisip chat
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
linphone_chat_room_params_enable_group(params, TRUE);
linphone_chat_room_params_enable_encryption(params, TRUE);
// Check that enabling encryption also defines a valid encryptionBackend
BC_ASSERT_EQUAL(linphone_chat_room_params_get_encryption_backend(params), LinphoneChatRoomEncryptionBackendLime,
int, "%d");
marieCr =
linphone_core_create_chat_room_2(marie->lc, params, "Encrypted group chat room subject", participantsAddresses);
BC_ASSERT_PTR_NOT_NULL(marieCr);
if (marieCr) {
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesEncrypted);
BC_ASSERT_FALSE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_chat_room_unref(marieCr);
}
// Should return NULL because params are invalid
linphone_chat_room_params_enable_group(params, TRUE);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendBasic); // Group + basic backend = invalid
BC_ASSERT_FALSE(linphone_chat_room_params_is_valid(params));
marieCr = linphone_core_create_chat_room_2(marie->lc, params, "Invalid chat room subject", NULL);
BC_ASSERT_PTR_NULL(marieCr);
if (marieCr) linphone_chat_room_unref(marieCr);
// Should set FlexisipChat as backend if encryption is enabled.
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendBasic);
linphone_chat_room_params_enable_encryption(params, TRUE);
BC_ASSERT_EQUAL(linphone_chat_room_params_get_backend(params), LinphoneChatRoomBackendFlexisipChat, int, "%d");
// Cleanup
linphone_chat_room_params_unref(params);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
linphone_core_manager_destroy(chloe);
}
static void group_chat_room_creation_with_given_identity(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_dual_proxy_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
BC_ASSERT_EQUAL((int)bctbx_list_size(linphone_core_get_proxy_config_list(marie->lc)), 2, int, "%d");
LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(marie->lc);
LinphoneProxyConfig *secondProxy = linphone_core_get_proxy_config_list(marie->lc)->next->data;
LinphoneAddress *marieAddr = linphone_address_new(linphone_proxy_config_get_identity(proxy));
LinphoneAddress *marieSecondAddr = linphone_address_new(linphone_proxy_config_get_identity(secondProxy));
LinphoneChatRoomParams *params = linphone_core_create_default_chat_room_params(marie->lc);
LinphoneChatRoom *marieCr =
linphone_core_create_chat_room(marie->lc, params, marieAddr, "first chat room", participantsAddresses);
BC_ASSERT_PTR_NOT_NULL(marieCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1,
liblinphone_tester_sip_timeout));
const LinphoneAddress *localAddr = linphone_chat_room_get_local_address(marieCr);
BC_ASSERT_TRUE(linphone_address_weak_equal(localAddr, marieAddr));
LinphoneChatRoom *secondMarieCr =
linphone_core_create_chat_room(marie->lc, params, marieSecondAddr, "second chat room", participantsAddresses);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1,
liblinphone_tester_sip_timeout));
localAddr = linphone_chat_room_get_local_address(secondMarieCr);
BC_ASSERT_TRUE(linphone_address_weak_equal(localAddr, marieSecondAddr));
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(marie, secondMarieCr, coresList);
if (marieCr) linphone_chat_room_unref(marieCr);
if (secondMarieCr) linphone_chat_room_unref(secondMarieCr);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
linphone_address_unref(marieAddr);
linphone_address_unref(marieSecondAddr);
linphone_chat_room_params_unref(params);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_creation_server(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
int dummy = 0;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
stats initialChloeStats = chloe->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Pauline tries to change the subject but is not admin so it fails
const char *newSubject = "Let's go drink a beer";
linphone_chat_room_set_subject(paulineCr, newSubject);
wait_for_list(coresList, &dummy, 1, 1000);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), initialSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), initialSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), initialSubject);
// Marie now changes the subject
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
// Marie designates Pauline as admin
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr, paulineAddr);
linphone_address_unref(paulineAddr);
BC_ASSERT_PTR_NOT_NULL(paulineParticipant);
paulineParticipant = linphone_participant_ref(paulineParticipant);
linphone_chat_room_set_participant_admin_status(marieCr, paulineParticipant, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(paulineParticipant));
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
linphone_participant_unref(paulineParticipant);
// Pauline adds Chloe to the chat room
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
linphone_chat_room_add_participants(paulineCr, participantsAddresses);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Check that the chat room is correctly created on Chloe's side and that she was added everywhere
LinphoneChatRoom *chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, newSubject, 3, FALSE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added,
initialMarieStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added,
initialPaulineStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added,
initialLaureStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 3, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 3, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 3, int, "%d");
// Pauline revokes the admin status of Marie
LinphoneAddress *marieAddr = linphone_address_new(linphone_core_get_identity(marie->lc));
LinphoneParticipant *marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddr);
linphone_address_unref(marieAddr);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
marieParticipant = linphone_participant_ref(marieParticipant);
linphone_chat_room_set_participant_admin_status(paulineCr, marieParticipant, FALSE);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(linphone_participant_is_admin(marieParticipant));
// Marie tries to change the subject again but is not admin, so it is not changed
linphone_chat_room_set_subject(marieCr, initialSubject);
wait_for_list(coresList, &dummy, 1, 1000);
// Chloe begins composing a message
BC_ASSERT_PTR_NOT_NULL(chloeCr);
linphone_chat_room_compose(chloeCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived,
initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived,
initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived,
initialLaureStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
const char *chloeTextMessage = "Hello";
LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDelivered,
initialChloeStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived,
initialLaureStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived,
initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived,
initialPaulineStats.number_of_LinphoneIsComposingIdleReceived + 1,
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingIdleReceived,
initialLaureStats.number_of_LinphoneIsComposingIdleReceived + 1,
liblinphone_tester_sip_timeout));
LinphoneAddress *chloeAddr;
if (BC_ASSERT_PTR_NOT_NULL(marie->stat.last_received_chat_message)) {
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message),
chloeTextMessage);
linphone_chat_message_unref(chloeMessage);
chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(
chloeAddr, linphone_chat_message_get_from_address(marie->stat.last_received_chat_message)));
linphone_address_unref(chloeAddr);
}
// Pauline removes Laure from the chat room
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(paulineCr, laureAddr);
linphone_address_unref(laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
laureParticipant = linphone_participant_ref(laureParticipant);
linphone_chat_room_remove_participant(paulineCr, laureParticipant);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_participants_removed,
initialChloeStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
linphone_participant_unref(laureParticipant);
// Pauline removes Marie and Chloe from the chat room
marieAddr = linphone_address_new(linphone_core_get_identity(marie->lc));
marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddr);
linphone_address_unref(marieAddr);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
LinphoneParticipant *chloeParticipant = linphone_chat_room_find_participant(paulineCr, chloeAddr);
linphone_address_unref(chloeAddr);
BC_ASSERT_PTR_NOT_NULL(chloeParticipant);
chloeParticipant = linphone_participant_ref(chloeParticipant);
bctbx_list_t *participantsToRemove = NULL;
initialPaulineStats = pauline->stat;
participantsToRemove = bctbx_list_append(participantsToRemove, marieParticipant);
participantsToRemove = bctbx_list_append(participantsToRemove, chloeParticipant);
linphone_chat_room_remove_participants(paulineCr, participantsToRemove);
bctbx_list_free_with_data(participantsToRemove, (bctbx_list_free_func)linphone_participant_unref);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateTerminated,
initialMarieStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneConferenceStateTerminated,
initialChloeStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 0, int, "%d");
// Pauline leaves the chat room
wait_for_list(coresList, &dummy, 1, 1000);
linphone_chat_room_leave(paulineCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateTerminationPending,
initialPaulineStats.number_of_LinphoneConferenceStateTerminationPending + 1, 100));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateTerminated,
initialPaulineStats.number_of_LinphoneConferenceStateTerminated + 1,
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
liblinphone_tester_sip_timeout));
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(laure->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(chloe->lc), 0, int, "%i");
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
linphone_core_manager_destroy(chloe);
}
static void group_chat_room_creation_server_network_down(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoomParams *params = linphone_core_create_default_chat_room_params(marie->lc);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
linphone_chat_room_params_enable_group(params, TRUE);
linphone_chat_room_params_enable_encryption(params, FALSE);
LinphoneChatRoom *marieCr =
linphone_core_create_chat_room_2(marie->lc, params, initialSubject, participantsAddresses);
linphone_chat_room_params_unref(params);
BC_ASSERT_TRUE(
wait_for_until(marie->lc, pauline->lc, &(marie->stat.number_of_LinphoneConferenceStateInstantiated), 1, 100));
// Check that the chat room is correctly created on Marie's side and that the participants are added
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc,
&(marie->stat.number_of_LinphoneConferenceStateCreationPending), 1,
liblinphone_tester_sip_timeout));
linphone_core_set_network_reachable(marie->lc, FALSE);
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc,
&(marie->stat.number_of_LinphoneConferenceStateCreationFailed), 1,
2 * liblinphone_tester_sip_timeout));
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (marieCr) linphone_chat_room_unref(marieCr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
static void group_chat_room_creation_server_network_down_up(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
int dummy = 0;
stats initialPaulineStats = pauline->stat;
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoomParams *params = linphone_core_create_default_chat_room_params(marie->lc);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
linphone_chat_room_params_enable_group(params, TRUE);
linphone_chat_room_params_enable_encryption(params, FALSE);
LinphoneChatRoom *marieCr =
linphone_core_create_chat_room_2(marie->lc, params, initialSubject, participantsAddresses);
linphone_chat_room_params_unref(params);
BC_ASSERT_TRUE(
wait_for_until(marie->lc, pauline->lc, &(marie->stat.number_of_LinphoneConferenceStateInstantiated), 1, 100));
// Check that the chat room is correctly created on Marie's side and that the participants are added
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc,
&(marie->stat.number_of_LinphoneConferenceStateCreationPending), 1,
liblinphone_tester_sip_timeout));
linphone_core_set_network_reachable(marie->lc, FALSE);
BC_ASSERT_FALSE(wait_for_until(marie->lc, pauline->lc, &dummy, 1, 5000));
linphone_core_set_network_reachable(marie->lc, TRUE);
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &(marie->stat.number_of_LinphoneConferenceStateCreated), 1,
2 * liblinphone_tester_sip_timeout));
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
if (marieCr) linphone_chat_room_unref(marieCr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_add_participant(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
linphone_core_remove_linphone_spec(chloe->lc, "groupchat");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(marie->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
stats initialChloeStats = chloe->stat;
// Pauline creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *paulineCr =
create_chat_room_client_side(coresList, pauline, &initialPaulineStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(paulineCr));
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *marieCr =
check_creation_chat_room_client_side(coresList, marie, &initialMarieStats, confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// To simulate dialog removal for Pauline
linphone_core_set_network_reachable(pauline->lc, FALSE);
LinphoneAddress *paulineAddr = linphone_address_clone(linphone_chat_room_get_peer_address(paulineCr));
coresList = bctbx_list_remove(coresList, pauline->lc);
linphone_core_manager_reinit(pauline);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline, TRUE);
paulineCr = linphone_core_search_chat_room(pauline->lc, NULL, NULL, paulineAddr, NULL);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
linphone_address_unref(paulineAddr);
// Pauline adds Chloe to the chat room
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
if (paulineCr) {
linphone_chat_room_add_participants(paulineCr, participantsAddresses);
}
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Refused by server because group chat disabled for Chloe
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_participants_added,
initialMarieStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participants_added,
initialPaulineStats.number_of_participants_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_participants_added,
initialLaureStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 2, int, "%d");
// Try to search for a participant that is not in the chatroom
LinphoneAddress *fakeAddr = linphone_address_new("sip:toto@sip.example.org");
LinphoneParticipant *fakeParticipant = linphone_chat_room_find_participant(marieCr, fakeAddr);
linphone_address_unref(fakeAddr);
BC_ASSERT_PTR_NULL(fakeParticipant);
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
// Pauline begins composing a message
linphone_chat_room_compose(paulineCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived,
initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived,
initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
// Now, Chloe is upgrading to group chat client
linphone_core_set_network_reachable(chloe->lc, FALSE);
coresList = bctbx_list_remove(coresList, chloe->lc);
linphone_core_manager_reinit(chloe);
tmpCoresManagerList = bctbx_list_append(NULL, chloe);
tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(chloe, TRUE);
// Pauline adds Chloe to the chat room
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
linphone_chat_room_add_participants(paulineCr, participantsAddresses);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Check that the chat room is correctly created on Chloe's side and that she was added everywhere
LinphoneChatRoom *chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 3, FALSE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added,
initialMarieStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added,
initialPaulineStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added,
initialLaureStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 3, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 3, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 3, int, "%d");
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(laure->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(chloe->lc), 0, int, "%i");
linphone_address_unref(confAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
linphone_core_manager_destroy(chloe);
}
static int im_encryption_engine_process_incoming_message_cb(BCTBX_UNUSED(LinphoneImEncryptionEngine *engine),
BCTBX_UNUSED(LinphoneChatRoom *room),
LinphoneChatMessage *msg) {
if (linphone_chat_message_get_content_type(msg)) {
if (strcmp(linphone_chat_message_get_content_type(msg), "cipher/b64") == 0) {
size_t b64Size = 0;
unsigned char *output;
const char *msg_str = linphone_chat_message_get_text(msg);
bctbx_base64_decode(NULL, &b64Size, (unsigned char *)msg_str, strlen(msg_str));
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
output = (unsigned char *)ms_malloc(b64Size + 1),
bctbx_base64_decode(output, &b64Size, (unsigned char *)msg_str, strlen(msg_str));
output[b64Size] = '\0';
linphone_chat_message_set_text(msg, (char *)output);
ms_free(output);
linphone_chat_message_set_content_type(msg, "message/cpim");
return 0;
} else if (strcmp(linphone_chat_message_get_content_type(msg), "application/im-iscomposing+xml") == 0) {
return -1; // Not encrypted, nothing to do
} else {
return 488; // Not acceptable
}
}
return 500;
}
static int im_encryption_engine_process_outgoing_message_cb(BCTBX_UNUSED(LinphoneImEncryptionEngine *engine),
BCTBX_UNUSED(LinphoneChatRoom *room),
LinphoneChatMessage *msg) {
if (strcmp(linphone_chat_message_get_content_type(msg), "message/cpim") == 0) {
size_t b64Size = 0;
unsigned char *output;
const char *msg_str = linphone_chat_message_get_text(msg);
bctbx_base64_encode(NULL, &b64Size, (unsigned char *)msg_str, strlen(msg_str));
output = (unsigned char *)ms_malloc0(b64Size + 1);
bctbx_base64_encode(output, &b64Size, (unsigned char *)msg_str, strlen(msg_str));
output[b64Size] = '\0';
linphone_chat_message_set_text(msg, (const char *)output);
ms_free(output);
linphone_chat_message_set_content_type(msg, "cipher/b64");
return 0;
}
return -1;
}
static void group_chat_room_message(bool_t encrypt, bool_t sal_error) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialChloeStats = chloe->stat;
LinphoneImEncryptionEngine *marie_imee = linphone_im_encryption_engine_new();
LinphoneImEncryptionEngineCbs *marie_cbs = linphone_im_encryption_engine_get_callbacks(marie_imee);
LinphoneImEncryptionEngine *pauline_imee = linphone_im_encryption_engine_new();
LinphoneImEncryptionEngineCbs *pauline_cbs = linphone_im_encryption_engine_get_callbacks(pauline_imee);
LinphoneImEncryptionEngine *chloe_imee = linphone_im_encryption_engine_new();
LinphoneImEncryptionEngineCbs *chloe_cbs = linphone_im_encryption_engine_get_callbacks(chloe_imee);
if (encrypt) {
linphone_im_encryption_engine_cbs_set_process_outgoing_message(
marie_cbs, im_encryption_engine_process_outgoing_message_cb);
linphone_im_encryption_engine_cbs_set_process_outgoing_message(
pauline_cbs, im_encryption_engine_process_outgoing_message_cb);
linphone_im_encryption_engine_cbs_set_process_outgoing_message(
chloe_cbs, im_encryption_engine_process_outgoing_message_cb);
linphone_im_encryption_engine_cbs_set_process_incoming_message(
marie_cbs, im_encryption_engine_process_incoming_message_cb);
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
linphone_im_encryption_engine_cbs_set_process_incoming_message(
pauline_cbs, im_encryption_engine_process_incoming_message_cb);
linphone_im_encryption_engine_cbs_set_process_incoming_message(
chloe_cbs, im_encryption_engine_process_incoming_message_cb);
linphone_core_set_im_encryption_engine(marie->lc, marie_imee);
linphone_core_set_im_encryption_engine(pauline->lc, pauline_imee);
linphone_core_set_im_encryption_engine(chloe->lc, chloe_imee);
}
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Chloe's side and that the participants are added
LinphoneChatRoom *chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
// Chloe begins composing a message
linphone_chat_room_compose(chloeCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived,
initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived,
initialPaulineStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
const char *chloeTextMessage = "Hello";
LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage);
const char *messageId = linphone_chat_message_get_message_id(chloeMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived,
initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived,
initialPaulineStats.number_of_LinphoneIsComposingIdleReceived + 1,
liblinphone_tester_sip_timeout));
LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end;
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage);
LinphoneChatMessage *foundMessage = linphone_chat_room_find_message(chloeCr, messageId);
linphone_chat_message_unref(chloeMessage); // Unref here because of messageId using
BC_ASSERT_PTR_NOT_NULL(foundMessage);
BC_ASSERT_PTR_NOT_NULL(linphone_chat_message_get_text(foundMessage));
linphone_chat_message_unref(foundMessage);
LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg)));
linphone_address_unref(chloeAddr);
// Pauline begins composing a messagewith some accents
linphone_chat_room_compose(paulineCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived,
initialMarieStats.number_of_LinphoneIsComposingActiveReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneIsComposingActiveReceived,
initialChloeStats.number_of_LinphoneIsComposingActiveReceived + 1,
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
liblinphone_tester_sip_timeout));
const char *paulineTextMessage = "Héllö Dàrling";
LinphoneChatMessage *paulineMessage = _send_message(paulineCr, paulineTextMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageReceived,
initialChloeStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived,
initialMarieStats.number_of_LinphoneIsComposingIdleReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneIsComposingIdleReceived,
initialChloeStats.number_of_LinphoneIsComposingIdleReceived + 1,
liblinphone_tester_sip_timeout));
marieLastMsg = marie->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end;
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_utf8_text(marieLastMsg), paulineTextMessage);
linphone_chat_message_unref(paulineMessage);
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(paulineAddr, linphone_chat_message_get_from_address(marieLastMsg)));
linphone_address_unref(paulineAddr);
if (sal_error) {
sal_set_send_error(linphone_core_get_sal(marie->lc), -1);
LinphoneChatMessage *msg = _send_message(marieCr, "Bli bli bli");
char *message_id = ms_strdup(linphone_chat_message_get_message_id(msg));
BC_ASSERT_STRING_NOT_EQUAL(message_id, "");
wait_for_list(coresList, NULL, 0, 1000);
sal_set_send_error(linphone_core_get_sal(marie->lc), 0);
linphone_chat_message_send(msg);
const char *message_id_2 = linphone_chat_message_get_message_id(msg);
BC_ASSERT_STRING_NOT_EQUAL(message_id_2, "");
BC_ASSERT_STRING_EQUAL(message_id, message_id_2);
ms_free(message_id);
wait_for_list(coresList, NULL, 0, 1000);
linphone_core_refresh_registers(marie->lc);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneRegistrationOk,
initialMarieStats.number_of_LinphoneRegistrationOk + 1,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(msg);
}
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_im_encryption_engine_unref(marie_imee);
linphone_im_encryption_engine_unref(pauline_imee);
linphone_im_encryption_engine_unref(chloe_imee);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(chloe);
}
static void group_chat_room_send_message(void) {
group_chat_room_message(FALSE, FALSE);
}
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
static void group_chat_room_send_message_encrypted(void) {
group_chat_room_message(TRUE, FALSE);
}
static void group_chat_room_send_message_with_error(void) {
group_chat_room_message(FALSE, TRUE);
}
static void group_chat_room_invite_multi_register_account(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPauline1Stats = pauline1->stat;
stats initialPauline2Stats = pauline2->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline1's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Pauline2's side and that the participants are added
LinphoneChatRoom *paulineCr2 = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline1, paulineCr, coresList);
linphone_core_delete_chat_room(pauline2->lc, paulineCr2);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_add_admin(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie designates Pauline as admin
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr, paulineAddr);
linphone_address_unref(paulineAddr);
BC_ASSERT_PTR_NOT_NULL(paulineParticipant);
linphone_chat_room_set_participant_admin_status(marieCr, paulineParticipant, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(paulineParticipant));
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_add_admin_lately_notified(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
1821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Simulate pauline has disappeared
linphone_core_set_network_reachable(pauline->lc, FALSE);
// Marie designates Pauline as admin
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr, paulineAddr);
linphone_address_unref(paulineAddr);
BC_ASSERT_PTR_NOT_NULL(paulineParticipant);
linphone_chat_room_set_participant_admin_status(marieCr, paulineParticipant, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
// Make sure pauline is not notified
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1, 3000));
linphone_core_set_network_reachable(pauline->lc, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(paulineParticipant));
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_add_admin_non_admin(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
1891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Pauline designates Laure as admin
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(paulineCr, laureAddr);
linphone_address_unref(laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
linphone_chat_room_set_participant_admin_status(paulineCr, laureParticipant, TRUE);
BC_ASSERT_FALSE(linphone_participant_is_admin(laureParticipant));
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_remove_admin(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
1961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie designates Pauline as admin
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr, paulineAddr);
linphone_address_unref(paulineAddr);
BC_ASSERT_PTR_NOT_NULL(paulineParticipant);
linphone_chat_room_set_participant_admin_status(marieCr, paulineParticipant, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(paulineParticipant));
// Pauline revokes the admin status of Marie
LinphoneAddress *marieAddr = linphone_address_new(linphone_core_get_identity(marie->lc));
LinphoneParticipant *marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddr);
linphone_address_unref(marieAddr);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
linphone_chat_room_set_participant_admin_status(paulineCr, marieParticipant, FALSE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(linphone_participant_is_admin(marieParticipant));
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_admin_creator_leaves_the_room(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
2031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie leaves the room
linphone_chat_room_leave(marieCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateTerminated,
initialMarieStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_removed,
initialLaureStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
/* FIXME: the number of admin status changed shoud be 1. But the conference server notifies first that marie looses
* its admin status, before being deleted from the chatroom. This is indeed useless to notify this. Once fixed in
* the conference server, the counter shall be set back to +1. */
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(linphone_chat_room_get_me(laureCr)));
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_change_subject(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
2101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
const char *newSubject = "New subject";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie now changes the subject
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_core_chat_room_subject_changed,
initialMarieStats.number_of_core_chat_room_subject_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_core_chat_room_subject_changed,
initialPaulineStats.number_of_core_chat_room_subject_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_core_chat_room_subject_changed,
initialLaureStats.number_of_core_chat_room_subject_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
end:
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_change_subject_non_admin(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
2171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
const char *newSubject = "New subject";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie now changes the subject
linphone_chat_room_set_subject(paulineCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), initialSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), initialSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), initialSubject);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
end:
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_remove_participant_base(bool_t restart) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
2241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr));
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie removes Laure from the chat room
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr);
linphone_address_unref(laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
linphone_chat_room_remove_participant(marieCr, laureParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
if (restart == TRUE) {
// Restart core for Marie
coresList = bctbx_list_remove(coresList, marie->lc);
linphone_core_manager_restart(marie, TRUE);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie);
init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_append(coresList, marie->lc);
// Retrieve chat room
LinphoneAddress *marieDeviceAddr = linphone_address_clone(
linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(marie->lc)));
marieCr = linphone_core_search_chat_room(marie->lc, NULL, marieDeviceAddr, confAddr, NULL);
linphone_address_unref(marieDeviceAddr);
BC_ASSERT_PTR_NOT_NULL(marieCr);
}
// Check that participant removed event has been stored
// Passing 0 as second argument because all events must be retrived
int nbMarieParticipantRemoved = 0;
bctbx_list_t *marieHistory = linphone_chat_room_get_history_events(marieCr, 0);
for (bctbx_list_t *item = marieHistory; item; item = bctbx_list_next(item)) {
LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item);
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceParticipantRemoved) {
nbMarieParticipantRemoved++;
const LinphoneAddress *removedParticipantAddress = linphone_event_log_get_participant_address(event);
BC_ASSERT_PTR_NOT_NULL(removedParticipantAddress);
2311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
}
}
bctbx_list_free_with_data(marieHistory, (bctbx_list_free_func)linphone_event_log_unref);
BC_ASSERT_EQUAL(nbMarieParticipantRemoved, 1, unsigned int, "%u");
linphone_address_unref(confAddr);
// Clean db from chat room
linphone_core_delete_chat_room(marie->lc, marieCr);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
end:
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_remove_participant(void) {
group_chat_room_remove_participant_base(FALSE);
}
static void group_chat_room_remove_participant_and_restart(void) {
group_chat_room_remove_participant_base(TRUE);
}
static void group_chat_room_send_message_with_participant_removed(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie removes Laure from the chat room
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr);
linphone_address_unref(laureAddr);
if (!BC_ASSERT_PTR_NOT_NULL(laureParticipant)) goto end;
2381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450
linphone_chat_room_remove_participant(marieCr, laureParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
// Laure try to send a message with the chat room where she was removed
const char *laureTextMessage = "Hello";
LinphoneChatMessage *laureMessage = _send_message(laureCr, laureTextMessage);
linphone_chat_message_unref(laureMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageDelivered, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived,
initialMarieStats.number_of_LinphoneIsComposingIdleReceived,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived,
initialPaulineStats.number_of_LinphoneIsComposingIdleReceived,
liblinphone_tester_sip_timeout));
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_leave(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
2451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(laureCr));
linphone_chat_room_leave(paulineCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateTerminated,
initialPaulineStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_removed,
initialLaureStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_chat_room_is_read_only(paulineCr));
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_delete_twice(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
2521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590
// Save db
const char *uri = linphone_config_get_string(linphone_core_get_config(laure->lc), "storage", "uri", "");
char *uriCopy = bc_tester_file("linphone_tester.db");
BC_ASSERT_FALSE(liblinphone_tester_copy_file(uri, uriCopy));
// Clean db from chat room
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
// Reset db
laure->database_path = uriCopy;
coresList = bctbx_list_remove(coresList, laure->lc);
linphone_core_manager_reinit(laure);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(laure, TRUE);
// Check that the chat room has correctly created on Laure's side and that the participants are added
laureCr = check_has_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
end:
// Clean db from chat room again
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_come_back_after_disconnection(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
int dummy = 0;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
const char *newSubject = "New subject";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
2591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
linphone_core_set_network_reachable(marie->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 1000);
linphone_core_set_network_reachable(marie->lc, TRUE);
wait_for_list(coresList, &dummy, 1, 1000);
// Marie now changes the subject
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_create_room_with_disconnected_friends_base(bool_t initial_message) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
int dummy = 0;
LinphoneChatRoom *paulineCr = NULL;
LinphoneChatRoom *laureCr = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
wait_for_list(coresList, &dummy, 1, 2000);
// Disconnect pauline and laure
linphone_core_set_network_reachable(pauline->lc, FALSE);
linphone_core_set_network_reachable(laure->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 2000);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
2661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
if (initial_message) {
LinphoneChatMessage *msg = linphone_chat_room_create_message_from_utf8(marieCr, "Salut");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
}
wait_for_list(coresList, &dummy, 1, 4000);
// Reconnect Pauline and check that the chat room is correctly created on Pauline's side and that the participants
// are added
linphone_core_set_network_reachable(pauline->lc, TRUE);
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Reconnect Laure and check that the chat room is correctly created on Laure's side and that the participants are
// added
linphone_core_set_network_reachable(laure->lc, TRUE);
laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(laureCr)) goto end;
if (initial_message) {
if (BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1,
liblinphone_tester_sip_timeout))) {
LinphoneChatMessage *msg = linphone_chat_room_get_last_message_in_history(paulineCr);
if (BC_ASSERT_PTR_NOT_NULL(msg)) {
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), "Salut");
linphone_chat_message_unref(msg);
}
}
if (BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneMessageReceived, 1,
liblinphone_tester_sip_timeout))) {
LinphoneChatMessage *msg = linphone_chat_room_get_last_message_in_history(laureCr);
if (BC_ASSERT_PTR_NOT_NULL(msg)) {
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(msg), "Salut");
linphone_chat_message_unref(msg);
}
}
}
end:
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (laureCr) linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_create_room_with_disconnected_friends(void) {
group_chat_room_create_room_with_disconnected_friends_base(FALSE);
}
static void group_chat_room_create_room_with_disconnected_friends_and_initial_message(void) {
group_chat_room_create_room_with_disconnected_friends_base(TRUE);
}
static void group_chat_room_reinvited_after_removed_base(bool_t offline_when_removed,
bool_t offline_when_reinvited,
bool_t restart_after_reinvited) {
2731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
const char *marieIdentity = linphone_core_get_identity(marie->lc);
const char *paulineIdentity = linphone_core_get_identity(pauline->lc);
const char *laureIdentity = linphone_core_get_identity(laure->lc);
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(paulineIdentity));
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(laureIdentity));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
char *savedLaureUuid = NULL;
char *laureParticipantAddress = NULL;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
char *conference_address_str = (confAddr) ? linphone_address_as_string(confAddr) : ms_strdup("<unknown>");
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
LinphoneChatRoom *newLaureCr = NULL;
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr) || !BC_ASSERT_PTR_NOT_NULL(paulineCr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
LinphoneAddress *laureAddr = linphone_address_new(laureIdentity);
laureParticipantAddress = linphone_address_as_string(laureAddr);
if (offline_when_removed) {
savedLaureUuid =
bctbx_strdup(linphone_config_get_string(linphone_core_get_config(laure->lc), "misc", "uuid", NULL));
coresList = bctbx_list_remove(coresList, laure->lc);
coresManagerList = bctbx_list_remove(coresManagerList, laure);
linphone_core_set_network_reachable(laure->lc, FALSE);
linphone_core_manager_stop(laure);
}
// Marie removes Laure from the chat room
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
ms_message("%s removes %s to chatroom %s", marieIdentity, laureParticipantAddress, conference_address_str);
linphone_chat_room_remove_participant(marieCr, laureParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
if (offline_when_removed && !offline_when_reinvited) {
wait_for_list(coresList, 0, 1, 20000); /* see large comment below, also applicable for BYE */
linphone_core_manager_configure(laure);
linphone_config_set_string(linphone_core_get_config(laure->lc), "misc", "uuid", savedLaureUuid);
2801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870
bctbx_free(savedLaureUuid);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
linphone_core_manager_start(laure, TRUE);
laureIdentity = linphone_core_get_identity(laure->lc);
coresList = bctbx_list_concat(coresList, tmpCoresList);
coresManagerList = bctbx_list_append(coresManagerList, laure);
}
if (!offline_when_reinvited) {
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
}
wait_for_list(coresList, 0, 1, 2000);
initialLaureStats = laure->stat;
// Marie adds Laure to the chat room
ms_message("%s adds %s to chatroom %s", marieIdentity, laureParticipantAddress, conference_address_str);
participantsAddresses = bctbx_list_append(participantsAddresses, laureAddr);
linphone_chat_room_add_participants(marieCr, participantsAddresses);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added,
initialMarieStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added,
initialPaulineStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
if (offline_when_reinvited) {
/*
* Hack: while we were offline the server sent an INVITE, that will get a 408 timeout after 20 seconds.
* During this time, the REGISTER from Laure won't trigger a new INVITE.
* FIXME: it should be handled at server side.
* However, since the case isn't very real-world probable, we can workaround it in the test by waiting this
* INVITE to timeout, and then REGISTER.
* */
wait_for_list(coresList, 0, 1, 20000);
linphone_core_manager_configure(laure);
linphone_config_set_string(linphone_core_get_config(laure->lc), "misc", "uuid", savedLaureUuid);
bctbx_free(savedLaureUuid);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
linphone_core_manager_start(laure, TRUE);
coresList = bctbx_list_concat(coresList, tmpCoresList);
coresManagerList = bctbx_list_append(coresManagerList, laure);
}
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateCreated,
initialLaureStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 2, int, "%d");
char *laureDeviceIdentity = linphone_core_get_device_identity(laure->lc);
laureAddr = linphone_address_new(laureDeviceIdentity);
bctbx_free(laureDeviceIdentity);
newLaureCr = linphone_core_find_chat_room(laure->lc, confAddr, laureAddr);
linphone_address_unref(laureAddr);
if (!offline_when_removed) BC_ASSERT_PTR_EQUAL(newLaureCr, laureCr);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(newLaureCr), 2, int, "%d");
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(newLaureCr), initialSubject);
BC_ASSERT_FALSE(linphone_chat_room_has_been_left(newLaureCr));
unsigned int nbLaureConferenceCreatedEventsBeforeRestart = 0;
bctbx_list_t *laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0);
for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) {
LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item);
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated)
nbLaureConferenceCreatedEventsBeforeRestart++;
}
bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref);
// Restarting Laure's core doesn't generate a second ConferenceCreated event
2871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940
BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsBeforeRestart, 1, unsigned int, "%u");
if (restart_after_reinvited) {
ms_message("%s restarts its core", laureIdentity);
coresList = bctbx_list_remove(coresList, laure->lc);
linphone_core_manager_reinit(laure);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(laure, TRUE);
laureIdentity = linphone_core_get_device_identity(laure->lc);
laureAddr = linphone_address_new(laureIdentity);
newLaureCr = linphone_core_find_chat_room(laure->lc, confAddr, laureAddr);
linphone_address_unref(laureAddr);
wait_for_list(coresList, 0, 1, 2000);
BC_ASSERT_FALSE(linphone_chat_room_has_been_left(newLaureCr));
unsigned int nbLaureConferenceCreatedEventsAfterRestart = 0;
bctbx_list_t *laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0);
for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) {
LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item);
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated)
nbLaureConferenceCreatedEventsAfterRestart++;
}
bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref);
BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsAfterRestart, nbLaureConferenceCreatedEventsBeforeRestart + 1,
unsigned int, "%u");
}
end:
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, newLaureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
ms_free(conference_address_str);
if (laureParticipantAddress) ms_free(laureParticipantAddress);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_reinvited_after_removed(void) {
group_chat_room_reinvited_after_removed_base(FALSE, FALSE, FALSE);
}
static void group_chat_room_reinvited_after_removed_2(void) {
group_chat_room_reinvited_after_removed_base(FALSE, FALSE, TRUE);
}
static void group_chat_room_reinvited_after_removed_while_offline(void) {
group_chat_room_reinvited_after_removed_base(TRUE, FALSE, FALSE);
}
static void group_chat_room_reinvited_after_removed_while_offline_2(void) {
group_chat_room_reinvited_after_removed_base(TRUE, TRUE, FALSE);
}
static void group_chat_room_reinvited_after_removed_with_several_devices(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
2941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010
coresManagerList = bctbx_list_append(coresManagerList, marie2);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialMarie2Stats = marie2->stat;
stats initialPauline1Stats = pauline1->stat;
stats initialPauline2Stats = pauline2->stat;
stats initialLaureStats = laure->stat;
// Marie2 is initially offline
linphone_core_set_network_reachable(marie2->lc, FALSE);
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marie1Cr =
create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
LinphoneChatRoom *marie2Cr = NULL;
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marie1Cr);
// Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are
// added
LinphoneChatRoom *pauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats,
confAddr, initialSubject, 2, FALSE);
LinphoneChatRoom *pauline2Cr = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats,
confAddr, initialSubject, 2, FALSE);
LinphoneChatRoom *newPauline1Cr = NULL;
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marie1Cr) || !BC_ASSERT_PTR_NOT_NULL(pauline1Cr) ||
!BC_ASSERT_PTR_NOT_NULL(pauline2Cr) || !BC_ASSERT_PTR_NOT_NULL(laureCr))
goto end;
// Marie1 removes Pauline from the chat room while Pauline2 is offline
linphone_core_set_network_reachable(pauline2->lc, FALSE);
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline1->lc));
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marie1Cr, paulineAddr);
BC_ASSERT_PTR_NOT_NULL(paulineParticipant);
linphone_chat_room_remove_participant(marie1Cr, paulineParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_participants_removed,
initialMarie1Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_removed,
initialLaureStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_LinphoneConferenceStateTerminated,
initialPauline1Stats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
// Marie2 comes online, check that pauline is not notified as still being in the chat room
linphone_core_set_network_reachable(marie2->lc, TRUE);
marie2Cr =
check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 1, TRUE);
// Marie2 adds Pauline back to the chat room
initialPauline1Stats = pauline1->stat;
participantsAddresses = bctbx_list_append(participantsAddresses, paulineAddr);
linphone_chat_room_add_participants(marie2Cr, participantsAddresses);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_participants_added,
3011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080
initialMarie1Stats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_participants_added,
initialMarie2Stats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added,
initialLaureStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marie1Cr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marie2Cr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 2, int, "%d");
newPauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr,
initialSubject, 2, FALSE);
BC_ASSERT_PTR_EQUAL(newPauline1Cr, pauline1Cr);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(newPauline1Cr), 2, int, "%d");
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(newPauline1Cr), initialSubject);
end:
// Clean chat room from db
linphone_core_set_network_reachable(pauline2->lc, TRUE);
linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
linphone_core_delete_chat_room(marie2->lc, marie2Cr);
initialPauline2Stats = pauline2->stat;
linphone_core_manager_delete_chat_room(pauline1, newPauline1Cr, coresList);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneConferenceStateTerminated,
initialPauline2Stats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
linphone_core_delete_chat_room(pauline2->lc, pauline2Cr);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_notify_after_disconnection(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
int dummy = 0;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_PTR_NOT_NULL(marieCr);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
3081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
BC_ASSERT_PTR_NOT_NULL(laureCr);
// Marie now changes the subject
const char *newSubject = "New subject";
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
linphone_core_set_network_reachable(pauline->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 1000);
// Marie now changes the subject
newSubject = "Let's go drink a beer";
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 2, liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 2, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 2, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_NOT_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
linphone_core_set_network_reachable(pauline->lc, TRUE);
wait_for_list(coresList, &dummy, 1, 1000);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 2, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
// Test with more than one missed notify
linphone_core_set_network_reachable(pauline->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 1000);
// Marie now changes the subject
newSubject = "Let's go drink a mineral water !";
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 3, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 3, liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 3, 3000));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_NOT_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
// Marie designates Laure as admin
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr);
LinphoneParticipant *laureParticipantFromPauline = linphone_chat_room_find_participant(paulineCr, laureAddr);
linphone_address_unref(laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
BC_ASSERT_PTR_NOT_NULL(laureParticipantFromPauline);
linphone_chat_room_set_participant_admin_status(marieCr, laureParticipant, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 1,
3151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipant));
BC_ASSERT_FALSE(linphone_participant_is_admin(laureParticipantFromPauline));
linphone_core_set_network_reachable(pauline->lc, TRUE);
wait_for_list(coresList, &dummy, 1, 1000);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 3, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipantFromPauline));
// Test with a participant being removed
linphone_core_set_network_reachable(pauline->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 1000);
// Laure leaves the room
linphone_chat_room_leave(laureCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1, 3000));
linphone_core_set_network_reachable(pauline->lc, TRUE);
wait_for_list(coresList, &dummy, 1, 1000);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_notify_after_core_restart(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
3221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_PTR_NOT_NULL(marieCr);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
BC_ASSERT_PTR_NOT_NULL(laureCr);
// Now paulines stops it's Core
coresList = bctbx_list_remove(coresList, pauline->lc);
// Make sure gruu is preserved
const char *uuid =
bctbx_strdup(linphone_config_get_string(linphone_core_get_config(pauline->lc), "misc", "uuid", NULL));
linphone_core_set_network_reachable(pauline->lc, FALSE); // to avoid unregister
linphone_core_manager_stop(pauline);
// Marie changes the subject
const char *newSubject = "New subject";
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
// Laure leaves the room
linphone_chat_room_leave(laureCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
// Pauline comes back
linphone_core_manager_reinit(pauline);
coresList = bctbx_list_append(coresList, pauline->lc);
// Make sure gruu is restored
linphone_config_set_string(linphone_core_get_config(pauline->lc), "misc", "uuid", uuid);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline);
init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
// Paulines starts it's Core again
linphone_core_manager_start(pauline, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 1, 3000));
char *deviceIdentity = linphone_core_get_device_identity(pauline->lc);
LinphoneAddress *localAddr = linphone_address_new(deviceIdentity);
bctbx_free(deviceIdentity);
paulineCr = linphone_core_find_chat_room(pauline->lc, confAddr, localAddr);
linphone_address_unref(localAddr);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
3291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_send_refer_to_all_devices(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, marie2);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialMarie2Stats = marie2->stat;
stats initialPauline1Stats = pauline1->stat;
stats initialPauline2Stats = pauline2->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on second Marie's device
LinphoneChatRoom *marieCr2 =
check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 2, TRUE);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats,
confAddr, initialSubject, 2, FALSE);
LinphoneChatRoom *paulineCr2 = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Check that added Marie's device didn't change her admin status
LinphoneAddress *marieAddr = linphone_address_new(linphone_core_get_identity(marie1->lc));
LinphoneParticipant *marieParticipant = linphone_chat_room_get_me(marieCr);
if (BC_ASSERT_PTR_NOT_NULL(marieParticipant)) BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
marieParticipant = linphone_chat_room_get_me(marieCr2);
if (BC_ASSERT_PTR_NOT_NULL(marieParticipant)) BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddr);
if (BC_ASSERT_PTR_NOT_NULL(marieParticipant)) BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
3361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430
marieParticipant = linphone_chat_room_find_participant(paulineCr2, marieAddr);
if (BC_ASSERT_PTR_NOT_NULL(marieParticipant)) BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
marieParticipant = linphone_chat_room_find_participant(laureCr, marieAddr);
if (BC_ASSERT_PTR_NOT_NULL(marieParticipant)) BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
linphone_address_unref(marieAddr);
// Marie removes Laure from the chat room
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr);
linphone_address_unref(laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
linphone_chat_room_remove_participant(marieCr, laureParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_participants_removed,
initialMarie1Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_participants_removed,
initialMarie2Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_participants_removed,
initialPauline1Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_participants_removed,
initialPauline2Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr2), 1, int, "%d");
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie1, marieCr, coresList);
linphone_core_delete_chat_room(marie2->lc, marieCr2);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline1, paulineCr, coresList);
linphone_core_delete_chat_room(pauline2->lc, paulineCr2);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_add_device(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPauline1Stats = pauline1->stat;
stats initialPauline2Stats = pauline2->stat;
3431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats,
confAddr, initialSubject, 2, FALSE);
LinphoneChatRoom *paulineCr2 = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Marie adds a new device
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
coresManagerList = bctbx_list_append(coresManagerList, marie2);
LinphoneAddress *factoryAddr = linphone_address_new(sFactoryUri);
_configure_core_for_conference(marie2, factoryAddr);
linphone_address_unref(factoryAddr);
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
linphone_core_cbs_set_chat_room_state_changed(cbs, core_chat_room_state_changed);
configure_core_for_callbacks(marie2, cbs);
linphone_core_cbs_unref(cbs);
coresList = bctbx_list_append(coresList, marie2->lc);
stats initialMarie2Stats = marie2->stat;
_start_core(marie2);
// Check that the chat room is correctly created on second Marie's device
LinphoneChatRoom *marieCr2 =
check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 2, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_participant_devices_added,
initialMarie1Stats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_participant_devices_added,
initialMarie1Stats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_participant_devices_added,
initialMarie1Stats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_devices_added,
initialMarie1Stats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
// Check that adding Marie's device didn't change her admin status
LinphoneParticipant *marieParticipant = linphone_chat_room_get_me(marieCr);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
marieParticipant = linphone_chat_room_get_me(marieCr2);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
LinphoneAddress *marieAddr = linphone_address_new(linphone_core_get_identity(marie1->lc));
marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddr);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
marieParticipant = linphone_chat_room_find_participant(paulineCr2, marieAddr);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
marieParticipant = linphone_chat_room_find_participant(laureCr, marieAddr);
BC_ASSERT_PTR_NOT_NULL(marieParticipant);
BC_ASSERT_TRUE(linphone_participant_is_admin(marieParticipant));
linphone_address_unref(marieAddr);
// Marie removes Laure from the chat room
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
3501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr);
linphone_address_unref(laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
linphone_chat_room_remove_participant(marieCr, laureParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_participants_removed,
initialMarie1Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_participants_removed,
initialMarie2Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_participants_removed,
initialPauline1Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_participants_removed,
initialPauline2Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr2), 1, int, "%d");
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie1, marieCr, coresList);
linphone_core_delete_chat_room(marie2->lc, marieCr2);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline1, paulineCr, coresList);
linphone_core_delete_chat_room(pauline2->lc, paulineCr2);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(laure);
}
static void multiple_is_composing_notification(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
const bctbx_list_t *composing_addresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
3571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Only one is composing
linphone_chat_room_compose(paulineCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived, 1,
liblinphone_tester_sip_timeout));
// Laure side
composing_addresses = linphone_chat_room_get_composing_addresses(laureCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 1, int, "%i");
if (bctbx_list_size(composing_addresses) == 1) {
LinphoneAddress *addr = (LinphoneAddress *)bctbx_list_get_data(composing_addresses);
BC_ASSERT_STRING_EQUAL(linphone_address_get_username(addr), linphone_address_get_username(pauline->identity));
}
// Marie side
composing_addresses = linphone_chat_room_get_composing_addresses(marieCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 1, int, "%i");
if (bctbx_list_size(composing_addresses) == 1) {
LinphoneAddress *addr = (LinphoneAddress *)bctbx_list_get_data(composing_addresses);
BC_ASSERT_STRING_EQUAL(linphone_address_get_username(addr), linphone_address_get_username(pauline->identity));
}
// Pauline side
composing_addresses = linphone_chat_room_get_composing_addresses(paulineCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 0, int, "%i");
wait_for_list(coresList, 0, 1, 1500);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingIdleReceived, 1,
liblinphone_tester_sip_timeout));
composing_addresses = linphone_chat_room_get_composing_addresses(marieCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 0, int, "%i");
composing_addresses = linphone_chat_room_get_composing_addresses(laureCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 0, int, "%i");
// multiple is composing
linphone_chat_room_compose(paulineCr);
linphone_chat_room_compose(marieCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingActiveReceived, 3,
liblinphone_tester_sip_timeout)); // + 2
// Laure side
composing_addresses = linphone_chat_room_get_composing_addresses(laureCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 2, int, "%i");
if (bctbx_list_size(composing_addresses) == 2) {
while (composing_addresses) {
LinphoneAddress *addr = (LinphoneAddress *)bctbx_list_get_data(composing_addresses);
bool_t equal =
strcmp(linphone_address_get_username(addr), linphone_address_get_username(pauline->identity)) == 0 ||
strcmp(linphone_address_get_username(addr), linphone_address_get_username(marie->identity)) == 0;
BC_ASSERT_TRUE(equal);
composing_addresses = bctbx_list_next(composing_addresses);
}
}
// Marie side
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingActiveReceived, 2,
liblinphone_tester_sip_timeout)); // + 1
composing_addresses = linphone_chat_room_get_composing_addresses(marieCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 1, int, "%i");
3641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710
if (bctbx_list_size(composing_addresses) == 1) {
LinphoneAddress *addr = (LinphoneAddress *)bctbx_list_get_data(composing_addresses);
BC_ASSERT_STRING_EQUAL(linphone_address_get_username(addr), linphone_address_get_username(pauline->identity));
}
// Pauline side
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingActiveReceived, 1, 2000));
composing_addresses = linphone_chat_room_get_composing_addresses(paulineCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 1, int, "%i");
if (bctbx_list_size(composing_addresses) == 1) {
LinphoneAddress *addr = (LinphoneAddress *)bctbx_list_get_data(composing_addresses);
BC_ASSERT_STRING_EQUAL(linphone_address_get_username(addr), linphone_address_get_username(marie->identity));
}
wait_for_list(coresList, 0, 1, 1500);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneIsComposingIdleReceived, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneIsComposingIdleReceived, 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneIsComposingIdleReceived, 1,
liblinphone_tester_sip_timeout));
composing_addresses = linphone_chat_room_get_composing_addresses(marieCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 0, int, "%i");
composing_addresses = linphone_chat_room_get_composing_addresses(laureCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 0, int, "%i");
composing_addresses = linphone_chat_room_get_composing_addresses(paulineCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(composing_addresses), 0, int, "%i");
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_fallback_to_basic_chat_room(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
linphone_core_remove_linphone_spec(pauline->lc, "groupchat");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
// Marie creates a new group chat room
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback", TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateInstantiated,
initialMarieStats.number_of_LinphoneConferenceStateInstantiated + 1, 100));
// Add participants
linphone_chat_room_add_participants(marieCr, participantsAddresses);
// Check that the group chat room creation fails and that a fallback to a basic chat room is done
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationPending,
initialMarieStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneConferenceStateCreationFailed,
3711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780
initialMarieStats.number_of_LinphoneConferenceStateCreationFailed, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Send a message and check that a basic chat room is created on Pauline's side
LinphoneChatMessage *msg = linphone_chat_room_create_message_from_utf8(marieCr, "Hey Pauline!");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message);
if (pauline->stat.last_received_chat_message)
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message),
"text/plain");
LinphoneChatRoom *paulineCr =
linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_local_address(marieCr));
BC_ASSERT_PTR_NOT_NULL(paulineCr);
if (paulineCr) BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesBasic);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_creation_fails_if_invited_participants_dont_support_it(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
linphone_core_remove_linphone_spec(pauline->lc, "groupchat");
linphone_core_remove_linphone_spec(laure->lc, "groupchat");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
// Marie creates a new group chat room
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Hello there", FALSE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateInstantiated,
initialMarieStats.number_of_LinphoneConferenceStateInstantiated + 1, 100));
// Add participants
linphone_chat_room_add_participants(marieCr, participantsAddresses);
// Check that the group chat room creation fails
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationPending,
initialMarieStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationFailed,
initialMarieStats.number_of_LinphoneConferenceStateCreationFailed + 1, 10000));
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
BC_ASSERT_EQUAL(linphone_chat_room_get_state(marieCr), LinphoneConferenceStateCreationFailed, int, "%d");
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
3781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_creation_successful_if_at_least_one_invited_participant_supports_it(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
linphone_core_remove_linphone_spec(laure->lc, "groupchat");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr = create_chat_room_client_side_with_expected_number_of_participants(
coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, 1, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
// Check that the chat room has not been created on Laure's side
BC_ASSERT_EQUAL(initialLaureStats.number_of_LinphoneConferenceStateCreated,
laure->stat.number_of_LinphoneConferenceStateCreated, int, "%d");
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_migrate_from_basic_chat_room(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
// Enable migration mecanism only for marie and create a basic chat room
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
linphone_core_remove_linphone_spec(marie->lc, "groupchat"); // Prevent basic chat room from migrating directly
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc",
3851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920
"enable_basic_to_client_group_chat_room_migration", 1);
LinphoneChatRoom *marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & (LinphoneChatRoomCapabilitiesMigratable));
// Send a message and check that a basic chat room is created on Pauline's side
LinphoneChatMessage *msg = linphone_chat_room_create_message_from_utf8(marieCr, "Hey Pauline!");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message);
if (pauline->stat.last_received_chat_message)
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message),
"text/plain");
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc",
"enable_basic_to_client_group_chat_room_migration", 1);
LinphoneChatRoom *paulineCr =
linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_local_address(marieCr));
BC_ASSERT_PTR_NOT_NULL(paulineCr);
if (paulineCr) {
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) &
(LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesMigratable));
}
// Enable chat room migration and restart core for Marie
_linphone_chat_room_enable_migration(marieCr, TRUE); // Will add Migratable capability to the in-db chatroom
coresList = bctbx_list_remove(coresList, marie->lc);
linphone_core_manager_reinit(marie);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc",
"enable_basic_to_client_group_chat_room_migration", 1);
linphone_core_manager_start(marie, TRUE);
marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr);
/* // Enable chat room migration and restart core for Pauline */
_linphone_chat_room_enable_migration(paulineCr, TRUE);
coresList = bctbx_list_remove(coresList, pauline->lc);
linphone_core_manager_reinit(pauline);
tmpCoresManagerList = bctbx_list_append(NULL, pauline);
tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc",
"enable_basic_to_client_group_chat_room_migration", 1);
linphone_core_manager_start(pauline, TRUE);
paulineCr = linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_local_address(marieCr));
// Send a new message to initiate chat room migration
BC_ASSERT_PTR_NOT_NULL(marieCr);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
if (marieCr && paulineCr) {
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
linphone_core_add_linphone_spec(marie->lc, "groupchat"); // Enable migration now
BC_ASSERT_EQUAL(linphone_chat_room_get_capabilities(marieCr),
LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesProxy |
LinphoneChatRoomCapabilitiesMigratable | LinphoneChatRoomCapabilitiesOneToOne,
int, "%d");
msg = linphone_chat_room_create_message_from_utf8(marieCr, "Did you migrate?");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationPending,
initialMarieStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
3921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomConferenceJoined,
initialMarieStats.number_of_LinphoneChatRoomConferenceJoined + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreationPending,
initialPaulineStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated,
initialPaulineStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomConferenceJoined,
initialPaulineStats.number_of_LinphoneChatRoomConferenceJoined + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 2, int, "%d");
msg = linphone_chat_room_create_message_from_utf8(marieCr, "Let's go drink a beer");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 3, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 3, int, "%d");
msg = linphone_chat_room_create_message_from_utf8(paulineCr, "Let's go drink mineral water instead");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 4, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 4, int, "%d");
BC_ASSERT_EQUAL((int)bctbx_list_size(linphone_core_get_chat_rooms(marie->lc)), 1, int, "%d");
BC_ASSERT_EQUAL((int)bctbx_list_size(linphone_core_get_chat_rooms(pauline->lc)), 1, int, "%d");
}
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_address_unref(paulineAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_migrate_from_basic_to_client_fail(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
int dummy = 0;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
linphone_core_remove_linphone_spec(pauline->lc, "groupchat");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
3991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060
// Marie creates a new group chat room
LinphoneChatRoom *marieCr = linphone_core_create_client_group_chat_room(marie->lc, "Fallback", TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateInstantiated,
initialMarieStats.number_of_LinphoneConferenceStateInstantiated + 1, 100));
// Add participants
linphone_chat_room_add_participants(marieCr, participantsAddresses);
// Check that the group chat room creation fails and that a fallback to a basic chat room is done
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationPending,
initialMarieStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_EQUAL(marie->stat.number_of_LinphoneConferenceStateCreationFailed,
initialMarieStats.number_of_LinphoneConferenceStateCreationFailed, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Send a message and check that a basic chat room is created on Pauline's side
LinphoneChatMessage *msg = linphone_chat_room_create_message_from_utf8(marieCr, "Hey Pauline!");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message);
if (pauline->stat.last_received_chat_message)
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message),
"text/plain");
LinphoneChatRoom *paulineCr =
linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_local_address(marieCr));
BC_ASSERT_PTR_NOT_NULL(paulineCr);
if (paulineCr) BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesBasic);
// Enable chat room migration and restart core for Marie
_linphone_chat_room_enable_migration(marieCr, TRUE);
if (marieCr) linphone_chat_room_unref(marieCr);
coresList = bctbx_list_remove(coresList, marie->lc);
linphone_core_manager_reinit(marie);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
// Send a new message to initiate chat room migration
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc",
"enable_basic_to_client_group_chat_room_migration", 1);
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc",
"basic_to_client_group_chat_room_migration_timer", 5);
linphone_core_manager_start(marie, TRUE);
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr);
linphone_address_unref(paulineAddr);
paulineCr = linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_local_address(marieCr));
BC_ASSERT_PTR_NOT_NULL(marieCr);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
if (marieCr && paulineCr) {
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
BC_ASSERT_EQUAL(linphone_chat_room_get_capabilities(marieCr),
LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesProxy |
LinphoneChatRoomCapabilitiesMigratable | LinphoneChatRoomCapabilitiesOneToOne,
int, "%d");
msg = linphone_chat_room_create_message_from_utf8(marieCr, "Did you migrate?");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationPending,
initialMarieStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
4061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d");
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreationPending,
initialPaulineStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated,
initialPaulineStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesBasic);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 2, int, "%d");
msg = linphone_chat_room_create_message_from_utf8(marieCr, "Let's go drink a beer");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 3, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 3, int, "%d");
msg = linphone_chat_room_create_message_from_utf8(paulineCr, "Let's go drink mineral water instead");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 4, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 4, int, "%d");
// Activate groupchat on Pauline's side and wait for 5 seconds, the migration should now be done on next message
// sending
_linphone_chat_room_enable_migration(paulineCr, TRUE);
coresList = bctbx_list_remove(coresList, pauline->lc);
linphone_core_manager_reinit(pauline);
tmpCoresManagerList = bctbx_list_append(NULL, pauline);
tmpCoresList = init_core_for_conference(tmpCoresManagerList);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc",
"enable_basic_to_client_group_chat_room_migration", 1);
linphone_core_add_linphone_spec(pauline->lc, "groupchat");
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline, TRUE);
paulineCr = linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_local_address(marieCr));
linphone_core_set_network_reachable(pauline->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 3000);
linphone_core_set_network_reachable(pauline->lc, TRUE);
wait_for_list(coresList, &dummy, 1, 5000);
msg = linphone_chat_room_create_message_from_utf8(marieCr, "And now, did you migrate?");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationPending,
initialMarieStats.number_of_LinphoneConferenceStateCreationPending + 2, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomConferenceJoined,
initialMarieStats.number_of_LinphoneChatRoomConferenceJoined + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 5, int, "%d");
4131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreationPending,
initialPaulineStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated,
initialPaulineStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomConferenceJoined,
initialPaulineStats.number_of_LinphoneChatRoomConferenceJoined + 1,
liblinphone_tester_sip_timeout));
if (paulineCr) {
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesConference);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 5, int, "%d");
}
}
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_donot_room_migrate_from_basic_chat_room(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
// Create a basic chat room
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
LinphoneChatRoom *marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr);
// Send a message and check that a basic chat room is created on Pauline's side
LinphoneChatMessage *msg = linphone_chat_room_create_message_from_utf8(marieCr, "Hey Pauline!");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_PTR_NOT_NULL(pauline->stat.last_received_chat_message);
if (pauline->stat.last_received_chat_message)
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_content_type(pauline->stat.last_received_chat_message),
"text/plain");
LinphoneChatRoom *paulineCr =
linphone_core_get_chat_room(pauline->lc, linphone_chat_room_get_local_address(marieCr));
BC_ASSERT_PTR_NOT_NULL(paulineCr);
if (paulineCr) BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesBasic);
// Enable chat room migration and restart core for Marie
coresList = bctbx_list_remove(coresList, marie->lc);
linphone_core_manager_restart(marie, TRUE);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie);
bctbx_list_t *coresList2 = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(coresList2);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_append(coresList, marie->lc);
// Send a new message to initiate chat room migration
marieCr = linphone_core_get_chat_room(marie->lc, paulineAddr);
BC_ASSERT_PTR_NOT_NULL(marieCr);
if (marieCr) {
4201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
BC_ASSERT_EQUAL(linphone_chat_room_get_capabilities(marieCr),
LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesOneToOne, int, "%d");
msg = linphone_chat_room_create_message_from_utf8(marieCr, "Did you migrate?");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreationPending,
initialMarieStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated,
initialMarieStats.number_of_LinphoneConferenceStateCreated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesBasic);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, "%d");
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreationPending,
initialPaulineStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated,
initialPaulineStats.number_of_LinphoneConferenceStateCreated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesBasic);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 1, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 2, int, "%d");
msg = linphone_chat_room_create_message_from_utf8(marieCr, "Let's go drink a beer");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 3, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 3, int, "%d");
msg = linphone_chat_room_create_message_from_utf8(paulineCr, "Let's go drink mineral water instead");
linphone_chat_message_send(msg);
linphone_chat_message_unref(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 4, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 4, int, "%d");
}
// Clean db from chat room
linphone_core_delete_chat_room(marie->lc, marieCr);
linphone_core_delete_chat_room(pauline->lc, paulineCr);
linphone_address_unref(paulineAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_send_file_with_or_without_text(bool_t with_text, bool_t two_files, bool_t use_buffer) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
char *sendFilepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
char *sendFilepath2 = NULL;
char *receivePaulineFilepath = bc_tester_file("receive_file_pauline.dump");
char *receiveChloeFilepath = bc_tester_file("receive_file_chloe.dump");
const char *text = "Hello Group !";
4271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340
if (two_files) {
sendFilepath2 = bc_tester_res("sounds/ahbahouaismaisbon.wav");
}
/* Globally configure an http file transfer server. */
linphone_core_set_file_transfer_server(marie->lc, file_transfer_url);
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialChloeStats = chloe->stat;
/* Remove any previously downloaded file */
remove(receivePaulineFilepath);
remove(receiveChloeFilepath);
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Chloe's side and that the participants are added
LinphoneChatRoom *chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
// Sending file
if (with_text) {
_send_file_plus_text(marieCr, sendFilepath, sendFilepath2, text, use_buffer);
} else {
_send_file(marieCr, sendFilepath, sendFilepath2, use_buffer);
}
// Check that chat rooms have received the file
if (with_text) {
_receive_file_plus_text(coresList, pauline, &initialPaulineStats, receivePaulineFilepath, sendFilepath,
sendFilepath2, text, use_buffer);
_receive_file_plus_text(coresList, chloe, &initialChloeStats, receiveChloeFilepath, sendFilepath, sendFilepath2,
text, use_buffer);
} else {
_receive_file(coresList, pauline, &initialPaulineStats, receivePaulineFilepath, sendFilepath, sendFilepath2,
use_buffer);
_receive_file(coresList, chloe, &initialChloeStats, receiveChloeFilepath, sendFilepath, sendFilepath2,
use_buffer);
}
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
remove(receivePaulineFilepath);
remove(receiveChloeFilepath);
bc_free(sendFilepath);
if (sendFilepath2) bc_free(sendFilepath2);
bc_free(receivePaulineFilepath);
bc_free(receiveChloeFilepath);
bctbx_list_free(coresList);
4341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(chloe);
}
static void group_chat_room_send_file(void) {
group_chat_room_send_file_with_or_without_text(FALSE, FALSE, FALSE);
}
static void group_chat_room_send_file_2(void) {
group_chat_room_send_file_with_or_without_text(FALSE, FALSE, TRUE);
}
static void group_chat_room_send_file_plus_text(void) {
group_chat_room_send_file_with_or_without_text(TRUE, FALSE, FALSE);
}
static void group_chat_room_send_two_files_plus_text(void) {
group_chat_room_send_file_with_or_without_text(TRUE, TRUE, FALSE);
}
static void group_chat_room_send_multipart_custom_content_types(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference_with_groupchat_version(coresManagerList, "1.0");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
// Add our custom content types
linphone_core_add_content_type_support(marie->lc, "application/vnd.3gpp.mcptt-info+xml");
linphone_core_add_content_type_support(marie->lc, "application/vnd.3gpp.mcptt-location-info+xml");
linphone_core_add_content_type_support(pauline->lc, "application/vnd.3gpp.mcptt-info+xml");
linphone_core_add_content_type_support(pauline->lc, "application/vnd.3gpp.mcptt-location-info+xml");
const char *data1 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><mcpttinfo xmlns=\"urn:3gpp:ns:mcpttInfo:1.0\" "
"xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><mcptt-Params><mcptt-request-uri "
"type=\"Normal\"><mcpttURI>sip:test@sip.example.org</mcpttURI></mcptt-request-uri></mcptt-Params></mcpttinfo>";
const char *data2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?><location-info "
"xmlns=\"urn:3gpp:ns:mcpttILocationInfo:1.0\"><Configuration><NonEmergencyLocationInformation><ServingEcgi/"
"><NeighbouringEcgi/><MbmsSaId/><MbsfnArea/><GeographicalCoordinate/><minimumIntervalLength>10</"
"minimumIntervalLength></NonEmergencyLocationInformation><TriggeringCriteria><CellChange><AnyCellChange "
"TriggerId=\"AnyCellChange\"/></CellChange><TrackingAreaChange><AnyTrackingAreaChange "
"TriggerId=\"AnyTrackingAreaChange\"/></TrackingAreaChange><PlmnChange><AnyPlmnChange "
"TriggerId=\"AnyPlmnChange\"/></PlmnChange><PeriodicReport "
"TriggerId=\"Periodic\">20</PeriodicReport><GeographicalAreaChange><AnyAreaChange "
"TriggerId=\"177db491c22\"></AnyAreaChange></GeographicalAreaChange></TriggeringCriteria></Configuration></"
"location-info>";
LinphoneChatMessage *msg;
msg = linphone_chat_room_create_empty_message(marieCr);
4411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480
LinphoneContent *content = linphone_factory_create_content(linphone_factory_get());
linphone_content_set_type(content, "application");
linphone_content_set_subtype(content, "vnd.3gpp.mcptt-info+xml");
linphone_content_set_utf8_text(content, data1);
linphone_chat_message_add_content(msg, content);
linphone_content_unref(content);
content = linphone_factory_create_content(linphone_factory_get());
linphone_content_set_type(content, "application");
linphone_content_set_subtype(content, "vnd.3gpp.mcptt-location-info+xml");
linphone_content_set_utf8_text(content, data2);
linphone_chat_message_add_content(msg, content);
linphone_content_unref(content);
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageReceived, 1));
linphone_chat_message_unref(msg);
if (pauline->stat.last_received_chat_message) {
const bctbx_list_t *contents = linphone_chat_message_get_contents(pauline->stat.last_received_chat_message);
BC_ASSERT_EQUAL((int)bctbx_list_size(contents), 2, int, "%d");
LinphoneContent *content1 = bctbx_list_get_data(contents);
BC_ASSERT_STRING_EQUAL(linphone_content_get_type(content1), "application");
BC_ASSERT_STRING_EQUAL(linphone_content_get_subtype(content1), "vnd.3gpp.mcptt-info+xml");
BC_ASSERT_STRING_EQUAL(linphone_content_get_utf8_text(content1), data1);
LinphoneContent *content2 = bctbx_list_nth_data(contents, 1);
BC_ASSERT_STRING_EQUAL(linphone_content_get_type(content2), "application");
BC_ASSERT_STRING_EQUAL(linphone_content_get_subtype(content2), "vnd.3gpp.mcptt-location-info+xml");
BC_ASSERT_STRING_EQUAL(linphone_content_get_utf8_text(content2), data2);
}
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_unique_one_to_one_chat_room_base(bool_t secondDeviceForSender) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *marie2 = NULL;
if (secondDeviceForSender) marie2 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
if (secondDeviceForSender) coresManagerList = bctbx_list_append(coresManagerList, marie2);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
/* This test was constructed according to 1.0 specification of groupchat.*/
bctbx_list_t *coresList = init_core_for_conference_with_groupchat_version(coresManagerList, "1.0");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialMarie2Stats;
memset(&initialMarie2Stats, 0, sizeof(initialMarie2Stats));
if (secondDeviceForSender) initialMarie2Stats = marie2->stat;
stats initialPaulineStats = pauline->stat;
// Marie creates a new group chat room
const char *initialSubject = "Pauline";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
4481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
const LinphoneAddress *tmpConfAddr = linphone_chat_room_get_conference_address(marieCr);
if (!tmpConfAddr) {
goto end;
}
LinphoneAddress *confAddr = linphone_address_clone(tmpConfAddr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *marie2Cr = NULL;
if (secondDeviceForSender)
marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr,
initialSubject, 1, FALSE);
// Marie sends a message
const char *textMessage = "Hello";
LinphoneChatMessage *message = _send_message(marieCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered,
initialMarieStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
if (secondDeviceForSender) linphone_core_set_network_reachable(marie2->lc, FALSE);
// Marie deletes the chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
wait_for_list(coresList, 0, 1, 2000);
BC_ASSERT_EQUAL(pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed,
int, "%d");
// Marie creates the chat room again
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
participantsAddresses = bctbx_list_append(NULL, linphone_address_new(linphone_core_get_identity(pauline->lc)));
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
// Marie sends a new message
textMessage = "Hey again";
message = _send_message(marieCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered,
initialMarieStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Check that the created address is the same as before
const LinphoneAddress *newConfAddr = linphone_chat_room_get_conference_address(marieCr);
BC_ASSERT_TRUE(linphone_address_weak_equal(confAddr, newConfAddr));
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (secondDeviceForSender) {
linphone_core_set_network_reachable(marie2->lc, TRUE);
linphone_core_delete_chat_room(marie2->lc, marie2Cr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneConferenceStateTerminated,
initialMarie2Stats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
}
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
4551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620
linphone_address_unref(confAddr);
end:
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
if (secondDeviceForSender) linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_unique_one_to_one_chat_room(void) {
group_chat_room_unique_one_to_one_chat_room_base(FALSE);
}
static void group_chat_room_unique_one_to_one_chat_room_dual_sender_device(void) {
group_chat_room_unique_one_to_one_chat_room_base(TRUE);
}
static void group_chat_room_unique_one_to_one_chat_room_with_forward_message_recreated_from_message_base(
bool_t with_app_restart, bool_t forward_message, bool_t reply_message) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
/* This test checks the behavior of 1.0 groupchat protocol version, where one-to-one chatroom were supposed to be
* unique. */
bctbx_list_t *coresList = init_core_for_conference_with_groupchat_version(coresManagerList, "1.0");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
char *messageId, *secondMessageId = NULL;
// Marie creates a new group chat room
const char *initialSubject = "Pauline";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr));
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
// Marie sends a message
const char *textMessage = "Hello";
LinphoneChatMessage *message = _send_message(marieCr, textMessage);
const bctbx_list_t *contents = linphone_chat_message_get_contents(message);
BC_ASSERT_EQUAL((int)bctbx_list_size(contents), 1, int, "%d");
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered,
initialMarieStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
messageId = bctbx_strdup(linphone_chat_message_get_message_id(message));
linphone_chat_message_unref(message);
if (forward_message) {
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 1, int, " %i");
if (linphone_chat_room_get_history_size(paulineCr) > 0) {
bctbx_list_t *history = linphone_chat_room_get_history(paulineCr, 1);
4621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690
LinphoneChatMessage *recv_msg = (LinphoneChatMessage *)(history->data);
LinphoneChatMessage *msg = linphone_chat_room_create_forward_message(paulineCr, recv_msg);
const LinphoneAddress *forwarded_from_address = linphone_chat_message_get_from_address(recv_msg);
char *forwarded_from = linphone_address_as_string_uri_only(forwarded_from_address);
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(linphone_chat_message_is_forward(msg));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_forward_info(msg), forwarded_from);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDelivered, 1));
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
BC_ASSERT_PTR_NOT_NULL(marie->stat.last_received_chat_message);
if (marie->stat.last_received_chat_message != NULL) {
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, " %i");
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message),
textMessage);
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text_content(marie->stat.last_received_chat_message),
textMessage);
BC_ASSERT_TRUE(linphone_chat_message_is_forward(marie->stat.last_received_chat_message));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_forward_info(marie->stat.last_received_chat_message),
forwarded_from);
}
linphone_chat_message_unref(msg);
ms_free(forwarded_from);
}
} else if (reply_message) {
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 1, int, " %i");
if (linphone_chat_room_get_history_size(paulineCr) > 0) {
bctbx_list_t *history = linphone_chat_room_get_history(paulineCr, 1);
LinphoneChatMessage *recv_msg = (LinphoneChatMessage *)(history->data);
LinphoneChatMessage *msg = linphone_chat_room_create_reply_message(paulineCr, recv_msg);
BC_ASSERT_TRUE(linphone_chat_message_is_reply(msg));
const char *replyId = linphone_chat_message_get_reply_message_id(msg);
BC_ASSERT_STRING_EQUAL(replyId, messageId);
linphone_chat_message_add_utf8_text_content(msg, "Quite funny!");
BC_ASSERT_TRUE(linphone_address_weak_equal(linphone_chat_message_get_reply_message_sender_address(msg),
linphone_chat_message_get_from_address(recv_msg)));
LinphoneChatMessage *orig = linphone_chat_message_get_reply_message(msg);
BC_ASSERT_PTR_NOT_NULL(orig);
BC_ASSERT_PTR_EQUAL(orig, recv_msg);
if (orig) {
const char *reply = linphone_chat_message_get_utf8_text(orig);
BC_ASSERT_STRING_EQUAL(reply, "Hello");
linphone_chat_message_unref(orig);
}
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &pauline->stat.number_of_LinphoneMessageDelivered, 1));
BC_ASSERT_TRUE(wait_for(pauline->lc, marie->lc, &marie->stat.number_of_LinphoneMessageReceived, 1));
BC_ASSERT_PTR_NOT_NULL(marie->stat.last_received_chat_message);
if (marie->stat.last_received_chat_message != NULL) {
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, " %i");
4691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message),
"Quite funny!");
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text_content(marie->stat.last_received_chat_message),
"Quite funny!");
BC_ASSERT_TRUE(linphone_chat_message_is_reply(marie->stat.last_received_chat_message));
BC_ASSERT_STRING_EQUAL(
linphone_chat_message_get_reply_message_id(marie->stat.last_received_chat_message), messageId);
BC_ASSERT_TRUE(linphone_address_weak_equal(linphone_chat_message_get_reply_message_sender_address(msg),
linphone_chat_room_get_local_address(marieCr)));
}
secondMessageId = bctbx_strdup(linphone_chat_message_get_message_id(msg));
linphone_chat_message_unref(msg);
}
}
if (with_app_restart) {
// To simulate dialog removal
LinphoneAddress *marieAddr = linphone_address_clone(linphone_chat_room_get_peer_address(marieCr));
linphone_core_set_network_reachable(marie->lc, FALSE);
coresList = bctbx_list_remove(coresList, marie->lc);
linphone_core_manager_reinit(marie);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(marie, TRUE);
marieCr = linphone_core_get_chat_room(marie->lc, marieAddr);
linphone_address_unref(marieAddr);
}
if (forward_message) {
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, " %i");
if (linphone_chat_room_get_history_size(marieCr) > 1) {
LinphoneChatMessage *recv_msg = linphone_chat_room_get_last_message_in_history(marieCr);
BC_ASSERT_TRUE(linphone_chat_message_is_forward(recv_msg));
// for marie, forward message by anonymous
LinphoneChatMessage *msgFromMarie = linphone_chat_room_create_forward_message(marieCr, recv_msg);
linphone_chat_message_send(msgFromMarie);
BC_ASSERT_TRUE(linphone_chat_message_is_forward(msgFromMarie));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_forward_info(msgFromMarie), "Anonymous");
linphone_chat_message_unref(msgFromMarie);
linphone_chat_message_unref(recv_msg);
}
} else if (reply_message) {
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(marieCr), 2, int, " %i");
if (linphone_chat_room_get_history_size(marieCr) > 1) {
LinphoneChatMessage *recv_msg = linphone_chat_room_get_last_message_in_history(marieCr);
const char *body = linphone_chat_message_get_utf8_text(recv_msg);
BC_ASSERT_STRING_EQUAL(body, "Quite funny!");
BC_ASSERT_TRUE(linphone_chat_message_is_reply(recv_msg));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_reply_message_id(recv_msg), messageId);
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_message_id(recv_msg), secondMessageId);
LinphoneChatMessage *orig = linphone_chat_message_get_reply_message(recv_msg);
BC_ASSERT_PTR_NOT_NULL(orig);
if (orig) {
const char *reply = linphone_chat_message_get_utf8_text(orig);
BC_ASSERT_STRING_EQUAL(reply, "Hello");
linphone_chat_message_unref(orig);
}
LinphoneChatMessage *msgFromMarie = linphone_chat_room_create_reply_message(marieCr, recv_msg);
BC_ASSERT_TRUE(linphone_address_weak_equal(linphone_chat_message_get_reply_message_sender_address(recv_msg),
linphone_chat_message_get_from_address(msgFromMarie)));
4761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830
BC_ASSERT_TRUE(linphone_chat_message_is_reply(msgFromMarie));
linphone_chat_message_add_utf8_text_content(msgFromMarie, "Still laughing!");
linphone_chat_message_send(msgFromMarie);
linphone_chat_message_unref(msgFromMarie);
linphone_chat_message_unref(recv_msg);
}
} else {
// Marie deletes the chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
wait_for_list(coresList, 0, 1, 2000);
BC_ASSERT_EQUAL(pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed, int, "%d");
// Pauline sends a new message
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
// Pauline sends a new message
textMessage = "Hey you";
message = _send_message(paulineCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered,
initialPaulineStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Check that the chat room has been correctly recreated on Marie's side
marieCr = check_creation_chat_room_client_side(coresList, marie, &initialMarieStats, confAddr, initialSubject,
1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
}
if (messageId) bc_free(messageId);
if (secondMessageId) bc_free(secondMessageId);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
wait_for_list(coresList, 0, 1, 2000);
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int, "%i");
BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(marie->lc));
BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(pauline->lc));
linphone_address_unref(confAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_base(bool_t with_app_restart) {
group_chat_room_unique_one_to_one_chat_room_with_forward_message_recreated_from_message_base(with_app_restart,
FALSE, FALSE);
}
static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message(void) {
group_chat_room_unique_one_to_one_chat_room_recreated_from_message_base(FALSE);
}
static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_with_app_restart(void) {
group_chat_room_unique_one_to_one_chat_room_recreated_from_message_base(TRUE);
}
4831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900
static void group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
// Create a second device for Marie, but it is inactive after registration in this test
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
// Create a second device for Pauline, but again inactivate it after registration
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, marie2);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
bctbx_list_t *coresList = init_core_for_conference_with_groupchat_version(coresManagerList, "1.0");
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialMarie2Stats = marie2->stat;
stats initialPauline2Stats = pauline2->stat;
linphone_core_set_network_reachable(marie2->lc, FALSE);
linphone_core_set_network_reachable(pauline2->lc, FALSE);
// Marie creates a new group chat room
const char *initialSubject = "Pauline";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr));
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
// Marie sends a message
const char *textMessage = "Hello";
LinphoneChatMessage *message = _send_message(marieCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered,
initialMarieStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Marie deletes the chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
wait_for_list(coresList, 0, 1, 2000);
BC_ASSERT_EQUAL(pauline->stat.number_of_participants_removed, initialPaulineStats.number_of_participants_removed,
int, "%d");
// Marie sends a new message
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
// Check that the chat room has been correctly recreated on Marie's side
marieCr =
check_creation_chat_room_client_side(coresList, marie, &initialMarieStats, confAddr, initialSubject, 1, FALSE);
4901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970
if (BC_ASSERT_PTR_NOT_NULL(marieCr)) {
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
textMessage = "Hey you";
message = _send_message(marieCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageDelivered,
initialMarieStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
}
// Clean db from chat room
linphone_core_set_network_reachable(marie2->lc, TRUE);
linphone_core_set_network_reachable(pauline2->lc, TRUE);
LinphoneChatRoom *paulineCr2 = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats,
confAddr, initialSubject, 1, FALSE);
LinphoneChatRoom *marieCr2 = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr,
initialSubject, 1, FALSE);
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_core_manager_delete_chat_room(marie2, marieCr2, coresList);
linphone_core_manager_delete_chat_room(pauline2, paulineCr2, coresList);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateTerminated,
initialMarieStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateTerminated,
initialPaulineStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneConferenceStateTerminated,
initialMarie2Stats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneConferenceStateTerminated,
initialPauline2Stats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int, "%i");
BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(marie->lc));
BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(pauline->lc));
linphone_address_unref(confAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline2);
}
static void group_chat_room_join_one_to_one_chat_room_with_a_new_device(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
bctbx_list_t *participantsAddresses =
bctbx_list_append(NULL, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPaulineStats = pauline->stat;
// Marie1 creates a new one-to-one chat room with Pauline
const char *initialSubject = "Pauline";
LinphoneChatRoom *marie1Cr =
4971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040
create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marie1Cr) & LinphoneChatRoomCapabilitiesOneToOne);
LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marie1Cr));
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
// Marie1 sends a message
const char *textMessage = "Hello";
LinphoneChatMessage *message = _send_message(marie1Cr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageDelivered,
initialMarie1Stats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Pauline answers to the previous message
textMessage = "Hey. How are you?";
message = _send_message(paulineCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered,
initialPaulineStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneMessageReceived,
initialMarie1Stats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie1->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Simulate an uninstall of the application on Marie's side
linphone_core_set_network_reachable(marie1->lc, FALSE);
coresManagerList = bctbx_list_remove(coresManagerList, marie1);
coresList = bctbx_list_remove(coresList, marie1->lc);
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
stats initialMarie2Stats = marie2->stat;
bctbx_list_t *newCoresManagerList = bctbx_list_append(NULL, marie2);
bctbx_list_t *newCoresList = init_core_for_conference(newCoresManagerList);
start_core_for_conference(newCoresManagerList);
coresManagerList = bctbx_list_concat(coresManagerList, newCoresManagerList);
coresList = bctbx_list_concat(coresList, newCoresList);
// Marie2 gets the one-to-one chat room with Pauline
LinphoneChatRoom *marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr,
initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marie2Cr) & LinphoneChatRoomCapabilitiesOneToOne);
// Marie2 sends a new message
textMessage = "Fine and you?";
message = _send_message(marie2Cr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageDelivered,
initialMarie2Stats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Pauline answers to the previous message
textMessage = "Perfect!";
message = _send_message(paulineCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered,
initialPaulineStats.number_of_LinphoneMessageDelivered + 2,
liblinphone_tester_sip_timeout));
5041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived,
initialMarie2Stats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie2->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Clean db from chat room
int previousNbRegistrationOk = marie1->stat.number_of_LinphoneRegistrationOk;
linphone_core_set_network_reachable(marie1->lc, TRUE);
wait_for_until(marie1->lc, NULL, &marie1->stat.number_of_LinphoneRegistrationOk, previousNbRegistrationOk + 1,
2000);
linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList);
linphone_core_delete_chat_room(marie1->lc, marie1Cr);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_address_unref(confAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference_with_groupchat_version(coresManagerList, "1.0");
;
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
// Marie creates a new group chat room
const char *initialSubject = "Pauline";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
LinphoneAddress *firstConfAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr));
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
firstConfAddr, initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
// Both participants delete the chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
wait_for_list(coresList, 0, 1, 3000);
// Marie re-creates a chat room with Pauline
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marieCr) & LinphoneChatRoomCapabilitiesOneToOne);
LinphoneAddress *secondConfAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr));
// Check that the chat room has been correctly recreated on Marie's side
5111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, secondConfAddr,
initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
/* firstconfAddr and secondConfAddr must differ */
BC_ASSERT_FALSE(linphone_address_equal(firstConfAddr, secondConfAddr));
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_address_unref(firstConfAddr);
linphone_address_unref(secondConfAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void imdn_for_group_chat_room(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
LinphoneChatRoom *marieCr = NULL, *marie2Cr = NULL, *paulineCr = NULL, *chloeCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
coresManagerList = bctbx_list_append(coresManagerList, marie2);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialChloeStats = chloe->stat;
stats initialMarie2Stats = marie2->stat;
time_t initialTime = ms_time(NULL);
// Enable IMDN
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie2->lc));
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Chloe's side and that the participants are added
chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(chloeCr)) goto end;
marie2Cr =
5181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250
check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 2, TRUE);
if (!BC_ASSERT_PTR_NOT_NULL(marie2Cr)) goto end;
// Chloe begins composing a message
const char *chloeTextMessage = "Hello";
LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived,
initialMarie2Stats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageSent, 1, 1000));
LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end;
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage);
LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg)));
linphone_address_unref(chloeAddr);
// Check that the message has been delivered to Marie and Pauline
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser,
initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed));
bctbx_list_t *participantsThatReceivedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 2, int, "%d");
for (bctbx_list_t *item = participantsThatReceivedChloeMessage; item; item = bctbx_list_next(item)) {
LinphoneParticipantImdnState *state = (LinphoneParticipantImdnState *)bctbx_list_get_data(item);
BC_ASSERT_GREATER((int)linphone_participant_imdn_state_get_state_change_time(state), (int)initialTime, int,
"%d");
BC_ASSERT_EQUAL(linphone_participant_imdn_state_get_state(state), LinphoneChatMessageStateDeliveredToUser,
int, "%d");
BC_ASSERT_PTR_NOT_NULL(linphone_participant_imdn_state_get_participant(state));
}
bctbx_list_free_with_data(participantsThatReceivedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered));
// Marie marks the message as read, check that the state is not yet displayed on Chloe's side
linphone_chat_room_mark_as_read(marieCr);
BC_ASSERT_FALSE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed,
initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 0, 1000));
bctbx_list_t *participantsThatDisplayedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatDisplayedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatDisplayedChloeMessage), 1, int, "%d");
bctbx_list_free_with_data(participantsThatDisplayedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
participantsThatReceivedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 1, int, "%d");
bctbx_list_free_with_data(participantsThatReceivedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered));
5251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered));
// Marie2 should have received marie's Display IMDN, causing it's own chatroom to be marked as read as well
// automatically
BC_ASSERT_EQUAL(linphone_chat_room_get_unread_messages_count(marie2Cr), 0, int, "%d");
// Pauline also marks the message as read, check that the state is now displayed on Chloe's side
linphone_chat_room_mark_as_read(paulineCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed,
initialChloeStats.number_of_LinphoneMessageDisplayed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 0, 1000));
participantsThatDisplayedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatDisplayedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatDisplayedChloeMessage), 2, int, "%d");
bctbx_list_free_with_data(participantsThatDisplayedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered));
linphone_chat_message_unref(chloeMessage);
end:
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (chloeCr) linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
if (marie2Cr) linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(chloe);
}
static void imdn_updated_for_group_chat_room_with_one_participant_offline(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *chloeCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialChloeStats = chloe->stat;
// Enable IMDN
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc));
5321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Chloe's side and that the participants are added
chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(chloeCr)) goto end;
// pauline offline
linphone_core_set_network_reachable(pauline->lc, FALSE);
// Chloe begins composing a message
const char *chloeTextMessage = "Hello";
LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageSent, 1, 1000));
LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end;
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage);
LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg)));
linphone_address_unref(chloeAddr);
// Check that the message has been delivered to Marie
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDelivered,
initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1,
liblinphone_tester_sip_timeout));
bctbx_list_t *participantsThatReceivedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 1, int, "%d");
bctbx_list_free_with_data(participantsThatReceivedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
// Check that the message has been sent to Pauline
bctbx_list_t *participantsThatSentChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatSentChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatSentChloeMessage), 1, int, "%d");
bctbx_list_free_with_data(participantsThatSentChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered));
// Marie marks the message as read
linphone_chat_room_mark_as_read(marieCr);
BC_ASSERT_FALSE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed,
initialChloeStats.number_of_LinphoneMessageDisplayed + 1, 3000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 0, 1000));
// Check that the message has beed displayed by Marie
bctbx_list_t *participantsThatDisplayedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatDisplayedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatDisplayedChloeMessage), 1, int, "%d");
5391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460
bctbx_list_free_with_data(participantsThatDisplayedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
// Check that the message has been sent to Pauline
participantsThatSentChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatSentChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatSentChloeMessage), 1, int, "%d");
bctbx_list_free_with_data(participantsThatSentChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered));
// Check that the message state is Delivered
BC_ASSERT_TRUE(linphone_chat_message_get_state(chloeMessage) == LinphoneChatMessageStateDelivered);
// set appData will trigger update db
linphone_chat_message_set_appdata(chloeMessage, "");
// Check that the message has beed displayed by Marie
participantsThatDisplayedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatDisplayedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatDisplayedChloeMessage), 1, int, "%d");
bctbx_list_free_with_data(participantsThatDisplayedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
// Check that the message has been sent to Pauline
participantsThatSentChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatSentChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatSentChloeMessage), 1, int, "%d");
bctbx_list_free_with_data(participantsThatSentChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered));
// Check that the message state is Delivered
BC_ASSERT_TRUE(linphone_chat_message_get_state(chloeMessage) == LinphoneChatMessageStateDelivered);
linphone_chat_message_unref(chloeMessage);
end:
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (chloeCr) linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(chloe);
}
static void aggregated_imdn_for_group_chat_room_base(bool_t read_while_offline) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
LinphoneCoreManager *chloe2 = linphone_core_manager_create("chloe_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *chloeCr = NULL, *chloe2Cr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
5461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
coresManagerList = bctbx_list_append(coresManagerList, chloe2);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialChloeStats = chloe->stat;
stats initialChloe2Stats = chloe2->stat;
bctbx_list_t *chloeMessages = NULL, *chloe2Messages = NULL, *chloe2DisplayedMessages = NULL;
stats chloeMessagesStats = {0}, chloe2MessagesStats = {0}, chloe2DisplayedMessagesStats = {0};
int messageCount = 0;
// Enable IMDN
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe2->lc));
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Chloe's side and that the participants are added
chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(chloeCr)) goto end;
// Check that the chat room is correctly created on Chloe2's side and that the participants are added
chloe2Cr = check_creation_chat_room_client_side(coresList, chloe2, &initialChloe2Stats, confAddr, initialSubject, 2,
FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(chloe2Cr)) goto end;
// Chloe begins composing a message
const char *chloeTextMessage = "Hello";
const char *chloeTextMessage2 = "Long time no talk";
const char *chloeTextMessage3 = "How are you?";
LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage);
LinphoneChatMessage *chloeMessage2 = _send_message(chloeCr, chloeTextMessage2);
LinphoneChatMessage *chloeMessage3 = _send_message(chloeCr, chloeTextMessage3);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe2->stat.number_of_LinphoneMessageReceived,
initialChloe2Stats.number_of_LinphoneMessageReceived + 3,
liblinphone_tester_sip_timeout));
LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end;
LinphoneChatMessage *chloe2LastMsg = chloe2->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(chloe2LastMsg)) goto end;
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage3);
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(chloe2LastMsg), chloeTextMessage3);
LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg)));
linphone_address_unref(chloeAddr);
5531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600
// Mark as read on Chloe and Chloe2 should not impact the message status
linphone_chat_room_mark_as_read(chloeCr);
linphone_chat_room_mark_as_read(chloe2Cr);
// Mark the messages as read on Marie's sides
linphone_chat_room_mark_as_read(marieCr);
wait_for_list(coresList, 0, 1, 2000);
// Get Chloe2 messages and use them to set callbacks. Check callback status and messages status
chloe2Messages = liblinphone_tester_get_messages_and_states(
chloe2Cr, &messageCount, &chloe2MessagesStats); // Do not unref chloe2Messages to keep callbacks
if (!BC_ASSERT_PTR_NOT_NULL(chloe2Messages)) goto end;
for (bctbx_list_t *elem = chloe2Messages; elem != NULL; elem = bctbx_list_next(elem))
linphone_chat_message_cbs_set_msg_state_changed(
linphone_chat_message_get_callbacks((LinphoneChatMessage *)elem->data),
liblinphone_tester_chat_message_msg_state_changed);
// All participants didn't read messages yet (only Marie) : number_of_LinphoneMessageDisplayed == displayedCount
BC_ASSERT_EQUAL(chloe->stat.number_of_LinphoneMessageDisplayed,
initialChloeStats.number_of_LinphoneMessageDisplayed, int, "%d");
BC_ASSERT_EQUAL(chloe2->stat.number_of_LinphoneMessageDisplayed,
initialChloe2Stats.number_of_LinphoneMessageDisplayed, int, "%d");
BC_ASSERT_EQUAL(chloe2MessagesStats.number_of_LinphoneMessageDisplayed, 0, int, "%d");
BC_ASSERT_EQUAL(messageCount, 3, int, "%d");
// Mark the messages as read on Pauline's sides
if (read_while_offline) {
linphone_core_set_network_reachable(pauline->lc, FALSE);
linphone_chat_room_mark_as_read(paulineCr);
wait_for_list(coresList, 0, 1, 2000);
linphone_core_set_network_reachable(pauline->lc, TRUE);
} else {
linphone_chat_room_mark_as_read(paulineCr);
}
// Messages have been read
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDisplayed,
initialChloeStats.number_of_LinphoneMessageDisplayed + 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe2->stat.number_of_LinphoneMessageDisplayed,
initialChloe2Stats.number_of_LinphoneMessageDisplayed + 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(chloe->stat.number_of_LinphoneMessageDeliveredToUser, 3, int, "%d"); // 3 for sending to chloe2
if (read_while_offline) {
wait_for_list(coresList, 0, 1, 2000); // To prevent memory leak
}
wait_for_list(coresList, 0, 1, 2000);
// Test internal data on Chloe2 and check consistency between callback and messages
chloe2DisplayedMessages =
liblinphone_tester_get_messages_and_states(chloe2Cr, &messageCount, &chloe2DisplayedMessagesStats);
BC_ASSERT_EQUAL(chloe2DisplayedMessagesStats.number_of_LinphoneMessageDisplayed, 3, int,
"%d"); // All messages have been read
BC_ASSERT_EQUAL(messageCount, 3, int, "%d");
// Test internal data on Chloe
chloeMessages = liblinphone_tester_get_messages_and_states(chloeCr, &messageCount, &chloeMessagesStats);
if (!BC_ASSERT_PTR_NOT_NULL(chloeMessages)) goto end;
BC_ASSERT_EQUAL(chloeMessagesStats.number_of_LinphoneMessageDisplayed, 3, int, "%d"); // All messages have been read
BC_ASSERT_EQUAL(messageCount, 3, int, "%d");
linphone_chat_message_unref(chloeMessage3);
linphone_chat_message_unref(chloeMessage2);
linphone_chat_message_unref(chloeMessage);
end:
if (chloeMessages) bctbx_list_free_with_data(chloeMessages, (bctbx_list_free_func)linphone_chat_message_unref);
if (chloe2Messages) bctbx_list_free_with_data(chloe2Messages, (bctbx_list_free_func)linphone_chat_message_unref);
if (chloe2DisplayedMessages)
bctbx_list_free_with_data(chloe2DisplayedMessages, (bctbx_list_free_func)linphone_chat_message_unref);
5601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (chloeCr) linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
if (chloe2Cr) linphone_core_manager_delete_chat_room(chloe2, chloe2Cr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(chloe);
linphone_core_manager_destroy(chloe2);
}
static void aggregated_imdn_for_group_chat_room(void) {
aggregated_imdn_for_group_chat_room_base(FALSE);
}
static void aggregated_imdn_for_group_chat_room_read_while_offline(void) {
aggregated_imdn_for_group_chat_room_base(TRUE);
}
static void imdn_sent_from_db_state(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *chloeCr = NULL;
LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialChloeStats = chloe->stat;
time_t initialTime = ms_time(NULL);
// Enable IMDN except for Marie
linphone_im_notif_policy_clear(linphone_core_get_im_notif_policy(marie->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(pauline->lc));
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(chloe->lc));
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = (LinphoneAddress *)linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
confAddr = linphone_address_clone(confAddr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Chloe's side and that the participants are added
chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(chloeCr)) goto end;
// Chloe begins composing a message
5671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740
const char *chloeTextMessage = "Hello";
LinphoneChatMessage *chloeMessage = _send_message(chloeCr, chloeTextMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived,
initialMarieStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
LinphoneChatMessage *marieLastMsg = marie->stat.last_received_chat_message;
if (!BC_ASSERT_PTR_NOT_NULL(marieLastMsg)) goto end;
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marieLastMsg), chloeTextMessage);
LinphoneAddress *chloeAddr = linphone_address_new(linphone_core_get_identity(chloe->lc));
BC_ASSERT_TRUE(linphone_address_weak_equal(chloeAddr, linphone_chat_message_get_from_address(marieLastMsg)));
linphone_address_unref(chloeAddr);
// Check that the message is not globally marked as delivered to user since Marie do not notify its delivery
BC_ASSERT_FALSE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser,
initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1, 3000));
// Restart Marie's core with IMDN enabled so that delivery notification is sent when chat room is loaded from DB
coresList = bctbx_list_remove(coresList, marie->lc);
linphone_core_manager_reinit(marie);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_im_notif_policy_enable_all(linphone_core_get_im_notif_policy(marie->lc));
linphone_core_manager_start(marie, TRUE);
char *marieIdentity = linphone_core_get_device_identity(marie->lc);
LinphoneAddress *marieAddr = linphone_address_new(marieIdentity);
bctbx_free(marieIdentity);
marieCr = linphone_core_find_chat_room(marie->lc, confAddr, marieAddr);
linphone_address_unref(marieAddr);
// Check that the message has been delivered to Marie and Pauline
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneMessageDeliveredToUser,
initialChloeStats.number_of_LinphoneMessageDeliveredToUser + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDisplayed));
bctbx_list_t *participantsThatReceivedChloeMessage =
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDeliveredToUser);
if (BC_ASSERT_PTR_NOT_NULL(participantsThatReceivedChloeMessage)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(participantsThatReceivedChloeMessage), 2, int, "%d");
for (bctbx_list_t *item = participantsThatReceivedChloeMessage; item; item = bctbx_list_next(item)) {
LinphoneParticipantImdnState *state = (LinphoneParticipantImdnState *)bctbx_list_get_data(item);
BC_ASSERT_GREATER((int)linphone_participant_imdn_state_get_state_change_time(state), (int)initialTime, int,
"%d");
BC_ASSERT_EQUAL(linphone_participant_imdn_state_get_state(state), LinphoneChatMessageStateDeliveredToUser,
int, "%d");
BC_ASSERT_PTR_NOT_NULL(linphone_participant_imdn_state_get_participant(state));
}
bctbx_list_free_with_data(participantsThatReceivedChloeMessage,
(bctbx_list_free_func)linphone_participant_imdn_state_unref);
}
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateDelivered));
BC_ASSERT_PTR_NULL(
linphone_chat_message_get_participants_by_imdn_state(chloeMessage, LinphoneChatMessageStateNotDelivered));
linphone_chat_message_unref(chloeMessage);
end:
if (confAddr) linphone_address_unref(confAddr);
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (chloeCr) linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
5741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(chloe);
}
static void find_one_to_one_chat_room(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *chloeCr = NULL, *marieOneToOneCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(chloe->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialChloeStats = chloe->stat;
// Only to be used in linphone_core_find_one_to_one_chatroom(...);
const LinphoneAddress *marieAddr =
linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(marie->lc));
const LinphoneAddress *paulineAddr =
linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc));
LinphoneChatMessage *basicMessage = NULL;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Chloe's side and that the participants are added
chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(chloeCr)) goto end;
// Chloe leave the chat room
linphone_chat_room_leave(chloeCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneConferenceStateTerminationPending,
initialChloeStats.number_of_LinphoneConferenceStateTerminationPending + 1, 100));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_LinphoneConferenceStateTerminated,
initialChloeStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
LinphoneChatRoom *oneToOneChatRoom = linphone_core_find_one_to_one_chat_room(marie->lc, marieAddr, paulineAddr);
BC_ASSERT_PTR_NULL(oneToOneChatRoom);
// Marie create a one to one chat room with Pauline
participantsAddresses = NULL;
5811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
marieOneToOneCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses,
"one to one", FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieOneToOneCr);
LinphoneChatRoom *paulineOneToOneCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, "one to one", 1, FALSE);
// Marie creates a basic chat room with Pauline
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
LinphoneChatRoomParams *params = linphone_core_create_default_chat_room_params(marie->lc);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendBasic);
linphone_chat_room_params_enable_group(params, FALSE);
LinphoneChatRoom *basicCR = linphone_core_create_chat_room_6(marie->lc, params, marieAddr, participantsAddresses);
linphone_chat_room_params_unref(params);
// Check it returns the One-To-One chat room (flexisip based)
oneToOneChatRoom = linphone_core_find_one_to_one_chat_room(marie->lc, marieAddr, paulineAddr);
BC_ASSERT_PTR_NOT_NULL(oneToOneChatRoom);
BC_ASSERT_PTR_EQUAL(oneToOneChatRoom, marieOneToOneCr);
// Check it returns the Basic chat room
oneToOneChatRoom = linphone_core_search_chat_room(marie->lc, NULL, marieAddr, paulineAddr, NULL);
BC_ASSERT_PTR_NOT_NULL(oneToOneChatRoom);
BC_ASSERT_PTR_EQUAL(oneToOneChatRoom, basicCR);
// Check it returns the Basic chat room
params = linphone_core_create_default_chat_room_params(marie->lc);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendBasic);
oneToOneChatRoom = linphone_core_search_chat_room(marie->lc, params, marieAddr, NULL, participantsAddresses);
BC_ASSERT_PTR_NOT_NULL(oneToOneChatRoom);
BC_ASSERT_PTR_EQUAL(oneToOneChatRoom, basicCR);
// Check it returns the One-To-One chat room (flexisip based)
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
oneToOneChatRoom = linphone_core_search_chat_room(marie->lc, params, marieAddr, NULL, participantsAddresses);
BC_ASSERT_PTR_NOT_NULL(oneToOneChatRoom);
BC_ASSERT_PTR_EQUAL(oneToOneChatRoom, marieOneToOneCr);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
linphone_chat_room_params_unref(params);
// Clean the db
linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineOneToOneCr, coresList);
marieOneToOneCr = NULL;
paulineOneToOneCr = NULL;
// Check cleaning went well
oneToOneChatRoom = linphone_core_find_one_to_one_chat_room(marie->lc, marieAddr, paulineAddr);
BC_ASSERT_PTR_NOT_NULL(oneToOneChatRoom);
BC_ASSERT_PTR_EQUAL(oneToOneChatRoom, basicCR);
if (basicCR) linphone_chat_room_unref(basicCR);
end:
// Clean db from chat room
if (basicMessage) linphone_chat_message_unref(basicMessage);
if (marieOneToOneCr) linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (chloeCr) linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
5881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(chloe);
}
static void exhume_one_to_one_chat_room_1(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneChatRoom *marieOneToOneCr = NULL, *paulineOneToOneCr = NULL;
LinphoneAddress *confAddr = NULL, *exhumedConfAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
marieOneToOneCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses,
"one to one", FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr)) goto end;
confAddr = linphone_address_clone((LinphoneAddress *)linphone_chat_room_get_conference_address(marieOneToOneCr));
paulineOneToOneCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr,
"one to one", 1, FALSE);
LinphoneChatMessage *message =
linphone_chat_room_create_message_from_utf8(paulineOneToOneCr, "Do. Or do not. There is no try.");
linphone_chat_message_send(message);
BC_ASSERT_TRUE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(
wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 1, liblinphone_tester_sip_timeout));
linphone_chat_message_unref(message);
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
if (marieOneToOneCr) {
linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneConferenceStateTerminated,
1, liblinphone_tester_sip_timeout));
/* The chatroom from Pauline is expected to terminate as well */
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc,
&pauline->stat.number_of_LinphoneConferenceStateTerminated, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
bctbx_list_t *participants = linphone_chat_room_get_participants(paulineOneToOneCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(participants), 1, int, "%d");
bctbx_list_free_with_data(participants, (bctbx_list_free_func)linphone_participant_unref);
LinphoneChatMessage *exhume_message =
linphone_chat_room_create_message_from_utf8(paulineOneToOneCr, "No. I am your father.");
linphone_chat_message_send(exhume_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 2, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 2,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(exhume_message);
5951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020
exhumedConfAddr =
linphone_address_ref((LinphoneAddress *)linphone_chat_room_get_conference_address(paulineOneToOneCr));
BC_ASSERT_PTR_NOT_NULL(exhumedConfAddr);
int pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
BC_ASSERT_EQUAL(pauline_messages, 2, int, "%d");
if (exhumedConfAddr) {
BC_ASSERT_FALSE(linphone_address_weak_equal(confAddr, exhumedConfAddr));
marieOneToOneCr = check_creation_chat_room_client_side(coresList, marie, &initialMarieStats,
exhumedConfAddr, "one to one", 1, FALSE);
BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr);
if (marieOneToOneCr) {
int marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 1, int, "%d");
LinphoneChatMessage *exhume_answer_message =
linphone_chat_room_create_message_from_utf8(marieOneToOneCr, "Nooooooooooooo !");
linphone_chat_message_send(exhume_answer_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(exhume_answer_message);
}
}
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *pauline_chat_rooms = linphone_core_get_chat_rooms(pauline->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(pauline_chat_rooms), 1, int, "%d");
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *marie_chat_rooms = linphone_core_get_chat_rooms(marie->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(marie_chat_rooms), 1, int, "%d");
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
}
end:
if (confAddr) linphone_address_unref(confAddr);
if (exhumedConfAddr) linphone_address_unref(exhumedConfAddr);
if (marieOneToOneCr) linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
if (paulineOneToOneCr) linphone_core_manager_delete_chat_room(pauline, paulineOneToOneCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void exhume_one_to_one_chat_room_2(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneChatRoom *marieOneToOneCr = NULL, *paulineOneToOneCr = NULL;
LinphoneAddress *confAddr = NULL, *exhumedConfAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
6021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
marieOneToOneCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses,
"one to one", FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr)) goto end;
confAddr = linphone_address_clone((LinphoneAddress *)linphone_chat_room_get_conference_address(marieOneToOneCr));
paulineOneToOneCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr,
"one to one", 1, FALSE);
LinphoneChatMessage *message =
linphone_chat_room_create_message_from_utf8(paulineOneToOneCr, "Help me, Obi-Wan Kenobi. You’re my only hope.");
linphone_chat_message_send(message);
BC_ASSERT_TRUE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(
wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 1, liblinphone_tester_sip_timeout));
linphone_chat_message_unref(message);
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
if (marieOneToOneCr) {
linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneConferenceStateTerminated,
1, liblinphone_tester_sip_timeout));
/* The chatroom from Pauline is expected to terminate as well */
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc,
&pauline->stat.number_of_LinphoneConferenceStateTerminated, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
participantsAddresses = NULL;
initialMarieStats = marie->stat;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
marieOneToOneCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses,
"one to one", FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneConferenceStateCreated, 2, 5000);
if (!BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr)) goto end;
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomConferenceJoined, 2,
liblinphone_tester_sip_timeout));
exhumedConfAddr =
linphone_address_clone((LinphoneAddress *)linphone_chat_room_get_conference_address(marieOneToOneCr));
BC_ASSERT_PTR_NOT_NULL(exhumedConfAddr);
if (exhumedConfAddr) {
BC_ASSERT_FALSE(linphone_address_weak_equal(confAddr, exhumedConfAddr));
LinphoneAddress *paulineNewConfAddr =
linphone_address_ref((LinphoneAddress *)linphone_chat_room_get_conference_address(paulineOneToOneCr));
BC_ASSERT_FALSE(linphone_address_weak_equal(confAddr, paulineNewConfAddr));
BC_ASSERT_TRUE(linphone_address_weak_equal(exhumedConfAddr, paulineNewConfAddr));
if (paulineNewConfAddr) linphone_address_unref(paulineNewConfAddr);
LinphoneChatMessage *exhume_message =
linphone_chat_room_create_message_from_utf8(marieOneToOneCr, "I find your lack of faith disturbing.");
linphone_chat_message_send(exhume_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1,
liblinphone_tester_sip_timeout));
6091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160
linphone_chat_message_unref(exhume_message);
int pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
BC_ASSERT_EQUAL(pauline_messages, 2, int, "%d");
int marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 1, int, "%d");
LinphoneChatRoom *paulineOneToOneCr2 = check_creation_chat_room_client_side(
coresList, pauline, &initialPaulineStats, exhumedConfAddr, "one to one", 1, FALSE);
BC_ASSERT_PTR_NOT_NULL(paulineOneToOneCr2);
if (paulineOneToOneCr2) {
int pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr2);
BC_ASSERT_EQUAL(pauline_messages, 2, int, "%d");
LinphoneChatMessage *exhume_answer_message = linphone_chat_room_create_message_from_utf8(
paulineOneToOneCr2, "Your focus determines your reality.");
linphone_chat_message_send(exhume_answer_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 2,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(exhume_answer_message);
}
}
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *pauline_chat_rooms = linphone_core_get_chat_rooms(pauline->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(pauline_chat_rooms), 1, int, "%d");
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *marie_chat_rooms = linphone_core_get_chat_rooms(marie->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(marie_chat_rooms), 1, int, "%d");
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
}
end:
if (confAddr) linphone_address_unref(confAddr);
if (exhumedConfAddr) linphone_address_unref(exhumedConfAddr);
if (marieOneToOneCr) linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
if (paulineOneToOneCr) linphone_core_manager_delete_chat_room(pauline, paulineOneToOneCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void linphone_tester_chat_room_exhumed(LinphoneCore *core, BCTBX_UNUSED(LinphoneChatRoom *room)) {
stats *counters;
counters = get_stats(core);
counters->number_of_LinphoneChatRoomExhumed++;
}
static void exhume_one_to_one_chat_room_3_base(bool_t core_restart) {
// WARNING: some waits are supposed to timeout in this test: the BC_ASSER_FALSE(wait_for...), do not increase the
// value or it triggers a timeout on the server side
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = NULL;
LinphoneChatRoom *marieOneToOneCr = NULL, *pauline2OneToOneCr = NULL, *paulineOneToOneCr = NULL;
int marie_messages = 0, pauline_messages = 0, pauline2_messages = 0;
LinphoneAddress *confAddr = NULL, *exhumedConfAddr = NULL;
6161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
char *conference_address_str = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
const char *initialSubject = "one to one";
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
marieOneToOneCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses,
initialSubject, FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr)) goto end;
confAddr = linphone_address_ref((LinphoneAddress *)linphone_chat_room_get_conference_address(marieOneToOneCr));
BC_ASSERT_PTR_NOT_NULL(confAddr);
conference_address_str = (confAddr) ? linphone_address_as_string(confAddr) : ms_strdup("<unknown>");
paulineOneToOneCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr,
initialSubject, 1, FALSE);
LinphoneChatMessage *message =
linphone_chat_room_create_message_from_utf8(paulineOneToOneCr, "Hasta la vista, baby.");
linphone_chat_message_send(message);
BC_ASSERT_TRUE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(
wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 1, liblinphone_tester_sip_timeout));
linphone_chat_message_unref(message);
marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 1, int, "%d");
pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
BC_ASSERT_EQUAL(pauline_messages, 1, int, "%d");
// Pauline goes offline
int dummy = 0;
wait_for_list(coresList, &dummy, 1, 5000); // Ensures 200 OK of the NOTIFY has been ACK'ed
ms_message("%s goes offline", linphone_core_get_identity(pauline->lc));
linphone_core_set_network_reachable(pauline->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 2000);
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
if (marieOneToOneCr) {
pauline2 = linphone_core_manager_create("pauline_rc");
stats initialPauline2Stats = pauline2->stat;
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline2);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
start_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
pauline2OneToOneCr = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats, confAddr,
initialSubject, 1, FALSE);
BC_ASSERT_PTR_NOT_NULL(pauline2OneToOneCr);
if (!pauline2OneToOneCr) goto end;
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneMessageReceived, 2, 5000));
6231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300
LinphoneChatMessage *offline_message =
linphone_chat_room_create_message_from_utf8(marieOneToOneCr, "I'll be back.");
linphone_chat_message_send(offline_message);
BC_ASSERT_TRUE(
wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 1, liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1, 5000));
linphone_chat_message_unref(offline_message);
// The other device using Pauline's account received the message as she was online
pauline2_messages = linphone_chat_room_get_history_size(pauline2OneToOneCr);
BC_ASSERT_EQUAL(pauline2_messages, 1, int, "%d");
marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 2, int, "%d");
pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
BC_ASSERT_EQUAL(pauline_messages, 1, int, "%d");
ms_message("%s is deleting chat room %s", linphone_core_get_identity(marie->lc), conference_address_str);
linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneConferenceStateTerminated,
1, liblinphone_tester_sip_timeout));
/* The chatroom from Pauline won't be terminated as it is offline */
BC_ASSERT_FALSE(wait_for_until(marie->lc, pauline->lc,
&pauline->stat.number_of_LinphoneConferenceStateTerminated, 1, 5000));
participantsAddresses = NULL;
initialMarieStats = marie->stat;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
ms_message("%s is exhuming chat room %s", linphone_core_get_identity(marie->lc), conference_address_str);
marieOneToOneCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
wait_for_until(marie->lc, NULL, &marie->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout);
if (!BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr)) goto end;
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated, 2, 5000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomConferenceJoined, 2, 5000));
exhumedConfAddr =
linphone_address_ref((LinphoneAddress *)linphone_chat_room_get_conference_address(marieOneToOneCr));
BC_ASSERT_PTR_NOT_NULL(exhumedConfAddr);
if (exhumedConfAddr) {
LinphoneChatMessage *exhume_message =
linphone_chat_room_create_message_from_utf8(marieOneToOneCr, "I'm back.");
linphone_chat_message_send(exhume_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 2, 5000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneMessageReceived, 2,
liblinphone_tester_sip_timeout));
marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 1, int, "%d");
pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
BC_ASSERT_EQUAL(pauline_messages, 1, int, "%d");
pauline2_messages = linphone_chat_room_get_history_size(pauline2OneToOneCr);
BC_ASSERT_EQUAL(pauline2_messages, 2, int, "%d");
linphone_chat_message_unref(exhume_message);
if (core_restart) {
ms_message("%s is restarting its core", linphone_core_get_identity(pauline->lc));
6301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370
coresList = bctbx_list_remove(coresList, pauline->lc);
linphone_core_manager_reinit(pauline);
// Make sure conference factory URI is preserved
LinphoneProxyConfig *lpc = linphone_core_get_default_proxy_config(pauline->lc);
linphone_proxy_config_edit(lpc);
linphone_proxy_config_set_conference_factory_uri(lpc, sFactoryUri);
linphone_proxy_config_done(lpc);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline);
init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
linphone_core_cbs_set_chat_room_exhumed(cbs, linphone_tester_chat_room_exhumed);
linphone_core_add_callbacks(pauline->lc, cbs);
linphone_core_manager_start(pauline, TRUE);
coresList = bctbx_list_append(coresList, pauline->lc);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomExhumed, 1,
liblinphone_tester_sip_timeout));
paulineOneToOneCr = linphone_core_get_chat_room(pauline->lc, exhumedConfAddr);
BC_ASSERT_EQUAL((int)linphone_chat_room_get_previouses_conference_ids_count(paulineOneToOneCr), 1, int,
"%d");
linphone_core_cbs_unref(cbs);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateTerminated, 1, 5000));
BC_ASSERT_EQUAL((int)linphone_chat_room_get_previouses_conference_ids_count(paulineOneToOneCr), 0, int,
"%d");
} else {
// Pauline goes back online
ms_message("%s comes back online", linphone_core_get_identity(pauline->lc));
linphone_core_set_network_reachable(pauline->lc, TRUE);
BC_ASSERT_FALSE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated, 2, 5000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomConferenceJoined, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateTerminated, 1, 5000));
}
pauline2_messages = linphone_chat_room_get_history_size(pauline2OneToOneCr);
BC_ASSERT_EQUAL(pauline2_messages, 2, int, "%d");
pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
BC_ASSERT_EQUAL(pauline_messages, 3, int, "%d");
marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 1, int, "%d");
LinphoneChatMessage *post_exhume_message =
linphone_chat_room_create_message_from_utf8(marieOneToOneCr, "Sarah Connor ?");
linphone_chat_message_send(post_exhume_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_LinphoneMessageReceived, 3,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(post_exhume_message);
pauline2_messages = linphone_chat_room_get_history_size(pauline2OneToOneCr);
BC_ASSERT_EQUAL(pauline2_messages, 3, int, "%d");
pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
6371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440
BC_ASSERT_EQUAL(pauline_messages, 4, int, "%d");
marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 2, int, "%d");
}
linphone_config_set_int(linphone_core_get_config(pauline2->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline2->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *pauline2_chat_rooms = linphone_core_get_chat_rooms(pauline2->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(pauline2_chat_rooms), 1, int, "%d");
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *pauline_chat_rooms = linphone_core_get_chat_rooms(pauline->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(pauline_chat_rooms), 1, int, "%d");
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *marie_chat_rooms = linphone_core_get_chat_rooms(marie->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(marie_chat_rooms), 1, int, "%d");
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
}
end:
if (confAddr) linphone_address_unref(confAddr);
if (exhumedConfAddr) linphone_address_unref(exhumedConfAddr);
if (marieOneToOneCr) linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
if (paulineOneToOneCr) linphone_core_manager_delete_chat_room(pauline, paulineOneToOneCr, coresList);
if (conference_address_str) ms_free(conference_address_str);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(pauline2);
}
static void exhume_one_to_one_chat_room_3(void) {
exhume_one_to_one_chat_room_3_base(FALSE);
}
static void exhume_one_to_one_chat_room_3_core_restart(void) {
exhume_one_to_one_chat_room_3_base(TRUE);
}
static void exhume_one_to_one_chat_room_4(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneChatRoom *marieOneToOneCr = NULL, *paulineOneToOneCr = NULL;
LinphoneAddress *confAddr = NULL, *exhumedConfAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
marieOneToOneCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses,
6441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510
"one to one", FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr)) goto end;
confAddr = linphone_address_clone((LinphoneAddress *)linphone_chat_room_get_conference_address(marieOneToOneCr));
paulineOneToOneCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr,
"one to one", 1, FALSE);
LinphoneChatMessage *message = linphone_chat_room_create_message_from_utf8(
paulineOneToOneCr,
"There is only one Lord of the Ring, only one who can bend it to his will. And he does not share power.");
linphone_chat_message_send(message);
BC_ASSERT_TRUE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(
wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 1, liblinphone_tester_sip_timeout));
linphone_chat_message_unref(message);
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
if (marieOneToOneCr) {
linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneConferenceStateTerminated,
1, liblinphone_tester_sip_timeout));
/* The chatroom from Pauline is expected to terminate as well */
BC_ASSERT_TRUE(wait_for_until(marie->lc, pauline->lc,
&pauline->stat.number_of_LinphoneConferenceStateTerminated, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
bctbx_list_t *participants = linphone_chat_room_get_participants(paulineOneToOneCr);
BC_ASSERT_EQUAL((int)bctbx_list_size(participants), 1, int, "%d");
bctbx_list_free_with_data(participants, (bctbx_list_free_func)linphone_participant_unref);
// Marie goes offline
int dummy = 0;
linphone_core_set_network_reachable(marie->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 2000);
LinphoneChatMessage *exhume_message = linphone_chat_room_create_message_from_utf8(
paulineOneToOneCr, "I am Gandalf the White. And I come back to you now... at the turn of the tide.");
linphone_chat_message_send(exhume_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(
wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageSent, 2, liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 2,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(exhume_message);
exhumedConfAddr =
linphone_address_ref((LinphoneAddress *)linphone_chat_room_get_conference_address(paulineOneToOneCr));
BC_ASSERT_PTR_NOT_NULL(exhumedConfAddr);
int pauline_messages = linphone_chat_room_get_history_size(paulineOneToOneCr);
BC_ASSERT_EQUAL(pauline_messages, 2, int, "%d");
// Marie goes back online
linphone_core_set_network_reachable(marie->lc, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateCreated, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomConferenceJoined, 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, 2,
liblinphone_tester_sip_timeout));
if (exhumedConfAddr) {
BC_ASSERT_FALSE(linphone_address_weak_equal(confAddr, exhumedConfAddr));
6511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580
marieOneToOneCr = check_creation_chat_room_client_side(coresList, marie, &initialMarieStats,
exhumedConfAddr, "one to one", 1, FALSE);
BC_ASSERT_PTR_NOT_NULL(marieOneToOneCr);
if (marieOneToOneCr) {
int marie_messages = linphone_chat_room_get_history_size(marieOneToOneCr);
BC_ASSERT_EQUAL(marie_messages, 1, int, "%d");
LinphoneChatMessage *exhume_answer_message = linphone_chat_room_create_message_from_utf8(
marieOneToOneCr, "In my experience there is no such thing as luck.");
linphone_chat_message_send(exhume_answer_message);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageSent, 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, 1,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(exhume_answer_message);
}
}
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *pauline_chat_rooms = linphone_core_get_chat_rooms(pauline->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(pauline_chat_rooms), 1, int, "%d");
linphone_config_set_int(linphone_core_get_config(marie->lc), "misc", "hide_empty_chat_rooms", 0);
linphone_config_set_int(linphone_core_get_config(pauline->lc), "misc", "hide_chat_rooms_from_removed_proxies",
0);
const bctbx_list_t *marie_chat_rooms = linphone_core_get_chat_rooms(marie->lc);
BC_ASSERT_EQUAL((int)bctbx_list_size(marie_chat_rooms), 1, int, "%d");
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(marieOneToOneCr));
BC_ASSERT_FALSE(linphone_chat_room_is_read_only(paulineOneToOneCr));
}
end:
if (confAddr) linphone_address_unref(confAddr);
if (exhumedConfAddr) linphone_address_unref(exhumedConfAddr);
if (marieOneToOneCr) linphone_core_manager_delete_chat_room(marie, marieOneToOneCr, coresList);
if (paulineOneToOneCr) linphone_core_manager_delete_chat_room(pauline, paulineOneToOneCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_room_new_device_after_creation(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneCoreManager *marie2 = NULL;
LinphoneChatRoom *marie1Cr = NULL, *marie2Cr = NULL, *pauline1Cr = NULL, *pauline2Cr = NULL, *laureCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPauline1Stats = pauline1->stat;
stats initialPauline2Stats = pauline2->stat;
stats initialLaureStats = laure->stat;
6581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marie1Cr = create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses,
initialSubject, FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marie1Cr)) goto end;
participantsAddresses = NULL;
confAddr = linphone_chat_room_get_conference_address(marie1Cr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are
// added
pauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr,
initialSubject, 2, FALSE);
pauline2Cr = check_creation_chat_room_client_side(coresList, pauline2, &initialPauline2Stats, confAddr,
initialSubject, 2, FALSE);
if (!(BC_ASSERT_PTR_NOT_NULL(pauline1Cr) && BC_ASSERT_PTR_NOT_NULL(pauline2Cr))) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(laureCr)) goto end;
// Marie adds a new device
marie2 = linphone_core_manager_create("marie_rc");
stats initialMarie2Stats = marie2->stat;
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, marie2);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
start_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
marie2Cr =
check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 2, TRUE);
if (!BC_ASSERT_PTR_NOT_NULL(marie2Cr)) goto end;
end:
// Clean db from chat room
if (marie1Cr) linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
if (marie2Cr) linphone_core_delete_chat_room(marie2->lc, marie2Cr);
if (pauline1Cr) linphone_core_manager_delete_chat_room(pauline1, pauline1Cr, coresList);
if (pauline2Cr) linphone_core_delete_chat_room(pauline2->lc, pauline2Cr);
if (laureCr) linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie1);
if (marie2) linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_list_subscription(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneChatRoom *marieCr1 = NULL, *marieCr2 = NULL, *marieCr3 = NULL;
LinphoneChatRoom *paulineCr1 = NULL, *paulineCr2 = NULL, *paulineCr3 = NULL;
LinphoneChatRoom *laureCr1 = NULL, *laureCr2 = NULL, *laureCr3 = NULL;
const LinphoneAddress *confAddr1 = NULL, *confAddr2 = NULL, *confAddr3 = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
start_core_for_conference(coresManagerList);
6651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
int dummy = 0;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr1 = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr1)) goto end;
confAddr1 = linphone_chat_room_get_conference_address(marieCr1);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr1)) goto end;
// Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are
// added
paulineCr1 = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr1,
initialSubject, 2, FALSE);
laureCr1 =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr1, initialSubject, 2, FALSE);
if (!(BC_ASSERT_PTR_NOT_NULL(paulineCr1) && BC_ASSERT_PTR_NOT_NULL(laureCr1))) goto end;
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
initialLaureStats = laure->stat;
// Marie creates a new group chat room
initialSubject = "Friends";
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
marieCr2 = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr2)) goto end;
confAddr2 = linphone_chat_room_get_conference_address(marieCr2);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr2)) goto end;
// Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are
// added
paulineCr2 = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr2,
initialSubject, 2, FALSE);
laureCr2 =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr2, initialSubject, 2, FALSE);
if (!(BC_ASSERT_PTR_NOT_NULL(paulineCr2) && BC_ASSERT_PTR_NOT_NULL(laureCr2))) goto end;
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
initialLaureStats = laure->stat;
// Marie creates a new group chat room
initialSubject = "Bros";
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
marieCr3 = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr3)) goto end;
confAddr3 = linphone_chat_room_get_conference_address(marieCr3);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr3)) goto end;
// Check that the chat room is correctly created on Pauline1 and Pauline2's sides and that the participants are
// added
paulineCr3 = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr3,
initialSubject, 2, FALSE);
laureCr3 =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr3, initialSubject, 2, FALSE);
if (!(BC_ASSERT_PTR_NOT_NULL(paulineCr3) && BC_ASSERT_PTR_NOT_NULL(laureCr3))) goto end;
6721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790
participantsAddresses = NULL;
// Marie designates Pauline as admin in chat room 1
LinphoneAddress *paulineAddr = linphone_address_new(linphone_core_get_identity(pauline->lc));
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr1, paulineAddr);
linphone_address_unref(paulineAddr);
BC_ASSERT_PTR_NOT_NULL(paulineParticipant);
linphone_chat_room_set_participant_admin_status(marieCr1, paulineParticipant, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(paulineParticipant));
// Pauline's device goes off
paulineAddr = linphone_address_clone(linphone_chat_room_get_local_address(paulineCr1));
coresList = bctbx_list_remove(coresList, pauline->lc);
linphone_core_set_network_reachable(pauline->lc, FALSE);
wait_for_list(coresList, &dummy, 1, 1000);
// Marie designates Laure as admin in chat rooms 1 & 3
LinphoneAddress *laureAddr = linphone_address_new(linphone_core_get_identity(laure->lc));
LinphoneParticipant *laureParticipant1 = linphone_chat_room_find_participant(marieCr1, laureAddr);
LinphoneParticipant *laureParticipant2 = linphone_chat_room_find_participant(marieCr2, laureAddr);
LinphoneParticipant *laureParticipant3 = linphone_chat_room_find_participant(marieCr3, laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipant1);
BC_ASSERT_PTR_NOT_NULL(laureParticipant2);
BC_ASSERT_PTR_NOT_NULL(laureParticipant3);
linphone_chat_room_set_participant_admin_status(marieCr1, laureParticipant1, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 2, 3000));
BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipant1));
linphone_chat_room_set_participant_admin_status(marieCr3, laureParticipant3, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_admin_statuses_changed,
initialMarieStats.number_of_participant_admin_statuses_changed + 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 3,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 3, 3000));
BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipant3));
// Marie now changes the subject or chat room 1
const char *newSubject = "New subject";
linphone_chat_room_set_subject(marieCr1, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 1, 3000));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr1), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr1), newSubject);
// Pauline is back
linphone_core_manager_reinit(pauline);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
6791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline, TRUE);
paulineCr1 = linphone_core_find_chat_room(pauline->lc, confAddr1, paulineAddr);
paulineCr2 = linphone_core_find_chat_room(pauline->lc, confAddr2, paulineAddr);
paulineCr3 = linphone_core_find_chat_room(pauline->lc, confAddr3, paulineAddr);
BC_ASSERT_PTR_NOT_NULL(paulineCr1);
BC_ASSERT_PTR_NOT_NULL(paulineCr2);
BC_ASSERT_PTR_NOT_NULL(paulineCr3);
linphone_address_unref(paulineAddr);
LinphoneParticipant *laureParticipantOfPauline1 = linphone_chat_room_find_participant(paulineCr1, laureAddr);
LinphoneParticipant *laureParticipantOfPauline2 = linphone_chat_room_find_participant(paulineCr2, laureAddr);
LinphoneParticipant *laureParticipantOfPauline3 = linphone_chat_room_find_participant(paulineCr3, laureAddr);
BC_ASSERT_PTR_NOT_NULL(laureParticipantOfPauline1);
BC_ASSERT_PTR_NOT_NULL(laureParticipantOfPauline2);
BC_ASSERT_PTR_NOT_NULL(laureParticipantOfPauline3);
linphone_address_unref(laureAddr);
wait_for_list(coresList, &dummy, 1, 5000);
// Check that Pauline receive the missing info and not more
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipantOfPauline1));
BC_ASSERT_TRUE(linphone_participant_is_admin(laureParticipantOfPauline3));
BC_ASSERT_FALSE(linphone_participant_is_admin(laureParticipantOfPauline2));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 1, 10000));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr1), newSubject);
// Check that Pauline can still receive info once back
// Marie now changes the subject or chat room 1
newSubject = "New New subject";
linphone_chat_room_set_subject(marieCr1, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 2, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 2, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 2, 10000));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr1), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr1), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr1), newSubject);
// Marie now changes the subject or chat room 2
newSubject = "Newer subject";
linphone_chat_room_set_subject(marieCr2, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 3, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 3, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 3, 10000));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr2), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr2), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr2), newSubject);
// Marie now changes the subject or chat room 3
newSubject = "Newest subject";
linphone_chat_room_set_subject(marieCr3, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 4, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 4, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
initialPaulineStats.number_of_subject_changed + 4, 10000));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr3), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr3), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr3), newSubject);
end:
// Clean db from chat room
6861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930
if (marieCr1) linphone_core_manager_delete_chat_room(marie, marieCr1, coresList);
if (paulineCr1) linphone_core_manager_delete_chat_room(pauline, paulineCr1, coresList);
if (laureCr1) linphone_core_manager_delete_chat_room(laure, laureCr1, coresList);
if (marieCr2) linphone_core_manager_delete_chat_room(marie, marieCr2, coresList);
if (paulineCr2) linphone_core_manager_delete_chat_room(pauline, paulineCr2, coresList);
if (laureCr2) linphone_core_manager_delete_chat_room(laure, laureCr2, coresList);
if (marieCr3) linphone_core_manager_delete_chat_room(marie, marieCr3, coresList);
if (paulineCr3) linphone_core_manager_delete_chat_room(pauline, paulineCr3, coresList);
if (laureCr3) linphone_core_manager_delete_chat_room(laure, laureCr3, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_complex_participant_removal_scenario(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *newLaureCr = NULL;
const LinphoneAddress *confAddr = NULL;
LinphoneAddress *laureDeviceAddress;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
participantsAddresses = NULL;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Restart Laure core
linphone_core_set_network_reachable(laure->lc, FALSE);
LinphoneAddress *laureAddr = linphone_address_clone(laure->identity);
coresList = bctbx_list_remove(coresList, laure->lc);
linphone_core_manager_reinit(laure);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(laure, TRUE);
initialLaureStats = laure->stat;
// Marie removes Laure from the chat room
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddr);
6931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000
BC_ASSERT_PTR_NOT_NULL(laureParticipant);
linphone_chat_room_remove_participant(marieCr, laureParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
wait_for_list(coresList, 0, 1, 2000);
initialLaureStats = laure->stat;
linphone_proxy_config_refresh_register(linphone_core_get_default_proxy_config(laure->lc));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneRegistrationOk,
initialLaureStats.number_of_LinphoneRegistrationOk + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1, 3000));
// Marie adds Laure to the chat room
participantsAddresses = bctbx_list_append(participantsAddresses, laureAddr);
linphone_chat_room_add_participants(marieCr, participantsAddresses);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added,
initialMarieStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added,
initialPaulineStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateCreationPending,
initialLaureStats.number_of_LinphoneConferenceStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateCreated,
initialLaureStats.number_of_LinphoneConferenceStateCreated + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomConferenceJoined,
initialLaureStats.number_of_LinphoneChatRoomConferenceJoined + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marieCr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(paulineCr), 2, int, "%d");
char *laureIdentity = linphone_core_get_device_identity(laure->lc);
laureDeviceAddress = linphone_address_new(laureIdentity);
bctbx_free(laureIdentity);
newLaureCr = linphone_core_find_chat_room(laure->lc, confAddr, laureDeviceAddress);
if (!BC_ASSERT_PTR_NOT_NULL(newLaureCr)) goto end;
linphone_address_unref(laureDeviceAddress);
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(newLaureCr), 2, int, "%d");
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(newLaureCr), initialSubject);
BC_ASSERT_FALSE(linphone_chat_room_has_been_left(newLaureCr));
unsigned int nbLaureConferenceCreatedEventsBeforeRestart = 0;
bctbx_list_t *laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0);
for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) {
LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item);
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated)
nbLaureConferenceCreatedEventsBeforeRestart++;
}
bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref);
BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsBeforeRestart, 2, unsigned int, "%u");
initialLaureStats = laure->stat;
linphone_proxy_config_refresh_register(linphone_core_get_default_proxy_config(laure->lc));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneRegistrationOk,
initialLaureStats.number_of_LinphoneRegistrationOk + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_LinphoneChatRoomConferenceJoined,
initialLaureStats.number_of_LinphoneChatRoomConferenceJoined + 1, 3000));
BC_ASSERT_FALSE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateTerminated,
initialLaureStats.number_of_LinphoneConferenceStateTerminated + 1, 3000));
unsigned int nbLaureConferenceCreatedEventsAfterRestart = 0;
7001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070
laureHistory = linphone_chat_room_get_history_events(newLaureCr, 0);
for (bctbx_list_t *item = laureHistory; item; item = bctbx_list_next(item)) {
LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(item);
if (linphone_event_log_get_type(event) == LinphoneEventLogTypeConferenceCreated)
nbLaureConferenceCreatedEventsAfterRestart++;
}
bctbx_list_free_with_data(laureHistory, (bctbx_list_free_func)linphone_event_log_unref);
BC_ASSERT_EQUAL(nbLaureConferenceCreatedEventsAfterRestart, nbLaureConferenceCreatedEventsBeforeRestart,
unsigned int, "%u");
end:
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (newLaureCr) linphone_core_manager_delete_chat_room(laure, newLaureCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_subscription_denied(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *laureCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
LinphoneAddress *paulineAddress = linphone_address_new(linphone_core_get_identity(pauline->lc));
start_core_for_conference(coresManagerList);
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_ref(paulineAddress));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(laureCr)) goto end;
// Simulate pauline has disconnected
linphone_core_set_network_reachable(pauline->lc, FALSE);
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr, paulineAddress);
BC_ASSERT_PTR_NOT_NULL(paulineParticipant);
linphone_chat_room_remove_participant(marieCr, paulineParticipant);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
7071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140
initialMarieStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_removed,
initialLaureStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
// Reconnect pauline
linphone_core_set_network_reachable(pauline->lc, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneConferenceStateTerminated,
initialPaulineStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
end:
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (laureCr) linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_address_unref(paulineAddress);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void search_friend_chat_room_participants(void) {
LinphoneMagicSearch *magicSearch = NULL;
bctbx_list_t *resultList = NULL;
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *laureCr = NULL;
const LinphoneAddress *confAddr = NULL;
LinphoneProxyConfig *laurePC = linphone_core_get_default_proxy_config(laure->lc);
LinphoneProxyConfig *mariePC = linphone_core_get_default_proxy_config(marie->lc);
const LinphoneAddress *laureIdentity = linphone_proxy_config_get_identity_address(laurePC);
const LinphoneAddress *marieIdentity = linphone_proxy_config_get_identity_address(mariePC);
char *laureI = linphone_address_as_string_uri_only(laureIdentity);
char *marieI = linphone_address_as_string_uri_only(marieIdentity);
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline's side and that the participants are added
7141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(laureCr)) goto end;
magicSearch = linphone_magic_search_new(pauline->lc);
resultList = linphone_magic_search_get_contact_list_from_filter(magicSearch, "", "");
if (BC_ASSERT_PTR_NOT_NULL(resultList)) {
BC_ASSERT_EQUAL((int)bctbx_list_size(resultList), 2, int, "%d");
_check_friend_result_list_2(pauline->lc, resultList, 0, laureI, NULL, LinphoneMagicSearchSourceChatRooms);
_check_friend_result_list_2(pauline->lc, resultList, 1, marieI, NULL, LinphoneMagicSearchSourceChatRooms);
bctbx_list_free_with_data(resultList, (bctbx_list_free_func)linphone_magic_search_unref);
}
ms_free(laureI);
ms_free(marieI);
linphone_magic_search_reset_search_cache(magicSearch);
linphone_magic_search_unref(magicSearch);
end:
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (laureCr) linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
linphone_core_manager_destroy(chloe);
}
static void group_chat_room_participant_devices_name(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneCoreManager *chloe = linphone_core_manager_create("chloe_rc");
LinphoneCoreManager *chloe2 = linphone_core_manager_create("chloe_rc");
LinphoneCoreManager *chloe3 = linphone_core_manager_create("chloe_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
coresManagerList = bctbx_list_append(coresManagerList, laure);
coresManagerList = bctbx_list_append(coresManagerList, chloe);
coresManagerList = bctbx_list_append(coresManagerList, chloe2);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
linphone_core_set_user_agent(marie->lc, "blabla (Marie device) blibli/blublu (bloblo)", NULL);
linphone_core_set_user_agent(pauline->lc, "blabla (Pauline device 1) blibli/blublu (bloblo)", NULL);
linphone_core_set_user_agent(pauline2->lc, "blabla (Pauline device 2) blibli/blublu (bloblo)", NULL);
linphone_core_set_user_agent(laure->lc, "(Laure device ((toto) tata) (titi)) (bloblo)", NULL);
linphone_core_set_user_agent(chloe->lc, "blabla (Chloe device 1) blibli/blublu (bloblo)", NULL);
linphone_core_set_user_agent(chloe2->lc, "blabla (Chloe device 2) blibli/blublu (bloblo)", NULL);
start_core_for_conference(coresManagerList);
LinphoneAddress *marieAddress = linphone_address_new(linphone_core_get_identity(marie->lc));
LinphoneAddress *paulineAddress =
linphone_address_ref(linphone_address_new(linphone_core_get_identity(pauline->lc)));
LinphoneAddress *laureAddress = linphone_address_ref(linphone_address_new(linphone_core_get_identity(laure->lc)));
LinphoneAddress *chloeAddress = linphone_address_new(linphone_core_get_identity(chloe->lc));
LinphoneAddress *marieDeviceAddress =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(marie->lc)));
LinphoneAddress *paulineDeviceAddress1 =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(pauline->lc)));
7211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280
LinphoneAddress *paulineDeviceAddress2 =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(pauline2->lc)));
LinphoneAddress *laureDeviceAddress =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(laure->lc)));
LinphoneAddress *chloeDeviceAddress1 =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(chloe->lc)));
LinphoneAddress *chloeDeviceAddress2 =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(chloe2->lc)));
participantsAddresses = bctbx_list_append(participantsAddresses, paulineAddress);
participantsAddresses = bctbx_list_append(participantsAddresses, laureAddress);
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialPaulineStats2 = pauline2->stat;
stats initialLaureStats = laure->stat;
stats initialChloeStats = chloe->stat;
stats initialChloeStats2 = chloe2->stat;
stats initialChloeStats3 = chloe3->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
LinphoneAddress *confAddr = linphone_address_clone(linphone_chat_room_get_conference_address(marieCr));
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr2 = check_creation_chat_room_client_side(coresList, pauline2, &initialPaulineStats2,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Check device's name in Marie's chat room
LinphoneParticipant *marieParticipant = linphone_chat_room_get_me(marieCr);
LinphoneParticipant *paulineParticipant = linphone_chat_room_find_participant(marieCr, paulineAddress);
LinphoneParticipant *laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddress);
LinphoneParticipantDevice *marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
LinphoneParticipantDevice *paulineDevice =
linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
LinphoneParticipantDevice *paulineDevice2 =
linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
LinphoneParticipantDevice *laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
// Check device's name in Pauline1's chat room
marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddress);
paulineParticipant = linphone_chat_room_get_me(paulineCr);
laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
// Check device's name in Pauline2's chat room
marieParticipant = linphone_chat_room_find_participant(paulineCr2, marieAddress);
paulineParticipant = linphone_chat_room_get_me(paulineCr2);
laureParticipant = linphone_chat_room_find_participant(paulineCr2, laureAddress);
7281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
// Check device's name in Laure's chat room
marieParticipant = linphone_chat_room_find_participant(laureCr, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(laureCr, paulineAddress);
laureParticipant = linphone_chat_room_get_me(laureCr);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
// Reset stats
marie->stat = initialMarieStats;
pauline->stat = initialPaulineStats;
pauline2->stat = initialPaulineStats2;
laure->stat = initialLaureStats;
chloe->stat = initialChloeStats;
chloe2->stat = initialChloeStats2;
chloe3->stat = initialChloeStats3;
// Marie adds Chloe to the chat room
participantsAddresses = NULL;
participantsAddresses = bctbx_list_append(participantsAddresses, chloeAddress);
linphone_chat_room_add_participants(marieCr, participantsAddresses);
// Check that the chat room is correctly created on Chloe's side and that she was added everywhere
LinphoneChatRoom *chloeCr =
check_creation_chat_room_client_side(coresList, chloe, &initialChloeStats, confAddr, initialSubject, 3, 0);
LinphoneChatRoom *chloeCr2 =
check_creation_chat_room_client_side(coresList, chloe2, &initialChloeStats2, confAddr, initialSubject, 3, 0);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participants_added,
initialMarieStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_devices_added,
initialMarieStats.number_of_participant_devices_added + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_added,
initialPaulineStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_added,
initialPaulineStats.number_of_participant_devices_added + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_participants_added,
initialPaulineStats2.number_of_participants_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_participant_devices_added,
initialPaulineStats2.number_of_participant_devices_added + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added,
initialLaureStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_devices_added,
initialLaureStats.number_of_participant_devices_added + 2,
liblinphone_tester_sip_timeout));
// Check device's name in Chloe's chat room
LinphoneParticipant *chloeParticipant = linphone_chat_room_get_me(chloeCr);
marieParticipant = linphone_chat_room_find_participant(chloeCr, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(chloeCr, paulineAddress);
laureParticipant = linphone_chat_room_find_participant(chloeCr, laureAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
7351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
LinphoneParticipantDevice *chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
LinphoneParticipantDevice *chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
// Check device's name in Chloe2's chat room
chloeParticipant = linphone_chat_room_get_me(chloeCr2);
marieParticipant = linphone_chat_room_find_participant(chloeCr2, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(chloeCr2, paulineAddress);
laureParticipant = linphone_chat_room_find_participant(chloeCr2, laureAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
// Check Chloe's devices name in other chat rooms
// Marie
chloeParticipant = linphone_chat_room_find_participant(marieCr, chloeAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
// Pauline
chloeParticipant = linphone_chat_room_find_participant(paulineCr, chloeAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
// Pauline 2
chloeParticipant = linphone_chat_room_find_participant(paulineCr2, chloeAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
// Laure
chloeParticipant = linphone_chat_room_find_participant(laureCr, chloeAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
// Reset stats
marie->stat = initialMarieStats;
pauline->stat = initialPaulineStats;
pauline2->stat = initialPaulineStats2;
laure->stat = initialLaureStats;
chloe->stat = initialChloeStats;
chloe2->stat = initialChloeStats2;
chloe3->stat = initialChloeStats3;
// Chloe adds a new device
coresManagerList = NULL;
coresManagerList = bctbx_list_append(coresManagerList, chloe3);
7421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490
init_core_for_conference(coresManagerList);
coresList = bctbx_list_append(coresList, chloe3->lc);
linphone_core_set_user_agent(chloe3->lc, "blabla (Chloe device 3) blibli/blublu (bloblo)", NULL);
start_core_for_conference(coresManagerList);
LinphoneAddress *chloeDeviceAddress3 =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(chloe3->lc)));
LinphoneChatRoom *chloeCr3 =
check_creation_chat_room_client_side(coresList, chloe3, &initialChloeStats3, confAddr, initialSubject, 3, 0);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_devices_added,
initialMarieStats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_added,
initialPaulineStats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline2->stat.number_of_participant_devices_added,
initialPaulineStats2.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_devices_added,
initialLaureStats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe->stat.number_of_participant_devices_added,
initialChloeStats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &chloe2->stat.number_of_participant_devices_added,
initialChloeStats2.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
// Check device's name in Chloe3's chat room
chloeParticipant = linphone_chat_room_get_me(chloeCr3);
marieParticipant = linphone_chat_room_find_participant(chloeCr3, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(chloeCr3, paulineAddress);
laureParticipant = linphone_chat_room_find_participant(chloeCr3, laureAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
LinphoneParticipantDevice *chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Check Chloe3's device name in other chat rooms
// Marie
chloeParticipant = linphone_chat_room_find_participant(marieCr, chloeAddress);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Pauline
chloeParticipant = linphone_chat_room_find_participant(paulineCr, chloeAddress);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Pauline 2
chloeParticipant = linphone_chat_room_find_participant(paulineCr2, chloeAddress);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Laure
chloeParticipant = linphone_chat_room_find_participant(laureCr, chloeAddress);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Chloe
chloeParticipant = linphone_chat_room_get_me(chloeCr);
7491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Chloe2
chloeParticipant = linphone_chat_room_get_me(chloeCr2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Still works after restart
linphone_core_manager_restart(marie, TRUE);
linphone_core_manager_restart(pauline, TRUE);
linphone_core_manager_restart(pauline2, TRUE);
linphone_core_manager_restart(laure, TRUE);
linphone_core_manager_restart(chloe, TRUE);
linphone_core_manager_restart(chloe2, TRUE);
linphone_core_manager_restart(chloe3, TRUE);
coresList = NULL;
coresList = bctbx_list_append(coresList, marie->lc);
coresList = bctbx_list_append(coresList, pauline->lc);
coresList = bctbx_list_append(coresList, pauline2->lc);
coresList = bctbx_list_append(coresList, laure->lc);
coresList = bctbx_list_append(coresList, chloe->lc);
coresList = bctbx_list_append(coresList, chloe2->lc);
coresList = bctbx_list_append(coresList, chloe3->lc);
// Marie
marieCr = linphone_core_find_chat_room(marie->lc, confAddr, marieDeviceAddress);
LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_add_callbacks(marieCr, cbs);
linphone_chat_room_cbs_unref(cbs);
BC_ASSERT_PTR_NOT_NULL(marieCr);
marieParticipant = linphone_chat_room_get_me(marieCr);
paulineParticipant = linphone_chat_room_find_participant(marieCr, paulineAddress);
laureParticipant = linphone_chat_room_find_participant(marieCr, laureAddress);
chloeParticipant = linphone_chat_room_find_participant(marieCr, chloeAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Pauline1
paulineCr = linphone_core_find_chat_room(pauline->lc, confAddr, paulineDeviceAddress1);
cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_add_callbacks(paulineCr, cbs);
linphone_chat_room_cbs_unref(cbs);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddress);
paulineParticipant = linphone_chat_room_get_me(paulineCr);
laureParticipant = linphone_chat_room_find_participant(paulineCr, laureAddress);
chloeParticipant = linphone_chat_room_find_participant(paulineCr, chloeAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
7561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Pauline2
paulineCr2 = linphone_core_find_chat_room(pauline2->lc, confAddr, paulineDeviceAddress2);
cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_add_callbacks(paulineCr2, cbs);
linphone_chat_room_cbs_unref(cbs);
BC_ASSERT_PTR_NOT_NULL(paulineCr2);
marieParticipant = linphone_chat_room_find_participant(paulineCr2, marieAddress);
paulineParticipant = linphone_chat_room_get_me(paulineCr2);
laureParticipant = linphone_chat_room_find_participant(paulineCr2, laureAddress);
chloeParticipant = linphone_chat_room_find_participant(paulineCr2, chloeAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Laure
laureCr = linphone_core_find_chat_room(laure->lc, confAddr, laureDeviceAddress);
cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_add_callbacks(laureCr, cbs);
linphone_chat_room_cbs_unref(cbs);
BC_ASSERT_PTR_NOT_NULL(laureCr);
marieParticipant = linphone_chat_room_find_participant(laureCr, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(laureCr, paulineAddress);
laureParticipant = linphone_chat_room_get_me(laureCr);
chloeParticipant = linphone_chat_room_find_participant(laureCr, chloeAddress);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Chloe1
chloeCr = linphone_core_find_chat_room(chloe->lc, confAddr, chloeDeviceAddress1);
cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_add_callbacks(chloeCr, cbs);
linphone_chat_room_cbs_unref(cbs);
BC_ASSERT_PTR_NOT_NULL(chloeCr);
marieParticipant = linphone_chat_room_find_participant(chloeCr, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(chloeCr, paulineAddress);
laureParticipant = linphone_chat_room_find_participant(chloeCr, laureAddress);
chloeParticipant = linphone_chat_room_get_me(chloeCr);
7631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Chloe2
chloeCr2 = linphone_core_find_chat_room(chloe2->lc, confAddr, chloeDeviceAddress2);
cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_add_callbacks(chloeCr2, cbs);
linphone_chat_room_cbs_unref(cbs);
BC_ASSERT_PTR_NOT_NULL(chloeCr2);
marieParticipant = linphone_chat_room_find_participant(chloeCr2, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(chloeCr2, paulineAddress);
laureParticipant = linphone_chat_room_find_participant(chloeCr2, laureAddress);
chloeParticipant = linphone_chat_room_get_me(chloeCr2);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
// Chloe3
chloeCr3 = linphone_core_find_chat_room(chloe3->lc, confAddr, chloeDeviceAddress3);
cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_state_changed(cbs, chat_room_state_changed);
linphone_chat_room_add_callbacks(chloeCr3, cbs);
linphone_chat_room_cbs_unref(cbs);
BC_ASSERT_PTR_NOT_NULL(chloeCr3);
marieParticipant = linphone_chat_room_find_participant(chloeCr3, marieAddress);
paulineParticipant = linphone_chat_room_find_participant(chloeCr3, paulineAddress);
laureParticipant = linphone_chat_room_find_participant(chloeCr3, laureAddress);
chloeParticipant = linphone_chat_room_get_me(chloeCr3);
marieDevice = linphone_participant_find_device(marieParticipant, marieDeviceAddress);
paulineDevice = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress1);
paulineDevice2 = linphone_participant_find_device(paulineParticipant, paulineDeviceAddress2);
laureDevice = linphone_participant_find_device(laureParticipant, laureDeviceAddress);
chloeDevice = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress1);
chloeDevice2 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress2);
chloeDevice3 = linphone_participant_find_device(chloeParticipant, chloeDeviceAddress3);
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(marieDevice), "Marie device");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice), "Pauline device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(paulineDevice2), "Pauline device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(laureDevice), "Laure device ((toto) tata) (titi)");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice), "Chloe device 1");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice2), "Chloe device 2");
BC_ASSERT_STRING_EQUAL(linphone_participant_device_get_name(chloeDevice3), "Chloe device 3");
linphone_address_unref(marieAddress);
linphone_address_unref(paulineAddress);
linphone_address_unref(laureAddress);
7701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770
linphone_address_unref(chloeAddress);
linphone_address_unref(confAddr);
linphone_address_unref(marieDeviceAddress);
linphone_address_unref(paulineDeviceAddress1);
linphone_address_unref(paulineDeviceAddress2);
linphone_address_unref(laureDeviceAddress);
linphone_address_unref(chloeDeviceAddress1);
linphone_address_unref(chloeDeviceAddress2);
linphone_address_unref(chloeDeviceAddress3);
// Clean db from chat room
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
linphone_core_manager_delete_chat_room(pauline2, paulineCr2, coresList);
linphone_core_manager_delete_chat_room(chloe, chloeCr, coresList);
linphone_core_manager_delete_chat_room(chloe2, chloeCr2, coresList);
linphone_core_manager_delete_chat_room(chloe3, chloeCr3, coresList);
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(laure);
linphone_core_manager_destroy(chloe);
linphone_core_manager_destroy(chloe2);
linphone_core_manager_destroy(chloe3);
}
static void add_device_one_to_one_chat_room_other_left(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *pauline2 = linphone_core_manager_create("pauline_rc");
LinphoneAddress *confAddr = NULL;
LinphoneChatRoom *paulineCr = NULL, *paulineCr2 = NULL, *marieCr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, pauline2);
bctbx_list_t *coresList = init_core_for_conference_with_groupchat_version(coresManagerList, "1.0");
linphone_core_manager_start(marie, TRUE);
linphone_core_manager_start(pauline, TRUE);
LinphoneAddress *paulineAddress = linphone_address_new(linphone_core_get_identity(pauline->lc));
participantsAddresses = bctbx_list_append(participantsAddresses, paulineAddress);
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialPaulineStats2 = pauline2->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto clean;
confAddr = (LinphoneAddress *)linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto clean;
confAddr = linphone_address_clone(confAddr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
1, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto clean;
// Marie leaves the chat room
linphone_chat_room_leave(marieCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateTerminationPending,
initialMarieStats.number_of_LinphoneConferenceStateTerminationPending + 1, 100));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateTerminated,
7771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840
initialMarieStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
int pauline_number_of_participant_devices_added = pauline->stat.number_of_participant_devices_added;
linphone_core_manager_start(pauline2, TRUE);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr2 = check_creation_chat_room_client_side(coresList, pauline2, &initialPaulineStats2, confAddr,
initialSubject, 1, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr2)) goto clean;
// Also, pauline should receive a notification that pauline2 device was added.
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_added,
pauline_number_of_participant_devices_added + 1, liblinphone_tester_sip_timeout));
wait_for_list(coresList, NULL, 0, 1000);
clean:
// Clean db from chat room
if (pauline && paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
if (pauline2 && paulineCr) linphone_core_manager_delete_chat_room(pauline2, paulineCr2, coresList);
if (marie && marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (confAddr) linphone_address_unref(confAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(pauline2);
}
/*
* This test simulates a case where whatever the reason the server thinks a client device is part of a given chatroom,
*but the client device has no longer this information.
**/
static void group_chat_loss_of_client_context(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Save Laure's db before it becomes part of a group chat.
const char *uri = linphone_config_get_string(linphone_core_get_config(laure->lc), "storage", "uri", "");
char *uriCopy = bc_tester_file("linphone_tester.db");
BC_ASSERT_FALSE(liblinphone_tester_copy_file(uri, uriCopy));
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
7841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Save Laure's db now that it is part of the group chat
uri = linphone_config_get_string(linphone_core_get_config(laure->lc), "storage", "uri", "");
char *uriCopyAfter = bc_tester_file("linphone_tester2.db");
BC_ASSERT_FALSE(liblinphone_tester_copy_file(uri, uriCopyAfter));
// Restore old db to Laure and restart it.
laure->database_path = uriCopy;
coresList = bctbx_list_remove(coresList, laure->lc);
linphone_core_manager_reinit(laure);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, laure);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(laure, TRUE);
// Pauline sends a message, laure shall not receive it, in any way.
if (paulineCr) {
_send_message(paulineCr, "Salut");
}
wait_for_list(coresList, NULL, 0, 2000);
BC_ASSERT_TRUE(linphone_core_get_chat_rooms(laure->lc) == NULL);
// Now restarts Laure with good db in order to clean the chatroom properly.
// Restore old db to Laure and restart it.
laure->database_path = uriCopyAfter;
coresList = bctbx_list_remove(coresList, laure->lc);
linphone_core_manager_reinit(laure);
tmpCoresManagerList = bctbx_list_append(NULL, laure);
tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(laure, TRUE);
// Clean chatroom from databases.
if (BC_ASSERT_TRUE(linphone_core_get_chat_rooms(laure->lc) != NULL)) {
LinphoneChatRoom *laureCr = (LinphoneChatRoom *)linphone_core_get_chat_rooms(laure->lc)->data;
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
}
end:
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void participant_removed_then_added(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneChatRoom *marie1Cr = NULL, *pauline1Cr = NULL, *newPauline1Cr = NULL, *laureCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
7911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPauline1Stats = pauline1->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marie1Cr = create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses,
initialSubject, FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marie1Cr)) goto end;
participantsAddresses = NULL;
confAddr = linphone_chat_room_get_conference_address(marie1Cr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline1
pauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr,
initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(pauline1Cr)) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(laureCr)) goto end;
// Pauline restart to make use of list subscription ::this part (core restart) is leaking memory
coresList = bctbx_list_remove(coresList, pauline1->lc);
linphone_core_manager_reinit(pauline1);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline1);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline1, TRUE);
// Check that the chat room has correctly created on Pauline's side and that the participants are added
pauline1Cr =
check_has_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr, initialSubject, 2, FALSE);
// wait for first notify to be received by pauline
wait_for_list(coresList, NULL, 0, 1000);
// Pauline leaving but keeping a ref like a Java GC can do, this is the key part of this test.
linphone_chat_room_ref(pauline1Cr);
linphone_core_delete_chat_room(pauline1->lc, pauline1Cr);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_LinphoneConferenceStateDeleted,
initialPauline1Stats.number_of_LinphoneConferenceStateDeleted + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_participants_removed,
initialMarie1Stats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_removed,
initialLaureStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marie1Cr), 1, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 1, int, "%d");
size_t paulineCrNo = bctbx_list_size(linphone_core_get_chat_rooms(pauline1->lc));
BC_ASSERT_EQUAL(paulineCrNo, 0, size_t, "%0zu");
// Send a message when Pauline is left to test ordering between events and messages.
wait_for_list(coresList, NULL, 0, 1500); // Wait enough time to make a difference on time_t
const char *textMessage = "Hello";
LinphoneChatMessage *message = _send_message(marie1Cr, textMessage);
wait_for_list(coresList, NULL, 0, 1500); // Wait enough time to make a difference on time_t
7981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050
linphone_chat_message_unref(message);
// Marie1 adds Pauline back to the chat room
initialMarie1Stats = marie1->stat;
initialLaureStats = laure->stat;
initialPauline1Stats = pauline1->stat;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
linphone_chat_room_add_participants(marie1Cr, participantsAddresses);
// BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_participants_added,
// initialMarie1Stats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
// BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_added,
// initialLaureStats.number_of_participants_added + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_chat_room_participants(coresList, marie1Cr, 2, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_chat_room_participants(coresList, laureCr, 2, liblinphone_tester_sip_timeout));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(marie1Cr), 2, int, "%d");
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(laureCr), 2, int, "%d");
newPauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr,
initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(newPauline1Cr)) goto end;
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(newPauline1Cr), 2, int, "%d");
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(newPauline1Cr), initialSubject);
// Check timestamps ordering in history
bctbx_list_t *history = linphone_chat_room_get_history_events(marie1Cr, 3); // Leave + Message + Join
bctbx_list_t *itHistory = history;
int step = 0;
time_t lastTime = 0;
while (itHistory) {
LinphoneEventLog *event = (LinphoneEventLog *)bctbx_list_get_data(itHistory);
switch (step) {
case 0:
BC_ASSERT_EQUAL((int)linphone_event_log_get_type(event),
LinphoneEventLogTypeConferenceParticipantRemoved, int, "%d");
lastTime = linphone_event_log_get_creation_time(event); // Main ordering (Leave + Message + Join)
break;
case 1: {
BC_ASSERT_EQUAL((int)linphone_event_log_get_type(event), LinphoneEventLogTypeConferenceChatMessage, int,
"%d");
LinphoneChatMessage *message = linphone_event_log_get_chat_message(event);
time_t messageTime = linphone_chat_message_get_time(message);
BC_ASSERT_TRUE(lastTime < messageTime); // Main ordering (Leave + Message + Join)
BC_ASSERT_TRUE(messageTime >= linphone_event_log_get_creation_time(
event)); // A send message timestamp should be after its creation.
lastTime = messageTime;
} break;
case 2:
BC_ASSERT_EQUAL((int)linphone_event_log_get_type(event), LinphoneEventLogTypeConferenceParticipantAdded,
int, "%d");
BC_ASSERT_TRUE(lastTime <
linphone_event_log_get_creation_time(event)); // Main ordering (Leave + Message + Join)
lastTime = linphone_event_log_get_creation_time(event);
break;
default: {
}
}
++step;
itHistory = bctbx_list_next(itHistory);
}
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_event_log_unref);
size_t marieCrNo = bctbx_list_size(linphone_core_get_chat_rooms(marie1->lc));
BC_ASSERT_EQUAL(marieCrNo, 1, size_t, "%0zu");
size_t laureCrNo = bctbx_list_size(linphone_core_get_chat_rooms(laure->lc));
BC_ASSERT_EQUAL(laureCrNo, 1, size_t, "%0zu");
paulineCrNo = bctbx_list_size(linphone_core_get_chat_rooms(pauline1->lc));
BC_ASSERT_EQUAL(paulineCrNo, 1, size_t, "%0zu");
8051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120
end:
// Clean db from chat room
if (marie1Cr) linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
if (newPauline1Cr) linphone_core_manager_delete_chat_room(pauline1, newPauline1Cr, coresList);
if (laureCr) linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
// now GC is cleaning old chatroom
if (pauline1Cr) linphone_chat_room_unref(pauline1Cr);
marieCrNo = bctbx_list_size(linphone_core_get_chat_rooms(marie1->lc));
BC_ASSERT_EQUAL(marieCrNo, 0, size_t, "%0zu");
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneConferenceStateDeleted, 1,
liblinphone_tester_sip_timeout));
laureCrNo = bctbx_list_size(linphone_core_get_chat_rooms(laure->lc));
BC_ASSERT_EQUAL(laureCrNo, 0, size_t, "%0zu");
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneConferenceStateDeleted, 1,
liblinphone_tester_sip_timeout));
paulineCrNo = bctbx_list_size(linphone_core_get_chat_rooms(pauline1->lc));
BC_ASSERT_EQUAL(paulineCrNo, 0, size_t, "%0zu");
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_LinphoneConferenceStateDeleted, 2,
liblinphone_tester_sip_timeout));
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(pauline1);
linphone_core_manager_destroy(laure);
}
static void group_chat_room_join_one_to_one_chat_room_with_a_new_device_not_notified(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *marie2 = NULL;
LinphoneChatRoom *marie1Cr = NULL, *marie2Cr = NULL, *paulineCr = NULL;
LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference_with_groupchat_version(coresManagerList, "1.0");
start_core_for_conference(coresManagerList);
bctbx_list_t *participantsAddresses =
bctbx_list_append(NULL, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPaulineStats = pauline->stat;
// Marie1 creates a new one-to-one chat room with Pauline
const char *initialSubject = "Pauline";
marie1Cr = create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses,
initialSubject, FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marie1Cr)) goto end;
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marie1Cr) & LinphoneChatRoomCapabilitiesOneToOne);
confAddr = (LinphoneAddress *)linphone_chat_room_get_conference_address(marie1Cr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
confAddr = linphone_address_clone(confAddr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
1, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
initialPaulineStats.number_of_participant_devices_added = pauline->stat.number_of_participant_devices_added;
marie2 = linphone_core_manager_create("marie_rc");
stats initialMarie2Stats = marie2->stat;
bctbx_list_t *newCoresManagerList = bctbx_list_append(NULL, marie2);
8121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190
bctbx_list_t *newCoresList = init_core_for_conference_with_groupchat_version(newCoresManagerList, "1.0");
start_core_for_conference(newCoresManagerList);
coresManagerList = bctbx_list_concat(coresManagerList, newCoresManagerList);
coresList = bctbx_list_concat(coresList, newCoresList);
// Marie2 gets the one-to-one chat room with Pauline
marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr, initialSubject, 1,
FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(marie2Cr)) goto end;
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(marie2Cr) & LinphoneChatRoomCapabilitiesOneToOne);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_added,
initialPaulineStats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
// Save pauline db
const char *uri = linphone_config_get_string(linphone_core_get_config(pauline->lc), "storage", "uri", "");
char *uriCopy = bc_tester_file("linphone_tester.db");
BC_ASSERT_FALSE(liblinphone_tester_copy_file(uri, uriCopy));
int initialPaulineEvent = linphone_chat_room_get_history_events_size(paulineCr);
// Simulate an uninstall of the application on Marie's side with unregistration (It should remove the device)
// Save the number of chat rooms at the moment of stopping the core
const int marie1_no_cr = (int)bctbx_list_size(linphone_core_get_chat_rooms(marie1->lc));
coresManagerList = bctbx_list_remove(coresManagerList, marie1);
coresList = bctbx_list_remove(coresList, marie1->lc);
initialPaulineStats = pauline->stat;
linphone_core_manager_stop(marie1);
// force flexisip to publish on marie topic
linphone_core_refresh_registers(marie2->lc);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_removed,
initialPaulineStats.number_of_participant_devices_removed + 1,
liblinphone_tester_sip_timeout));
// Reset db at pauline side
pauline->database_path = uriCopy;
coresList = bctbx_list_remove(coresList, pauline->lc);
memset(&initialPaulineStats, 0, sizeof(initialPaulineStats));
linphone_core_manager_reinit(pauline);
// force full state
linphone_config_set_bool(linphone_core_get_config(pauline->lc), "misc", "conference_event_package_force_full_state",
TRUE);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline);
bctbx_list_t *tmpCoresList = init_core_for_conference_with_groupchat_version(tmpCoresManagerList, "1.0");
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline, TRUE);
// wait for first notify to be received by pauline
wait_for_list(coresList, NULL, 0, 1000);
// Marie2 gets the one-to-one chat room with Pauline
paulineCr =
check_has_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 1, FALSE);
LinphoneAddress *marieAddress = linphone_address_new(linphone_core_get_identity(marie2->lc));
LinphoneParticipant *marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddress);
BC_ASSERT_EQUAL((int)bctbx_list_size(linphone_participant_get_devices(marieParticipant)), 1, int, "%i");
// recheck after restart
coresList = bctbx_list_remove(coresList, pauline->lc);
linphone_core_manager_reinit(pauline);
linphone_config_set_bool(linphone_core_get_config(pauline->lc), "misc", "conference_event_package_force_full_state",
FALSE);
tmpCoresManagerList = bctbx_list_append(NULL, pauline);
tmpCoresList = init_core_for_conference_with_groupchat_version(tmpCoresManagerList, "1.0");
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline, TRUE);
8191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260
// wait for first notify to be received by pauline
wait_for_list(coresList, NULL, 0, 1000);
// Marie2 gets the one-to-one chat room with Pauline
paulineCr =
check_has_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject, 1, FALSE);
marieParticipant = linphone_chat_room_find_participant(paulineCr, marieAddress);
BC_ASSERT_EQUAL((int)bctbx_list_size(linphone_participant_get_devices(marieParticipant)), 1, int, "%i");
BC_ASSERT_EQUAL(linphone_chat_room_get_history_events_size(paulineCr), initialPaulineEvent, int, "%i");
// check if we can still communicate
// Marie1 sends a message
const char *textMessage = "Hello";
LinphoneChatMessage *message = _send_message(marie2Cr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageDelivered,
initialMarie1Stats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(pauline->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Pauline answers to the previous message
textMessage = "Hey. How are you?";
message = _send_message(paulineCr, textMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageDelivered,
initialPaulineStats.number_of_LinphoneMessageDelivered + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived,
initialMarie1Stats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_text(marie2->stat.last_received_chat_message), textMessage);
linphone_chat_message_unref(message);
// Clean db from chat room
linphone_core_manager_reinit(marie1);
tmpCoresManagerList = bctbx_list_append(NULL, marie1);
tmpCoresList = init_core_for_conference_with_groupchat_version(tmpCoresManagerList, "1.0");
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(marie1, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie1->stat.number_of_LinphoneConferenceStateCreated,
initialMarie1Stats.number_of_LinphoneConferenceStateCreated + marie1_no_cr,
liblinphone_tester_sip_timeout));
wait_for_list(coresList, NULL, 0, 1000);
marie1Cr =
check_has_chat_room_client_side(coresList, marie1, &initialMarie1Stats, confAddr, initialSubject, 1, FALSE);
end:
if (marie1Cr) linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
if (marie2Cr) linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
if (confAddr) linphone_address_unref(confAddr);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie1);
if (marie2) linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline);
}
static void subscribe_test_after_set_chat_database_path(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
LinphoneChatRoom *marieCr = NULL, *paulineCr = NULL, *laureCr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
8261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marieCr = create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marieCr)) goto end;
confAddr = linphone_chat_room_get_conference_address(marieCr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline's side and that the participants are added
paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats, confAddr, initialSubject,
2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(paulineCr)) goto end;
// Check that the chat room is correctly created on Laure's side and that the participants are added
laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(laureCr)) goto end;
linphone_core_manager_reinit(pauline);
coresList = NULL;
coresList = bctbx_list_append(coresList, marie->lc);
coresList = bctbx_list_append(coresList, pauline->lc);
coresList = bctbx_list_append(coresList, laure->lc);
LinphoneAddress *factoryAddr = linphone_address_new(sFactoryUri);
_configure_core_for_conference(pauline, factoryAddr);
linphone_address_unref(factoryAddr);
LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get());
linphone_core_cbs_set_chat_room_state_changed(cbs, core_chat_room_state_changed);
configure_core_for_callbacks(pauline, cbs);
linphone_core_cbs_unref(cbs);
linphone_core_manager_start(pauline, TRUE);
LinphoneAddress *paulineAddress =
linphone_address_clone(linphone_proxy_config_get_contact(linphone_core_get_default_proxy_config(pauline->lc)));
paulineCr = linphone_core_find_chat_room(pauline->lc, confAddr, paulineAddress);
BC_ASSERT_PTR_NOT_NULL(paulineCr);
linphone_chat_room_ref(paulineCr);
linphone_core_set_network_reachable(pauline->lc, FALSE);
const char *path = "";
// set_chat_database_path() will cause a reload of the database, with re-creation of chatrooms.
linphone_core_set_chat_database_path(pauline->lc, path);
if (paulineCr) linphone_chat_room_unref(paulineCr);
paulineCr = linphone_core_find_chat_room(pauline->lc, confAddr, paulineAddress);
linphone_address_unref(paulineAddress);
linphone_core_set_network_reachable(pauline->lc, TRUE);
// Marie now changes the subject
const char *newSubject = "Subject has been changed! :O";
linphone_chat_room_set_subject(marieCr, newSubject);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_subject_changed,
initialMarieStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_subject_changed,
8331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400
initialPaulineStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_subject_changed,
initialLaureStats.number_of_subject_changed + 1, liblinphone_tester_sip_timeout));
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(marieCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(paulineCr), newSubject);
BC_ASSERT_STRING_EQUAL(linphone_chat_room_get_subject(laureCr), newSubject);
end:
// Clean db from chat room
if (marieCr) linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
if (laureCr) linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
if (paulineCr) linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void one_to_one_chat_room_send_forward_message(void) {
group_chat_room_unique_one_to_one_chat_room_with_forward_message_recreated_from_message_base(FALSE, TRUE, FALSE);
}
static void one_to_one_chat_room_send_forward_message_with_restart(void) {
group_chat_room_unique_one_to_one_chat_room_with_forward_message_recreated_from_message_base(TRUE, TRUE, FALSE);
}
static void one_to_one_chat_room_reply_forward_message(void) {
group_chat_room_unique_one_to_one_chat_room_with_forward_message_recreated_from_message_base(FALSE, FALSE, TRUE);
}
static void one_to_one_chat_room_reply_forward_message_with_restart(void) {
group_chat_room_unique_one_to_one_chat_room_with_forward_message_recreated_from_message_base(TRUE, FALSE, TRUE);
}
static void core_stop_start_with_chat_room_ref(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline1 = linphone_core_manager_create("pauline_rc");
LinphoneChatRoom *marie1Cr = NULL, *pauline1Cr = NULL, *newPauline1Cr = NULL;
const LinphoneAddress *confAddr = NULL;
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, pauline1);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline1->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialPauline1Stats = pauline1->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
marie1Cr = create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses,
initialSubject, FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
if (!BC_ASSERT_PTR_NOT_NULL(marie1Cr)) goto end;
participantsAddresses = NULL;
confAddr = linphone_chat_room_get_conference_address(marie1Cr);
if (!BC_ASSERT_PTR_NOT_NULL(confAddr)) goto end;
// Check that the chat room is correctly created on Pauline1
pauline1Cr = check_creation_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr,
initialSubject, 1, FALSE);
if (!BC_ASSERT_PTR_NOT_NULL(pauline1Cr)) goto end;
// Pauline leaving but keeping a ref like a Java GC can do, this is the key part of this test.
linphone_chat_room_ref(pauline1Cr);
linphone_core_stop(pauline1->lc);
8401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_LinphoneGlobalShutdown,
initialPauline1Stats.number_of_LinphoneGlobalShutdown + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline1->stat.number_of_LinphoneGlobalOff,
initialPauline1Stats.number_of_LinphoneGlobalOff + 1, liblinphone_tester_sip_timeout));
linphone_core_start(pauline1->lc);
// now GC is cleaning old chatroom
if (pauline1Cr) linphone_chat_room_unref(pauline1Cr);
// test very early client group chatroom creation, should fail
LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(pauline1->lc);
linphone_proxy_config_edit(proxy);
linphone_proxy_config_set_conference_factory_uri(proxy, sFactoryUri);
linphone_proxy_config_done(proxy);
LinphoneChatRoomParams *params = linphone_core_create_default_chat_room_params(pauline1->lc);
linphone_chat_room_params_set_backend(params, LinphoneChatRoomBackendFlexisipChat);
LinphoneChatRoom *chatRoom =
linphone_core_create_chat_room_2(pauline1->lc, params, initialSubject, participantsAddresses);
linphone_chat_room_params_unref(params);
BC_ASSERT_PTR_NULL(chatRoom);
if (chatRoom) linphone_chat_room_unref(chatRoom);
coresList = bctbx_list_remove(coresList, pauline1->lc);
linphone_core_manager_reinit(pauline1);
bctbx_list_t *tmpCoresManagerList = bctbx_list_append(NULL, pauline1);
bctbx_list_t *tmpCoresList = init_core_for_conference(tmpCoresManagerList);
bctbx_list_free(tmpCoresManagerList);
coresList = bctbx_list_concat(coresList, tmpCoresList);
linphone_core_manager_start(pauline1, TRUE);
// Check that the chat room has correctly created on Laure's side and that the participants are added
newPauline1Cr =
check_has_chat_room_client_side(coresList, pauline1, &initialPauline1Stats, confAddr, initialSubject, 1, FALSE);
wait_for_list(coresList, NULL, 0, 1000);
end:
// Clean db from chat room
if (marie1Cr) linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
if (newPauline1Cr) linphone_core_manager_delete_chat_room(pauline1, newPauline1Cr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(pauline1);
}
static void group_chat_room_device_unregistered(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
// Marie creates a new group chat room
8471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
participantsAddresses = NULL;
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
LinphoneProxyConfig *proxyConfig = linphone_core_get_default_proxy_config(laure->lc);
linphone_proxy_config_edit(proxyConfig);
linphone_proxy_config_enable_register(proxyConfig, FALSE);
linphone_proxy_config_done(proxyConfig);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneRegistrationCleared,
initialMarieStats.number_of_LinphoneRegistrationCleared + 1,
liblinphone_tester_sip_timeout));
// Current expected behavior is to have participant devices removed
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_devices_removed,
initialMarieStats.number_of_participant_devices_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_removed,
initialPaulineStats.number_of_participant_devices_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1, 3000));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1, 3000));
// to avoid automatique re-subscription of chatroom while disabling network
linphone_core_enter_background(marie->lc);
linphone_core_enter_background(pauline->lc);
linphone_core_enter_background(laure->lc);
wait_for_list(coresList, NULL, 1, 3000);
// to force re-re-connection to restarted flexisip
linphone_core_set_network_reachable(marie->lc, FALSE);
linphone_core_set_network_reachable(pauline->lc, FALSE);
linphone_core_set_network_reachable(laure->lc, FALSE);
// break here and restart Flexisip
marie->stat.number_of_participant_devices_added = 0;
pauline->stat.number_of_participant_devices_added = 0;
proxyConfig = linphone_core_get_default_proxy_config(laure->lc);
linphone_proxy_config_edit(proxyConfig);
linphone_proxy_config_enable_register(proxyConfig, TRUE);
linphone_proxy_config_done(proxyConfig);
linphone_core_enter_foreground(marie->lc);
linphone_core_set_network_reachable(marie->lc, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneRegistrationOk,
initialMarieStats.number_of_LinphoneRegistrationOk + 1, 10000));
linphone_core_enter_foreground(pauline->lc);
linphone_core_set_network_reachable(pauline->lc, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneRegistrationOk,
initialPaulineStats.number_of_LinphoneRegistrationOk + 1, 10000));
linphone_core_enter_foreground(laure->lc);
linphone_core_set_network_reachable(laure->lc, TRUE);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneRegistrationOk,
initialLaureStats.number_of_LinphoneRegistrationOk + 1, 10000));
8541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610
// in case of flexisip restart
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_devices_added,
initialMarieStats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_added,
initialPaulineStats.number_of_participant_devices_added + 1,
liblinphone_tester_sip_timeout));
// Laure adds a new device without group chat enabled
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
initialLaureStats = laure->stat;
LinphoneCoreManager *laure2 = linphone_core_manager_new("laure_tcp_rc");
coresManagerList = bctbx_list_append(coresManagerList, laure2);
proxyConfig = linphone_core_get_default_proxy_config(laure->lc);
linphone_proxy_config_edit(proxyConfig);
linphone_proxy_config_enable_register(proxyConfig, FALSE);
linphone_proxy_config_done(proxyConfig);
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_LinphoneRegistrationCleared,
initialLaureStats.number_of_LinphoneRegistrationCleared + 1,
liblinphone_tester_sip_timeout));
// Current expected behavior is to have participant devices removed
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_participant_devices_removed,
initialMarieStats.number_of_participant_devices_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_devices_removed,
initialPaulineStats.number_of_participant_devices_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &marie->stat.number_of_participants_removed,
initialMarieStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_FALSE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
linphone_core_manager_destroy(laure2);
}
static void group_chat_room_admin_creator_leaves_and_is_reinvited(void) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
LinphoneCoreManager *laure = linphone_core_manager_create("laure_tcp_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
coresManagerList = bctbx_list_append(coresManagerList, laure);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(laure->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
stats initialLaureStats = laure->stat;
8611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 2, FALSE);
// Check that the chat room is correctly created on Laure's side and that the participants are added
LinphoneChatRoom *laureCr =
check_creation_chat_room_client_side(coresList, laure, &initialLaureStats, confAddr, initialSubject, 2, FALSE);
// Marie leaves the room
linphone_chat_room_leave(marieCr);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneConferenceStateTerminated,
initialMarieStats.number_of_LinphoneConferenceStateTerminated + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participants_removed,
initialPaulineStats.number_of_participants_removed + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participants_removed,
initialLaureStats.number_of_participants_removed + 1, liblinphone_tester_sip_timeout));
/* FIXME: the number of admin status changed shoud be 1. But the conference server notifies first that marie looses
* its admin status, before being deleted from the chatroom. This is indeed useless to notify this. Once fixed in
* the conference server, the counter shall be set back to +1. */
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_participant_admin_statuses_changed,
initialPaulineStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &laure->stat.number_of_participant_admin_statuses_changed,
initialLaureStats.number_of_participant_admin_statuses_changed + 2,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(linphone_participant_is_admin(linphone_chat_room_get_me(laureCr)));
linphone_core_delete_chat_room(marie->lc, marieCr);
initialMarieStats = marie->stat;
// Laure invites Marie to the chatroom
participantsAddresses = NULL;
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(marie->lc)));
linphone_chat_room_add_participants(laureCr, participantsAddresses);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Check that the chat room is correctly created on Marie's side and that the participants are added
marieCr = check_creation_chat_room_client_side(coresList, marie, &initialMarieStats,
linphone_chat_room_get_conference_address(laureCr), initialSubject,
2, FALSE);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(laure, laureCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(laure);
}
static void group_chat_forward_file_transfer_message_url(const char *file_transfer_server_url) {
LinphoneCoreManager *marie = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
8681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750
bctbx_list_t *participantsAddresses = NULL;
char *sendFilepath = bc_tester_res("sounds/sintel_trailer_opus_h264.mkv");
char *receivePaulineFilepath = bc_tester_file("receive_file_pauline.dump");
char *receiveMarieFilepath = bc_tester_file("receive_file_marie.dump");
/* Remove any previously downloaded file */
remove(receivePaulineFilepath);
remove(receiveMarieFilepath);
coresManagerList = bctbx_list_append(coresManagerList, marie);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
linphone_core_set_file_transfer_server(marie->lc, file_transfer_server_url);
linphone_core_set_file_transfer_server(pauline->lc, file_transfer_server_url);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
stats initialPaulineStats = pauline->stat;
// Marie creates a new group chat room
const char *initialSubject = "Pauline";
LinphoneChatRoom *marieCr =
create_chat_room_client_side(coresList, marie, &initialMarieStats, participantsAddresses, initialSubject, FALSE,
LinphoneChatRoomEphemeralModeDeviceManaged);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marieCr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(paulineCr) & LinphoneChatRoomCapabilitiesOneToOne);
// Marie sends a message
_send_file(marieCr, sendFilepath, NULL, FALSE);
// Check pauline got it
// Note: we must not use the buffer reception(last param to FALSE) or our message transfer won't work, probably some
// fix to be done in the callback
_receive_file(coresList, pauline, &initialPaulineStats, receivePaulineFilepath, sendFilepath, NULL, FALSE);
// Retrieve message from Pauline chatroom history
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 1, int, " %i");
if (linphone_chat_room_get_history_size(paulineCr) > 0) {
bctbx_list_t *history = linphone_chat_room_get_history(paulineCr, 1);
LinphoneChatMessage *recv_msg = (LinphoneChatMessage *)(history->data);
// Forward it to Marie
LinphoneChatMessage *msg = linphone_chat_room_create_forward_message(paulineCr, recv_msg);
const LinphoneAddress *forwarded_from_address = linphone_chat_message_get_from_address(recv_msg);
char *forwarded_from = linphone_address_as_string_uri_only(forwarded_from_address);
bctbx_list_free_with_data(history, (bctbx_list_free_func)linphone_chat_message_unref);
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
linphone_chat_message_cbs_set_msg_state_changed(cbs, liblinphone_tester_chat_message_msg_state_changed);
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(linphone_chat_message_is_forward(msg));
BC_ASSERT_STRING_EQUAL(linphone_chat_message_get_forward_info(msg), forwarded_from);
// Check Marie received it and that the file is still the same
_receive_file(coresList, marie, &initialMarieStats, receiveMarieFilepath, sendFilepath, NULL, FALSE);
linphone_chat_message_unref(msg);
ms_free(forwarded_from);
} else {
BC_FAIL("Could not get message to forward from history");
}
8751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie, marieCr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
wait_for_list(coresList, 0, 1, 2000);
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(marie->lc), 0, int, "%i");
BC_ASSERT_EQUAL(linphone_core_get_call_history_size(pauline->lc), 0, int, "%i");
BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(marie->lc));
BC_ASSERT_PTR_NULL(linphone_core_get_call_logs(pauline->lc));
ms_free(sendFilepath);
ms_free(receivePaulineFilepath);
ms_free(receiveMarieFilepath);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void group_chat_forward_file_transfer_message(void) {
group_chat_forward_file_transfer_message_url(file_transfer_url);
}
static void group_chat_forward_file_transfer_message_digest_auth_server(void) {
group_chat_forward_file_transfer_message_url(file_transfer_url_digest_auth);
}
static void group_chat_forward_file_transfer_message_digest_auth_server_encryptedFS(void) {
uint8_t evfs_key[32] = {0xaa, 0x55, 0xFF, 0xFF, 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde,
0xf0, 0x11, 0x22, 0x33, 0x44, 0x5a, 0xa5, 0x5F, 0xaF, 0x52, 0xa4,
0xa6, 0x58, 0xaa, 0x5c, 0xae, 0x50, 0xa1, 0x52, 0xa3, 0x54};
linphone_factory_set_vfs_encryption(linphone_factory_get(), LINPHONE_VFS_ENCRYPTION_AES256GCM128_SHA256, evfs_key,
32);
group_chat_forward_file_transfer_message_url(file_transfer_url_digest_auth);
linphone_factory_set_vfs_encryption(linphone_factory_get(), LINPHONE_VFS_ENCRYPTION_UNSET, NULL, 0);
}
static void group_chat_room_message_sync_between_devices_with_same_identity(void) {
LinphoneCoreManager *marie1 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *marie2 = linphone_core_manager_create("marie_rc");
LinphoneCoreManager *pauline = linphone_core_manager_create("pauline_rc");
bctbx_list_t *coresManagerList = NULL;
bctbx_list_t *participantsAddresses = NULL;
coresManagerList = bctbx_list_append(coresManagerList, marie1);
coresManagerList = bctbx_list_append(coresManagerList, marie2);
coresManagerList = bctbx_list_append(coresManagerList, pauline);
bctbx_list_t *coresList = init_core_for_conference(coresManagerList);
start_core_for_conference(coresManagerList);
participantsAddresses =
bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarie1Stats = marie1->stat;
stats initialMarie2Stats = marie2->stat;
stats initialPaulineStats = pauline->stat;
// Marie creates a new group chat room
const char *initialSubject = "Colleagues";
LinphoneChatRoom *marie1Cr =
create_chat_room_client_side(coresList, marie1, &initialMarie1Stats, participantsAddresses, initialSubject,
FALSE, LinphoneChatRoomEphemeralModeDeviceManaged);
BC_ASSERT_PTR_NOT_NULL(marie1Cr);
const LinphoneAddress *confAddr = linphone_chat_room_get_conference_address(marie1Cr);
// Check that the chat room is correctly created on Pauline's side and that the participants are added
LinphoneChatRoom *paulineCr = check_creation_chat_room_client_side(coresList, pauline, &initialPaulineStats,
confAddr, initialSubject, 1, FALSE);
8821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890
BC_ASSERT_PTR_NOT_NULL(paulineCr);
// Check that the chat room is correctly created on Chloe's side and that the participants are added
LinphoneChatRoom *marie2Cr = check_creation_chat_room_client_side(coresList, marie2, &initialMarie2Stats, confAddr,
initialSubject, 1, FALSE);
BC_ASSERT_PTR_NOT_NULL(marie2Cr);
// Marie2 won't send 200OK to flexisip when receiving it's own outgoing message from marie1
sal_set_send_error(linphone_core_get_sal(marie2->lc), -1); // to trash 200ok without generating error
const char *marie1TextMessage = "Hum.";
LinphoneChatMessage *marie1Message = _send_message(marie1Cr, marie1TextMessage);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived,
initialPaulineStats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived,
initialMarie2Stats.number_of_LinphoneMessageReceived + 1,
liblinphone_tester_sip_timeout));
linphone_chat_message_unref(marie1Message);
wait_for_list(coresList, NULL, 0, 1000);
// Marie2 will now receive the message again but this time it will acknowledge it
sal_set_send_error(linphone_core_get_sal(marie2->lc), 0);
linphone_core_refresh_registers(marie2->lc);
// Check that the duplicate is detected and we are not notified of it, not it is stored in DB
BC_ASSERT_FALSE(wait_for_list(coresList, &marie2->stat.number_of_LinphoneMessageReceived,
initialMarie2Stats.number_of_LinphoneMessageReceived + 2,
liblinphone_tester_sip_timeout));
bctbx_list_t *messages = linphone_chat_room_get_history(marie2Cr, 0);
int count = (int)(bctbx_list_size(messages));
BC_ASSERT_EQUAL(count, 1, int, "%d");
bctbx_list_free_with_data(messages, (bctbx_list_free_func)linphone_chat_message_unref);
// Clean db from chat room
linphone_core_manager_delete_chat_room(marie1, marie1Cr, coresList);
linphone_core_manager_delete_chat_room(marie2, marie2Cr, coresList);
linphone_core_manager_delete_chat_room(pauline, paulineCr, coresList);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie1);
linphone_core_manager_destroy(marie2);
linphone_core_manager_destroy(pauline);
}
test_t group_chat_tests[] = {
TEST_NO_TAG("Chat room params", group_chat_room_params),
TEST_NO_TAG("Chat room with forced local identity", group_chat_room_creation_with_given_identity),
TEST_NO_TAG("Group chat room creation server", group_chat_room_creation_server),
TEST_NO_TAG("Network down while creating group chat room", group_chat_room_creation_server_network_down),
TEST_NO_TAG("Network down/up while creating group chat room", group_chat_room_creation_server_network_down_up),
TEST_ONE_TAG("Add participant", group_chat_room_add_participant, "LeaksMemory"),
TEST_NO_TAG("Send message", group_chat_room_send_message),
TEST_NO_TAG("Send encrypted message", group_chat_room_send_message_encrypted),
TEST_NO_TAG("Send message with error", group_chat_room_send_message_with_error),
TEST_NO_TAG("Send invite on a multi register account", group_chat_room_invite_multi_register_account),
TEST_NO_TAG("Send message check sync between devices",
group_chat_room_message_sync_between_devices_with_same_identity),
TEST_NO_TAG("Add admin", group_chat_room_add_admin),
TEST_NO_TAG("Add admin lately notified", group_chat_room_add_admin_lately_notified),
TEST_NO_TAG("Add admin with a non admin", group_chat_room_add_admin_non_admin),
TEST_NO_TAG("Remove admin", group_chat_room_remove_admin),
TEST_NO_TAG("Admin creator leaves the room", group_chat_room_admin_creator_leaves_the_room),
TEST_NO_TAG("Change subject", group_chat_room_change_subject),
TEST_NO_TAG("Change subject with a non admin", group_chat_room_change_subject_non_admin),
TEST_NO_TAG("Remove participant", group_chat_room_remove_participant),
TEST_ONE_TAG("Remove participant and restart",
8891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960
group_chat_room_remove_participant_and_restart,
"LeaksMemory"), // Due to core restart
TEST_NO_TAG("Send message with a participant removed", group_chat_room_send_message_with_participant_removed),
TEST_NO_TAG("Leave group chat room", group_chat_room_leave),
TEST_NO_TAG("Delete group chat room successful if it's already removed by server", group_chat_room_delete_twice),
TEST_NO_TAG("Come back on a group chat room after a disconnection", group_chat_room_come_back_after_disconnection),
TEST_NO_TAG("Create chat room with disconnected friends", group_chat_room_create_room_with_disconnected_friends),
TEST_NO_TAG("Create chat room with disconnected friends and initial message",
group_chat_room_create_room_with_disconnected_friends_and_initial_message),
TEST_NO_TAG("Reinvited after removed from group chat room", group_chat_room_reinvited_after_removed)};
test_t group_chat2_tests[] = {
TEST_NO_TAG("Send file + text", group_chat_room_send_file_plus_text),
TEST_NO_TAG("Send 2 files + text", group_chat_room_send_two_files_plus_text),
TEST_NO_TAG("Send multipart message with custom content types",
group_chat_room_send_multipart_custom_content_types),
TEST_NO_TAG("Unique one-to-one chatroom", group_chat_room_unique_one_to_one_chat_room),
TEST_NO_TAG("Unique one-to-one chatroom with dual sender device",
group_chat_room_unique_one_to_one_chat_room_dual_sender_device),
TEST_NO_TAG("Unique one-to-one chatroom recreated from message",
group_chat_room_unique_one_to_one_chat_room_recreated_from_message),
TEST_ONE_TAG("Unique one-to-one chatroom recreated from message with app restart",
group_chat_room_unique_one_to_one_chat_room_recreated_from_message_with_app_restart,
"LeaksMemory"),
TEST_NO_TAG("Join one-to-one chat room with a new device",
group_chat_room_join_one_to_one_chat_room_with_a_new_device),
TEST_NO_TAG("New unique one-to-one chatroom after both participants left",
group_chat_room_new_unique_one_to_one_chat_room_after_both_participants_left),
TEST_NO_TAG("Unique one-to-one chatroom re-created from the party that deleted it, with inactive devices",
group_chat_room_unique_one_to_one_chat_room_recreated_from_message_2),
TEST_ONE_TAG("Group chat room notify participant devices name",
group_chat_room_participant_devices_name,
"LeaksMemory" /* Core restarts */),
TEST_NO_TAG("Add device in one-to-one chat room where other participant left",
add_device_one_to_one_chat_room_other_left),
TEST_NO_TAG("IMDN for group chat room", imdn_for_group_chat_room),
TEST_NO_TAG("Aggregated IMDN for group chat room", aggregated_imdn_for_group_chat_room),
TEST_NO_TAG("Aggregated IMDN for group chat room read while offline",
aggregated_imdn_for_group_chat_room_read_while_offline),
TEST_ONE_TAG("IMDN sent from DB state", imdn_sent_from_db_state, "LeaksMemory"),
TEST_NO_TAG("IMDN updated for group chat room with one participant offline",
imdn_updated_for_group_chat_room_with_one_participant_offline),
TEST_NO_TAG("Find one-to-one chat room", find_one_to_one_chat_room),
TEST_NO_TAG("Exhumed one-to-one chat room 1", exhume_one_to_one_chat_room_1),
TEST_NO_TAG("Exhumed one-to-one chat room 2", exhume_one_to_one_chat_room_2),
TEST_NO_TAG("Exhumed one-to-one chat room 3", exhume_one_to_one_chat_room_3),
TEST_ONE_TAG("Exhumed one-to-one chat room 3 with core restart",
exhume_one_to_one_chat_room_3_core_restart,
"LeaksMemory" /*due to core restart*/),
TEST_NO_TAG("Exhumed one-to-one chat room 4", exhume_one_to_one_chat_room_4),
TEST_NO_TAG("New device after group chat room creation", group_chat_room_new_device_after_creation),
TEST_ONE_TAG("Chat room list subscription", group_chat_room_list_subscription, "LeaksMemory"),
TEST_ONE_TAG(
"Complex participant removal scenario", group_chat_room_complex_participant_removal_scenario, "LeaksMemory"),
TEST_NO_TAG("Group chat room subscription denied", group_chat_room_subscription_denied),
TEST_ONE_TAG("Search friend result chat room participants", search_friend_chat_room_participants, "MagicSearch"),
TEST_ONE_TAG("Client loose context of a chatroom", group_chat_loss_of_client_context, "LeaksMemory")};
test_t group_chat3_tests[] = {
TEST_ONE_TAG(
"Participant removed then added", participant_removed_then_added, "LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Check if participant device are removed",
group_chat_room_join_one_to_one_chat_room_with_a_new_device_not_notified,
"LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Subscribe successful after set chat database path",
subscribe_test_after_set_chat_database_path,
"LeaksMemory" /*due to core restart*/),
TEST_NO_TAG("Send forward message", one_to_one_chat_room_send_forward_message),
TEST_ONE_TAG("Send forward message with restart",
one_to_one_chat_room_send_forward_message_with_restart,
8961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030
"LeaksMemory" /*due to core restart*/),
TEST_NO_TAG("Send reply message", one_to_one_chat_room_reply_forward_message),
TEST_ONE_TAG("Send reply message with core restart",
one_to_one_chat_room_reply_forward_message_with_restart,
"LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Linphone core stop/start and chatroom ref",
core_stop_start_with_chat_room_ref,
"LeaksMemory" /*due to core restart*/),
TEST_ONE_TAG("Subscribe successful after set chat database path",
subscribe_test_after_set_chat_database_path,
"LeaksMemory" /*due to core restart*/),
TEST_NO_TAG("Make sure device unregistration does not triger user to be removed from a group",
group_chat_room_device_unregistered),
TEST_NO_TAG("Admin leaves the room and is reinvited", group_chat_room_admin_creator_leaves_and_is_reinvited),
TEST_NO_TAG("Forward file transfer message", group_chat_forward_file_transfer_message),
TEST_NO_TAG("Forward file transfer message using digest auth on server",
group_chat_forward_file_transfer_message_digest_auth_server),
TEST_NO_TAG("Forward file transfer message using digest auth on server and encrypted FS",
group_chat_forward_file_transfer_message_digest_auth_server_encryptedFS),
};
test_t group_chat4_tests[] = {
TEST_ONE_TAG(
"Reinvited after removed from group chat room 2", group_chat_room_reinvited_after_removed_2, "LeaksMemory"),
TEST_ONE_TAG("Reinvited after removed from group chat room while offline",
group_chat_room_reinvited_after_removed_while_offline,
"LeaksMemory"),
TEST_ONE_TAG("Reinvited after removed from group chat room while offline 2",
group_chat_room_reinvited_after_removed_while_offline_2,
"LeaksMemory"),
TEST_NO_TAG("Reinvited after removed from group chat room with several devices",
group_chat_room_reinvited_after_removed_with_several_devices),
TEST_NO_TAG("Notify after disconnection", group_chat_room_notify_after_disconnection),
TEST_ONE_TAG("Notify after core restart",
group_chat_room_notify_after_core_restart,
"LeaksMemory"), /* due to Core restart */
TEST_NO_TAG("Send refer to all participants devices", group_chat_room_send_refer_to_all_devices),
TEST_NO_TAG("Admin add device and doesn't lose admin status", group_chat_room_add_device),
TEST_NO_TAG("Send multiple is composing", multiple_is_composing_notification),
TEST_ONE_TAG("Fallback to basic chat room", group_chat_room_fallback_to_basic_chat_room, "LeaksMemory"),
TEST_NO_TAG("Group chat room creation fails if invited participants don't support it",
group_chat_room_creation_fails_if_invited_participants_dont_support_it),
TEST_NO_TAG("Group chat room creation successful if at least one invited participant supports it",
group_chat_room_creation_successful_if_at_least_one_invited_participant_supports_it),
TEST_ONE_TAG(
"Migrate basic chat room to client group chat room", group_chat_room_migrate_from_basic_chat_room, "Migration"),
TEST_TWO_TAGS("Migrate basic chat room to client group chat room failure",
group_chat_room_migrate_from_basic_to_client_fail,
"LeaksMemory",
"Migration"),
TEST_ONE_TAG("Migrate basic chat room to client group chat room not needed",
group_chat_donot_room_migrate_from_basic_chat_room,
"Migration"),
TEST_NO_TAG("Send file", group_chat_room_send_file),
TEST_NO_TAG("Send file using buffer", group_chat_room_send_file_2)};
test_suite_t group_chat_test_suite = {"Group Chat",
NULL,
NULL,
liblinphone_tester_before_each,
liblinphone_tester_after_each,
sizeof(group_chat_tests) / sizeof(group_chat_tests[0]),
group_chat_tests,
0};
test_suite_t group_chat2_test_suite = {"Group Chat2",
NULL,
NULL,
liblinphone_tester_before_each,
liblinphone_tester_after_each,
90319032903390349035903690379038903990409041904290439044904590469047904890499050905190529053905490559056
sizeof(group_chat2_tests) / sizeof(group_chat2_tests[0]),
group_chat2_tests,
0};
test_suite_t group_chat3_test_suite = {"Group Chat3",
NULL,
NULL,
liblinphone_tester_before_each,
liblinphone_tester_after_each,
sizeof(group_chat3_tests) / sizeof(group_chat3_tests[0]),
group_chat3_tests,
0};
test_suite_t group_chat4_test_suite = {"Group Chat4",
NULL,
NULL,
liblinphone_tester_before_each,
liblinphone_tester_after_each,
sizeof(group_chat4_tests) / sizeof(group_chat4_tests[0]),
group_chat4_tests,
0};
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
#pragma GCC diagnostic pop
#endif