Commit 5ff20768 authored by Ghislain MARY's avatar Ghislain MARY

Handle basic to client group chat room migration.

parent 1f15bc62
......@@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "call/call-p.h"
#include "chat/chat-room/chat-room.h"
#include "core/core.h"
#include "core/core-p.h"
#include "c-wrapper/c-wrapper.h"
#include "conference/session/media-session-p.h"
......@@ -154,3 +154,8 @@ int _linphone_call_get_main_video_stream_index (const LinphoneCall *call) {
return L_GET_PRIVATE(static_pointer_cast<LinphonePrivate::MediaSession>(
L_GET_PRIVATE_FROM_C_OBJECT(call)->getActiveSession()))->getMainVideoStreamIndex();
}
void _linphone_chat_room_enable_migration(LinphoneChatRoom *cr, bool_t enable) {
shared_ptr<AbstractChatRoom> acr = L_GET_CPP_PTR_FROM_C_OBJECT(cr);
L_GET_PRIVATE(acr->getCore())->mainDb->enableChatRoomMigration(acr->getChatRoomId(), !!enable);
}
......@@ -103,6 +103,8 @@ LINPHONE_PUBLIC mblk_t *_linphone_call_stats_get_received_rtcp (const LinphoneCa
LINPHONE_PUBLIC LinphoneQualityReporting *linphone_call_log_get_quality_reporting(LinphoneCallLog *call_log);
LINPHONE_PUBLIC reporting_session_report_t **linphone_quality_reporting_get_reports(LinphoneQualityReporting *qreporting);
LINPHONE_PUBLIC void _linphone_chat_room_enable_migration(LinphoneChatRoom *cr, bool_t enable);
LINPHONE_PUBLIC MSList* linphone_core_fetch_friends_from_db(LinphoneCore *lc, LinphoneFriendList *list);
LINPHONE_PUBLIC MSList* linphone_core_fetch_friends_lists_from_db(LinphoneCore *lc);
LINPHONE_PUBLIC void linphone_friend_invalidate_subscription(LinphoneFriend *lf);
......
......@@ -35,6 +35,7 @@
F(Basic, 1 << 0) \
F(RealTimeText, 1 << 1) \
F(Conference, 1 << 2) \
F(Proxy, 1 << 3)
F(Proxy, 1 << 3) \
F(Migratable, 1 << 4)
#endif // ifndef _CHAT_ROOM_ENUMS_H_
......@@ -90,6 +90,8 @@ public:
void loadFileTransferUrlFromBodyToContent();
void setChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
// -----------------------------------------------------------------------------
// Deprecated methods only used for C wrapper, to be removed some day...
// -----------------------------------------------------------------------------
......
......@@ -312,6 +312,18 @@ void ChatMessagePrivate::loadFileTransferUrlFromBodyToContent() {
fileTransferChatMessageModifier.decode(q->getSharedFromThis(), errorCode);
}
void ChatMessagePrivate::setChatRoom (const shared_ptr<AbstractChatRoom> &cr) {
chatRoom = cr;
chatRoomId = cr->getChatRoomId();
if (direction == ChatMessage::Direction::Outgoing) {
fromAddress = chatRoomId.getLocalAddress();
toAddress = chatRoomId.getPeerAddress();
} else {
fromAddress = chatRoomId.getPeerAddress();
toAddress = chatRoomId.getLocalAddress();
}
}
// -----------------------------------------------------------------------------
void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
......@@ -672,16 +684,8 @@ ChatMessage::ChatMessage (const shared_ptr<AbstractChatRoom> &chatRoom, ChatMess
Object(*new ChatMessagePrivate), CoreAccessor(chatRoom->getCore()) {
L_D();
d->chatRoom = chatRoom;
d->chatRoomId = chatRoom->getChatRoomId();
if (direction == Direction::Outgoing) {
d->fromAddress = d->chatRoomId.getLocalAddress();
d->toAddress = d->chatRoomId.getPeerAddress();
} else {
d->fromAddress = d->chatRoomId.getPeerAddress();
d->toAddress = d->chatRoomId.getLocalAddress();
}
d->direction = direction;
d->setChatRoom(chatRoom);
}
ChatMessage::~ChatMessage () {
......
......@@ -41,6 +41,8 @@ class FileTransferContent;
class ChatMessagePrivate;
class LINPHONE_PUBLIC ChatMessage : public Object, public CoreAccessor {
friend class BasicToClientGroupChatRoom;
friend class BasicToClientGroupChatRoomPrivate;
friend class ChatRoom;
friend class ChatRoomPrivate;
friend class CpimChatMessageModifier;
......
......@@ -19,6 +19,12 @@
#include "basic-to-client-group-chat-room.h"
#include "proxy-chat-room-p.h"
#include "client-group-chat-room-p.h"
#include "chat/chat-message/chat-message-p.h"
#include "conference/participant.h"
#include "conference/session/call-session.h"
#include "core/core-p.h"
#include "c-wrapper/c-wrapper.h"
// =============================================================================
......@@ -30,15 +36,53 @@ LINPHONE_BEGIN_NAMESPACE
class BasicToClientGroupChatRoomPrivate : public ProxyChatRoomPrivate {
public:
inline void sendChatMessage (const shared_ptr<ChatMessage> &chatMessage) override {
void onChatRoomInsertRequested (const shared_ptr<AbstractChatRoom> &chatRoom) override {
L_Q();
// Insert the client group chat room temporarily
q->getCore()->getPrivate()->insertChatRoom(chatRoom);
}
void onChatRoomInsertInDatabaseRequested (const shared_ptr<AbstractChatRoom> &chatRoom) override {
// Do not insert the client group chat room in database, the migration will do it
}
void sendChatMessage (const shared_ptr<ChatMessage> &chatMessage) override {
ProxyChatRoomPrivate::sendChatMessage(chatMessage);
// TODO: Try migration.
if (!linphone_core_get_conference_factory_uri(chatMessage->getCore()->getCCore())
|| (chatRoom->getCapabilities() & ChatRoom::Capabilities::Conference)
|| clientGroupChatRoom
) {
return;
}
clientGroupChatRoom = static_pointer_cast<ClientGroupChatRoom>(
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), false)
);
clientGroupChatRoom->getPrivate()->setCallSessionListener(this);
clientGroupChatRoom->getPrivate()->setChatRoomListener(this);
clientGroupChatRoom->addParticipant(chatRoom->getPeerAddress(), nullptr, false);
}
inline void onChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) override {
ProxyChatRoomPrivate::onChatMessageReceived(chatMessage);
// TODO: Try migration.
void onCallSessionStateChanged (
const shared_ptr<const CallSession> &session,
LinphoneCallState newState,
const string &message
) override {
if (!clientGroupChatRoom)
return;
if ((newState == LinphoneCallError) && (clientGroupChatRoom->getState() == ChatRoom::State::CreationPending)) {
Core::deleteChatRoom(clientGroupChatRoom);
if (session->getReason() == LinphoneReasonNotAcceptable) {
clientGroupChatRoom = nullptr;
return;
}
}
clientGroupChatRoom->getPrivate()->onCallSessionStateChanged(session, newState, message);
}
private:
shared_ptr<ClientGroupChatRoom> clientGroupChatRoom;
L_DECLARE_PUBLIC(BasicToClientGroupChatRoom);
};
// =============================================================================
......@@ -46,4 +90,30 @@ public:
BasicToClientGroupChatRoom::BasicToClientGroupChatRoom (const shared_ptr<ChatRoom> &chatRoom) :
ProxyChatRoom(*new BasicToClientGroupChatRoomPrivate, chatRoom) {}
shared_ptr<ChatMessage> BasicToClientGroupChatRoom::createChatMessage () {
shared_ptr<ChatMessage> msg = ProxyChatRoom::createChatMessage();
msg->getPrivate()->setChatRoom(getSharedFromThis());
return msg;
}
shared_ptr<ChatMessage> BasicToClientGroupChatRoom::createChatMessage (const string &text) {
shared_ptr<ChatMessage> msg = ProxyChatRoom::createChatMessage(text);
msg->getPrivate()->setChatRoom(getSharedFromThis());
return msg;
}
void BasicToClientGroupChatRoom::migrate(const std::shared_ptr<ClientGroupChatRoom> &clientGroupChatRoom, const std::shared_ptr<AbstractChatRoom> &chatRoom) {
clientGroupChatRoom->getCore()->getPrivate()->mainDb->migrateBasicToClientGroupChatRoom(chatRoom, clientGroupChatRoom);
if (chatRoom->getCapabilities() & ChatRoom::Capabilities::Proxy) {
shared_ptr<BasicToClientGroupChatRoom> btcgcr = static_pointer_cast<BasicToClientGroupChatRoom>(chatRoom);
btcgcr->getCore()->getPrivate()->replaceChatRoom(chatRoom, clientGroupChatRoom);
btcgcr->getPrivate()->chatRoom = clientGroupChatRoom;
} else {
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(chatRoom);
L_SET_CPP_PTR_FROM_C_OBJECT(lcr, clientGroupChatRoom);
clientGroupChatRoom->getCore()->getPrivate()->replaceChatRoom(chatRoom, clientGroupChatRoom);
}
}
LINPHONE_END_NAMESPACE
......@@ -27,11 +27,17 @@
LINPHONE_BEGIN_NAMESPACE
class BasicToClientGroupChatRoomPrivate;
class ClientGroupChatRoom;
class LINPHONE_PUBLIC BasicToClientGroupChatRoom : public ProxyChatRoom {
public:
BasicToClientGroupChatRoom (const std::shared_ptr<ChatRoom> &chatRoom);
std::shared_ptr<ChatMessage> createChatMessage () override;
std::shared_ptr<ChatMessage> createChatMessage (const std::string &text) override;
static void migrate(const std::shared_ptr<ClientGroupChatRoom> &clientGroupChatRoom, const std::shared_ptr<AbstractChatRoom> &chatRoom);
private:
L_DECLARE_PRIVATE(BasicToClientGroupChatRoom);
L_DISABLE_COPY(BasicToClientGroupChatRoom);
......
......@@ -21,6 +21,8 @@
#include "address/address-p.h"
#include "c-wrapper/c-wrapper.h"
#include "basic-chat-room.h"
#include "basic-to-client-group-chat-room.h"
#include "client-group-chat-room-p.h"
#include "conference/handlers/remote-conference-event-handler.h"
#include "conference/participant-p.h"
......@@ -382,6 +384,15 @@ void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
L_D();
d->setState(ChatRoom::State::Created);
if (getParticipantCount() == 1) {
ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress());
shared_ptr<AbstractChatRoom> chatRoom = getCore()->findChatRoom(id);
if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) {
BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom);
return;
}
}
d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis());
// TODO: Bug. Event is inserted many times.
......
......@@ -30,9 +30,12 @@ LINPHONE_BEGIN_NAMESPACE
class ClientGroupChatRoomPrivate;
class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConference {
friend class BasicToClientGroupChatRoomPrivate;
friend class ClientGroupToBasicChatRoomPrivate;
public:
L_OVERRIDE_SHARED_FROM_THIS(ClientGroupChatRoom);
// TODO: Make me private.
ClientGroupChatRoom (
const std::shared_ptr<Core> &core,
......
......@@ -21,6 +21,7 @@
#include "address/identity-address.h"
#include "chat/chat-room/basic-chat-room.h"
#include "chat/chat-room/basic-to-client-group-chat-room.h"
#include "chat/chat-room/chat-room-p.h"
#include "chat/chat-room/real-time-text-chat-room.h"
#include "conference/participant.h"
......@@ -63,16 +64,24 @@ static IdentityAddress getDefaultLocalAddress (const shared_ptr<Core> &core, con
shared_ptr<AbstractChatRoom> CorePrivate::createBasicChatRoom (
const ChatRoomId &chatRoomId,
bool isRtt
ChatRoom::CapabilitiesMask capabilities
) {
L_Q();
shared_ptr<AbstractChatRoom> chatRoom;
if (isRtt)
if (capabilities & ChatRoom::Capabilities::RealTimeText)
chatRoom.reset(new RealTimeTextChatRoom(q->getSharedFromThis(), chatRoomId));
else
chatRoom.reset(new BasicChatRoom(q->getSharedFromThis(), chatRoomId));
else {
bool isToMigrate = (capabilities & ChatRoom::Capabilities::Migratable);
if (isToMigrate) {
shared_ptr<BasicChatRoom> bcr;
bcr.reset(new BasicChatRoom(q->getSharedFromThis(), chatRoomId));
chatRoom.reset(new BasicToClientGroupChatRoom(bcr));
} else {
chatRoom.reset(new BasicChatRoom(q->getSharedFromThis(), chatRoomId));
}
}
AbstractChatRoomPrivate *dChatRoom = chatRoom->getPrivate();
dChatRoom->setState(ChatRoom::State::Instantiated);
......@@ -81,6 +90,18 @@ shared_ptr<AbstractChatRoom> CorePrivate::createBasicChatRoom (
return chatRoom;
}
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const string &subject, bool fallback) {
L_Q();
return L_GET_CPP_PTR_FROM_C_OBJECT(
_linphone_client_group_chat_room_new(
q->getCCore(),
linphone_core_get_conference_factory_uri(q->getCCore()),
L_STRING_TO_C(subject),
fallback ? TRUE : FALSE
)
);
}
void CorePrivate::insertChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom) {
L_ASSERT(chatRoom);
L_Q();
......@@ -95,6 +116,20 @@ void CorePrivate::insertChatRoomWithDb (const shared_ptr<AbstractChatRoom> &chat
mainDb->insertChatRoom(chatRoom);
}
void CorePrivate::replaceChatRoom (const shared_ptr<AbstractChatRoom> &replacedChatRoom, const shared_ptr<AbstractChatRoom> &newChatRoom) {
const ChatRoomId &replacedChatRoomId = replacedChatRoom->getChatRoomId();
const ChatRoomId &newChatRoomId = newChatRoom->getChatRoomId();
if (replacedChatRoom->getCapabilities() & ChatRoom::Capabilities::Proxy) {
chatRooms.remove(newChatRoom);
chatRoomsById.erase(newChatRoomId);
chatRoomsById[newChatRoomId] = replacedChatRoom;
} else {
chatRooms.remove(replacedChatRoom);
chatRoomsById.erase(replacedChatRoomId);
chatRoomsById[newChatRoomId] = newChatRoom;
}
}
// -----------------------------------------------------------------------------
const list<shared_ptr<AbstractChatRoom>> &Core::getChatRooms () const {
......@@ -146,14 +181,8 @@ shared_ptr<AbstractChatRoom> Core::findOneToOneChatRoom (
}
shared_ptr<AbstractChatRoom> Core::createClientGroupChatRoom (const string &subject) {
return L_GET_CPP_PTR_FROM_C_OBJECT(
_linphone_client_group_chat_room_new(
getCCore(),
linphone_core_get_conference_factory_uri(getCCore()),
L_STRING_TO_C(subject),
TRUE
)
);
L_D();
return d->createClientGroupChatRoom(subject, true);
}
shared_ptr<AbstractChatRoom> Core::getOrCreateBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt) {
......@@ -163,7 +192,9 @@ shared_ptr<AbstractChatRoom> Core::getOrCreateBasicChatRoom (const ChatRoomId &c
if (chatRoom)
return chatRoom;
chatRoom = d->createBasicChatRoom(chatRoomId, isRtt);
chatRoom = d->createBasicChatRoom(chatRoomId,
isRtt ? ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::RealTimeText) : ChatRoom::CapabilitiesMask()
);
d->insertChatRoom(chatRoom);
d->insertChatRoomWithDb(chatRoom);
......@@ -179,7 +210,7 @@ shared_ptr<AbstractChatRoom> Core::getOrCreateBasicChatRoom (const IdentityAddre
shared_ptr<AbstractChatRoom> chatRoom = d->createBasicChatRoom(
ChatRoomId(peerAddress, getDefaultLocalAddress(getSharedFromThis(), peerAddress)),
isRtt
isRtt ? ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::RealTimeText) : ChatRoom::CapabilitiesMask()
);
d->insertChatRoom(chatRoom);
d->insertChatRoomWithDb(chatRoom);
......
......@@ -20,6 +20,7 @@
#ifndef _CORE_P_H_
#define _CORE_P_H_
#include "chat/chat-room/abstract-chat-room.h"
#include "core.h"
#include "db/main-db.h"
#include "object/object-p.h"
......@@ -58,7 +59,9 @@ public:
void insertChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
void insertChatRoomWithDb (const std::shared_ptr<AbstractChatRoom> &chatRoom);
std::shared_ptr<AbstractChatRoom> createBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt);
std::shared_ptr<AbstractChatRoom> createBasicChatRoom (const ChatRoomId &chatRoomId, AbstractChatRoom::CapabilitiesMask capabilities);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, bool fallback = true);
void replaceChatRoom (const std::shared_ptr<AbstractChatRoom> &replacedChatRoom, const std::shared_ptr<AbstractChatRoom> &newChatRoom);
std::unique_ptr<MainDb> mainDb;
......
......@@ -40,6 +40,8 @@ class IdentityAddress;
class AbstractChatRoom;
class LINPHONE_PUBLIC Core : public Object {
friend class BasicToClientGroupChatRoom;
friend class BasicToClientGroupChatRoomPrivate;
friend class CallPrivate;
friend class CallSession;
friend class ChatMessagePrivate;
......
......@@ -229,7 +229,9 @@ static constexpr string &blobToString (string &in) {
return id;
}
static const int capabilities = ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::Basic);
static const int capabilities = ChatRoom::CapabilitiesMask(
{ ChatRoom::Capabilities::Basic, ChatRoom::Capabilities::Migratable }
);
lInfo() << "Insert new chat room in database: (peer=" << peerSipAddressId <<
", local=" << localSipAddressId << ", capabilities=" << capabilities << ").";
*session << "INSERT INTO chat_room ("
......@@ -2064,10 +2066,7 @@ static constexpr string &blobToString (string &in) {
: static_cast<unsigned int>(row.get<int>(7, 0));
if (capabilities & ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::Basic)) {
chatRoom = core->getPrivate()->createBasicChatRoom(
chatRoomId,
capabilities & ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::RealTimeText)
);
chatRoom = core->getPrivate()->createBasicChatRoom(chatRoomId, capabilities);
chatRoom->setSubject(subject);
} else if (capabilities & ChatRoom::CapabilitiesMask(ChatRoom::Capabilities::Conference)) {
list<shared_ptr<Participant>> participants;
......@@ -2273,6 +2272,32 @@ static constexpr string &blobToString (string &in) {
L_END_LOG_EXCEPTION
}
void MainDb::enableChatRoomMigration (const ChatRoomId &chatRoomId, bool enable) {
L_D();
if (!isConnected()) {
lWarning() << "Unable to enable chat room migration. Not connected.";
return;
}
L_BEGIN_LOG_EXCEPTION
const long long &dbChatRoomId = d->selectChatRoomId(chatRoomId);
soci::session *session = d->dbSession.getBackendSession<soci::session>();
int capabilities = 0;
*session << "SELECT capabilities FROM chat_room WHERE id = :chatRoomId",
soci::use(dbChatRoomId), soci::into(capabilities);
if (enable)
capabilities |= static_cast<int>(ChatRoom::Capabilities::Migratable);
else
capabilities &= ~static_cast<int>(ChatRoom::Capabilities::Migratable);
*session << "UPDATE chat_room SET capabilities = :capabilities WHERE id = :chatRoomId",
soci::use(capabilities), soci::use(dbChatRoomId);
L_END_LOG_EXCEPTION
}
// -----------------------------------------------------------------------------
#define LEGACY_MESSAGE_COL_LOCAL_ADDRESS 1
......
......@@ -118,6 +118,7 @@ public:
std::list<std::shared_ptr<AbstractChatRoom>> getChatRooms () const;
void insertChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
void deleteChatRoom (const ChatRoomId &chatRoomId);
void enableChatRoomMigration (const ChatRoomId &chatRoomId, bool enable);
void migrateBasicToClientGroupChatRoom (
const std::shared_ptr<AbstractChatRoom> &basicChatRoom,
......
......@@ -1612,6 +1612,89 @@ static void group_chat_room_creation_successful_if_at_least_one_invited_particip
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;
int dummy = 0;
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 create on Pauline's side
LinphoneChatMessage *msg = linphone_chat_room_create_message(marieCr, "Hey Pauline!");
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 1, 1000));
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);
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);
// 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) {
initialMarieStats = marie->stat;
initialPaulineStats = pauline->stat;
BC_ASSERT_EQUAL(linphone_chat_room_get_capabilities(marieCr), LinphoneChatRoomCapabilitiesBasic | LinphoneChatRoomCapabilitiesProxy, int, "%d");
msg = linphone_chat_room_create_message(marieCr, "Did you migrate?");
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
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_LinphoneChatRoomStateCreationPending, initialPaulineStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneChatRoomStateCreated, initialPaulineStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
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, 1000));
BC_ASSERT_EQUAL(linphone_chat_room_get_history_size(paulineCr), 2, int, "%d");
msg = linphone_chat_room_create_message(marieCr, "Let's go drink a beer");
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &pauline->stat.number_of_LinphoneMessageReceived, initialPaulineStats.number_of_LinphoneMessageReceived + 2, 1000));
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(paulineCr, "Let's go drink mineral water instead");
linphone_chat_message_send(msg);
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneMessageReceived, initialMarieStats.number_of_LinphoneMessageReceived + 1, 1000));
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(marie->lc, paulineCr);
wait_for_list(coresList, &dummy, 1, 1000);
bctbx_list_free(coresList);
bctbx_list_free(coresManagerList);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
test_t group_chat_tests[] = {
TEST_TWO_TAGS("Group chat room creation server", group_chat_room_creation_server, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Send message", group_chat_room_send_message, "Server", "LeaksMemory"),
......@@ -1633,7 +1716,8 @@ test_t group_chat_tests[] = {
TEST_TWO_TAGS("Create chat room with incompatible friend", group_chat_room_create_room_with_incompatible_friend, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Fallback to basic chat room", group_chat_room_fallback_to_basic_chat_room, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Group chat room creation fails if invited participants don't support it", group_chat_room_creation_fails_if_invited_participants_dont_support_it, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Group chat room creation succesful if at least one invited participant supports it", group_chat_room_creation_successful_if_at_least_one_invited_participant_supports_it, "Server", "LeaksMemory")
TEST_TWO_TAGS("Group chat room creation succesful if at least one invited participant supports it", group_chat_room_creation_successful_if_at_least_one_invited_participant_supports_it, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Migrate basic chat room to client group chat room", group_chat_room_migrate_from_basic_chat_room, "Server", "LeaksMemory")
};
test_suite_t group_chat_test_suite = {
......
......@@ -299,6 +299,7 @@ typedef struct _LinphoneCoreManager {
bool_t decline_subscribe;
int number_of_bcunit_error_at_creation;
char* phone_alias;
char *rc_path;
} LinphoneCoreManager;
typedef struct _LinphoneConferenceServer {
......@@ -318,13 +319,14 @@ typedef struct _LinphoneCallTestParams {
void liblinphone_tester_add_suites(void);
void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, const char* phone_alias);
void linphone_core_manager_start(LinphoneCoreManager *mgr, int check_for_proxies);
void linphone_core_manager_start(LinphoneCoreManager *mgr, bool_t check_for_proxies);
LinphoneCoreManager* linphone_core_manager_create2(const char* rc_file, const char* phone_alias);
LinphoneCoreManager* linphone_core_manager_create(const char* rc_file);
LinphoneCoreManager* linphone_core_manager_new3(const char* rc_file, int check_for_proxies, const char* phone_alias);
LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, int check_for_proxies);
LinphoneCoreManager* linphone_core_manager_new3(const char* rc_file, bool_t check_for_proxies, const char* phone_alias);
LinphoneCoreManager* linphone_core_manager_new2(const char* rc_file, bool_t check_for_proxies);
LinphoneCoreManager* linphone_core_manager_new(const char* rc_file);
void linphone_core_manager_stop(LinphoneCoreManager *mgr);
void linphone_core_manager_restart(LinphoneCoreManager *mgr, bool_t check_for_proxies);
void linphone_core_manager_uninit(LinphoneCoreManager *mgr);
void linphone_core_manager_wait_for_stun_resolution(LinphoneCoreManager *mgr);
void linphone_core_manager_destroy(LinphoneCoreManager* mgr);
......
......@@ -290,45 +290,11 @@ bool_t transport_supported(LinphoneTransportType transport) {
}
}
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
#pragma GCC diagnostic push
#endif
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#else
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, const char* phone_alias) {
void linphone_core_manager_configure (LinphoneCoreManager *mgr) {
LinphoneImNotifPolicy *im_notif_policy;
char *rc_path = NULL;
char *hellopath = bc_tester_res("sounds/hello8000.wav");
mgr->number_of_bcunit_error_at_creation = bc_get_number_of_failures();
mgr->v_table.registration_state_changed=registration_state_changed;
mgr->v_table.auth_info_requested=auth_info_requested;
mgr->v_table.call_state_changed=call_state_changed;
mgr->v_table.text_received=text_message_received;
mgr->v_table.message_received=message_received;
mgr->v_table.is_composing_received=is_composing_received;
mgr->v_table.new_subscription_requested=new_subscription_requested;
mgr->v_table.notify_presence_received=notify_presence_received;
mgr->v_table.notify_presence_received_for_uri_or_tel=notify_presence_received_for_uri_or_tel;
mgr->v_table.transfer_state_changed=linphone_transfer_state_changed;
mgr->v_table.info_received=info_message_received;
mgr->v_table.subscription_state_changed=linphone_subscription_state_change;
mgr->v_table.notify_received=linphone_notify_received;
mgr->v_table.publish_state_changed=linphone_publish_state_changed;
mgr->v_table.configuring_status=linphone_configuration_status;
mgr->v_table.call_encryption_changed=linphone_call_encryption_changed;
mgr->v_table.network_reachable=network_reachable;
mgr->v_table.dtmf_received=dtmf_received;
mgr->v_table.call_stats_updated=call_stats_updated;
mgr->phone_alias = phone_alias ? ms_strdup(phone_alias) : NULL;
reset_counters(&mgr->stat);
if (rc_file) rc_path = ms_strdup_printf("rcfiles/%s", rc_file);
mgr->lc=configure_lc_from(&mgr->v_table, bc_tester_get_resource_dir_prefix(), rc_path, mgr);
mgr->lc=configure_lc_from(&mgr->v_table, bc_tester_get_resource_dir_prefix(), mgr->rc_path, mgr);
linphone_core_manager_check_accounts(mgr);
im_notif_policy = linphone_core_get_im_notif_policy(mgr->lc);
if (im_notif_policy != NULL) {
......@@ -338,8 +304,6 @@ void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, c
linphone_im_notif_policy_set_recv_is_composing(im_notif_policy, TRUE);
}
manager_count++;
#if TARGET_OS_IPHONE
linphone_core_set_ringer_device( mgr->lc, "AQ: Audio Queue Device");
linphone_core_set_ringback(mgr->lc, NULL);
......@@ -369,7 +333,7 @@ void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, c
if( manager_count >= 2){
char *recordpath = ms_strdup_printf("%s/record_for_lc_%p.wav",bc_tester_get_writable_dir_prefix(),mgr->lc);
ms_message("Manager for '%s' using files", rc_file ? rc_file : "--");
ms_message("Manager for '%s' using files", mgr->rc_path ? mgr->rc_path : "--");
linphone_core_set_use_files(mgr->lc, TRUE);
linphone_core_set_record_file(mgr->lc,recordpath);
ms_free(recordpath);
......@@ -378,14 +342,52 @@ void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, c
linphone_core_set_user_certificates_path(mgr->lc,bc_tester_get_writable_dir_prefix());
/*for now, we need the periodical updates facility to compute bandwidth measurements correctly during tests*/
linphone_core_enable_send_call_stats_periodical_updates(mgr->lc, TRUE);
}
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
#pragma GCC diagnostic push
#endif
#ifdef _MSC_VER
#pragma warning(disable : 4996)
#else
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
#endif
void linphone_core_manager_init(LinphoneCoreManager *mgr, const char* rc_file, const char* phone_alias) {
mgr->number_of_bcunit_error_at_creation = bc_get_number_of_failures();
mgr->v_table.registration_state_changed=registration_state_changed;
mgr->v_table.auth_info_requested=auth_info_requested;
mgr->v_table.call_state_changed=call_state_changed;
mgr->v_table.text_received=text_message_received;
mgr->v_table.message_received=message_received;
mgr->v_table.is_composing_received=is_composing_received;
mgr->v_table.new_subscription_requested=new_subscription_requested;
mgr->v_table.notify_presence_received=notify_presence_received;
mgr->v_table.notify_presence_received_for_uri_or_tel=notify_presence_received_for_uri_or_tel;
mgr->v_table.transfer_state_changed=linphone_transfer_state_changed;
mgr->v_table.info_received=info_message_received;
mgr->v_table.subscription_state_changed=linphone_subscription_state_change;
mgr->v_table.notify_received=linphone_notify_received;
mgr->v_table.publish_state_changed=linphone_publish_state_changed;
mgr->v_table.configuring_status=linphone_configuration_status;
mgr->v_table.call_encryption_changed=linphone_call_encryption_changed;
mgr->v_table.network_reachable=network_reachable;
mgr->v_table.dtmf_received=dtmf_received;
mgr->v_table.call_stats_updated=call_stats_updated;
if (rc_path) ms_free(rc_path);
mgr->phone_alias = phone_alias ? ms_strdup(phone_alias) : NULL;
reset_counters(&mgr->stat);
if (rc_file) mgr->rc_path = ms_strdup_printf("rcfiles/%s", rc_file);
manager_count++;
linphone_core_manager_configure(mgr);
}
#if __clang__ || ((__GNUC__ == 4 && __GNUC_MINOR__ >= 6) || __GNUC__ > 4)
#pragma GCC diagnostic pop
#endif
void linphone_core_manager_start(LinphoneCoreManager *mgr, int check_for_proxies) {
void linphone_core_manager_start(LinphoneCoreManager *mgr, bool_t check_for_proxies) {
LinphoneProxyConfig* proxy;
int proxy_count;
......@@ -436,13 +438,13 @@ LinphoneCoreManager* linphone_core_manager_create(const char* rc_file) {