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

Handle fallback to basic chat room when a client group chat room is created...

Handle fallback to basic chat room when a client group chat room is created inviting a single participant that does not support it.
parent 6251a91d
......@@ -50,6 +50,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#include "bctoolbox/charconv.h"
#include "chat/chat-room/client-group-chat-room-p.h"
#include "chat/chat-room/client-group-to-basic-chat-room.h"
#include "chat/chat-room/server-group-chat-room-p.h"
#include "conference/handlers/remote-conference-event-handler.h"
#include "content/content-manager.h"
......@@ -2141,20 +2142,22 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve
));
if (chatRoom) {
shared_ptr<ClientGroupChatRoom> cgcr;
if (chatRoom->getCapabilities() & static_cast<int>(ChatRoom::Capabilities::Proxy))
cgcr = static_pointer_cast<ClientGroupChatRoom>(
static_pointer_cast<ClientGroupToBasicChatRoom>(chatRoom)->getProxiedChatRoom());
else
cgcr = static_pointer_cast<ClientGroupChatRoom>(chatRoom);
if (linphone_content_is_multipart(body)) {
// TODO : migrate to c++ 'Content'.
int i = 0;
LinphoneContent *part = NULL;
while ((part = linphone_content_get_part(body, i))) {
i++;
L_GET_PRIVATE(static_pointer_cast<ClientGroupChatRoom>(chatRoom))->notifyReceived(
linphone_content_get_string_buffer(part)
);
L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(part));
}
} else
L_GET_PRIVATE(static_pointer_cast<ClientGroupChatRoom>(chatRoom))->notifyReceived(
linphone_content_get_string_buffer(body)
);
L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(body));
}
}
}
......@@ -7281,3 +7284,12 @@ bool_t linphone_core_has_crappy_opengl(LinphoneCore *lc) {
if (sound_description->flags & DEVICE_HAS_CRAPPY_OPENGL) return TRUE;
return FALSE;
}
const char *linphone_core_get_linphone_specs (const LinphoneCore *core) {
return lp_config_get_string(linphone_core_get_config(core), "sip", "linphone_specs", NULL);
}
void linphone_core_set_linphone_specs (LinphoneCore *core, const char *specs) {
lp_config_set_string(linphone_core_get_config(core), "sip", "linphone_specs", specs);
core->sal->set_contact_linphone_specs(specs);
}
......@@ -312,6 +312,13 @@ LINPHONE_PUBLIC bool_t linphone_chat_room_can_handle_participants (const Linphon
*/
LINPHONE_PUBLIC LinphoneParticipant *linphone_chat_room_find_participant (const LinphoneChatRoom *cr, const LinphoneAddress *addr);
/**
* Get the capabilities of a chat room.
* @param[in] cr A LinphoneChatRoom object
* @return The capabilities of the chat room
*/
LINPHONE_PUBLIC LinphoneChatRoomCapabilities linphone_chat_room_get_capabilities (const LinphoneChatRoom *cr);
/**
* Get the conference address of the chat room.
* @param[in] cr A LinphoneChatRoom object
......
......@@ -169,6 +169,12 @@ L_DECLARE_C_ENUM(ChatMessageDirection, L_ENUM_VALUES_CHAT_MESSAGE_DIRECTION);
*/
L_DECLARE_C_ENUM(ChatMessageState, L_ENUM_VALUES_CHAT_MESSAGE_STATE);
/**
* LinphoneChatRoomCapabilities is used to indicated the capabilities of a chat room.
* @ingroup chatroom
*/
L_DECLARE_C_ENUM_FIXED_VALUES(ChatRoomCapabilities, L_ENUM_VALUES_CHAT_ROOM_CAPABILITIES);
/**
* LinphoneChatRoomState is used to indicate the current state of a chat room.
* @ingroup chatroom
......
......@@ -4910,6 +4910,21 @@ LINPHONE_PUBLIC bool_t linphone_core_is_content_type_supported(const LinphoneCor
*/
LINPHONE_PUBLIC void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type);
/**
* Get the linphone specs value telling what functionalities the linphone client supports.
* @param[in] core LinphoneCore object
* @return The linphone specs telling what functionalities the linphone client supports
* @ingroup initializing
*/
const char *linphone_core_get_linphone_specs (const LinphoneCore *core);
/**
* Set the linphone specs value telling what functionalities the linphone client supports.
* @param[in] core LinphoneCore object
* @param[in] specs The linphone specs to set
* @ingroup initializing
*/
void linphone_core_set_linphone_specs (LinphoneCore *core, const char *specs);
/**
* @addtogroup chatroom
......
......@@ -34,6 +34,7 @@
#define L_ENUM_VALUES_CHAT_ROOM_CAPABILITIES(F) \
F(Basic, 1 << 0) \
F(RealTimeText, 1 << 1) \
F(Conference, 1 << 2)
F(Conference, 1 << 2) \
F(Proxy, 1 << 3)
#endif // ifndef _CHAT_ROOM_ENUMS_H_
......@@ -42,6 +42,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
chat/chat-room/basic-chat-room.h
chat/chat-room/basic-to-client-group-chat-room.h
chat/chat-room/chat-room-id.h
chat/chat-room/chat-room-listener.h
chat/chat-room/chat-room-p.h
chat/chat-room/chat-room.h
chat/chat-room/client-group-chat-room-p.h
......
......@@ -29,7 +29,8 @@
#include "c-wrapper/c-wrapper.h"
#include "chat/chat-message/chat-message-p.h"
#include "chat/chat-room/basic-chat-room.h"
#include "chat/chat-room/client-group-chat-room.h"
#include "chat/chat-room/client-group-chat-room-p.h"
#include "chat/chat-room/client-group-to-basic-chat-room.h"
#include "chat/chat-room/real-time-text-chat-room-p.h"
#include "chat/chat-room/server-group-chat-room-p.h"
#include "conference/participant.h"
......@@ -264,6 +265,10 @@ LinphoneParticipant *linphone_chat_room_find_participant (const LinphoneChatRoom
));
}
LinphoneChatRoomCapabilities linphone_chat_room_get_capabilities (const LinphoneChatRoom *cr) {
return (LinphoneChatRoomCapabilities)L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getCapabilities();
}
const LinphoneAddress *linphone_chat_room_get_conference_address (const LinphoneChatRoom *cr) {
if (cr->conferenceAddressCache)
linphone_address_unref(cr->conferenceAddressCache);
......@@ -388,11 +393,15 @@ LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, cons
if (from.empty())
from = linphone_core_get_primary_contact(core);
LinphonePrivate::IdentityAddress me(from);
// Create a ClientGroupToBasicChatRoom to handle fallback from ClientGroupChatRoom to BasicGroupChatRoom if
// only one participant is invited and that it does not support group chat
shared_ptr<LinphonePrivate::ClientGroupChatRoom> cgcr = make_shared<LinphonePrivate::ClientGroupChatRoom>(
L_GET_CPP_PTR_FROM_C_OBJECT(core), L_C_TO_STRING(uri), me, L_C_TO_STRING(subject));
L_GET_PRIVATE(cgcr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
LinphoneChatRoom *cr = L_INIT(ChatRoom);
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ClientGroupChatRoom>(
L_GET_CPP_PTR_FROM_C_OBJECT(core), L_C_TO_STRING(uri), me, L_C_TO_STRING(subject))
);
L_GET_PRIVATE_FROM_C_OBJECT(cr, ChatRoom)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ClientGroupToBasicChatRoom>(cgcr));
L_GET_PRIVATE(cgcr)->setCallSessionListener(L_GET_PRIVATE_FROM_C_OBJECT(cr));
L_GET_PRIVATE(cgcr)->setChatRoomListener(L_GET_PRIVATE_FROM_C_OBJECT(cr));
return cr;
}
......
......@@ -47,6 +47,7 @@
F(AbstractChatRoom, BasicToClientGroupChatRoom) \
F(AbstractChatRoom, ChatRoom) \
F(AbstractChatRoom, ClientGroupChatRoom) \
F(AbstractChatRoom, ClientGroupToBasicChatRoom) \
F(AbstractChatRoom, RealTimeTextChatRoom) \
F(AbstractChatRoom, ServerGroupChatRoom) \
F(Call, LocalConferenceCall) \
......
......@@ -21,6 +21,8 @@
#define _ABSTRACT_CHAT_ROOM_P_H_
#include "abstract-chat-room.h"
#include "chat/chat-room/chat-room-listener.h"
#include "conference/session/call-session-listener.h"
#include "object/object-p.h"
// =============================================================================
......@@ -31,7 +33,7 @@ LINPHONE_BEGIN_NAMESPACE
class SalOp;
class AbstractChatRoomPrivate : public ObjectPrivate {
class AbstractChatRoomPrivate : public ObjectPrivate, public ChatRoomListener, public CallSessionListener {
public:
virtual void setCreationTime (time_t creationTime) = 0;
virtual void setLastUpdateTime (time_t lastUpdateTime) = 0;
......
......@@ -42,6 +42,8 @@ class LINPHONE_PUBLIC AbstractChatRoom : public Object, public CoreAccessor, pub
friend class ProxyChatRoomPrivate;
public:
L_OVERRIDE_SHARED_FROM_THIS(AbstractChatRoom);
L_DECLARE_ENUM(Capabilities, L_ENUM_VALUES_CHAT_ROOM_CAPABILITIES);
L_DECLARE_ENUM(State, L_ENUM_VALUES_CHAT_ROOM_STATE);
......
/*
* chat-room-listener.h
* Copyright (C) 2010-2017 Belledonne Communications SARL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _CHAT_ROOM_LISTENER_H_
#define _CHAT_ROOM_LISTENER_H_
#include <memory>
#include "chat/chat-room/abstract-chat-room.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ChatRoomListener {
public:
virtual ~ChatRoomListener () = default;
virtual void onChatRoomInsertRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) {}
virtual void onChatRoomInsertInDatabaseRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) {}
virtual void onChatRoomDeleteRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) {}
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CHAT_ROOM_LISTENER_H_
......@@ -22,13 +22,12 @@
#include "chat/chat-room/chat-room-p.h"
#include "client-group-chat-room.h"
#include "conference/session/call-session-listener.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ClientGroupChatRoomPrivate : public ChatRoomPrivate, public CallSessionListener {
class ClientGroupChatRoomPrivate : public ChatRoomPrivate {
public:
ClientGroupChatRoomPrivate () = default;
......@@ -37,11 +36,21 @@ public:
void notifyReceived (const std::string &body);
void multipartNotifyReceived (const std::string &body);
private:
void setCallSessionListener (CallSessionListener *listener) { callSessionListener = listener; }
void setChatRoomListener (ChatRoomListener *listener) { chatRoomListener = listener; }
// ChatRoomListener
void onChatRoomInsertRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
void onChatRoomInsertInDatabaseRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
// CallSessionListener
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override;
void onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, LinphoneCallState state, const std::string &message) override;
private:
CallSessionListener *callSessionListener = this;
ChatRoomListener *chatRoomListener = this;
L_DECLARE_PUBLIC(ClientGroupChatRoom);
};
......
......@@ -62,7 +62,7 @@ shared_ptr<CallSession> ClientGroupChatRoomPrivate::createSession () {
csp.addCustomContactParameter("text");
shared_ptr<Participant> focus = qConference->getPrivate()->focus;
shared_ptr<CallSession> session = focus->getPrivate()->createSession(*q, &csp, false, this);
shared_ptr<CallSession> session = focus->getPrivate()->createSession(*q, &csp, false, callSessionListener);
const Address &myAddress = q->getMe()->getAddress();
Address myCleanedAddress(myAddress);
myCleanedAddress.setUriParam("gr"); // Remove gr parameter for INVITE
......@@ -83,6 +83,18 @@ void ClientGroupChatRoomPrivate::multipartNotifyReceived (const string &body) {
// -----------------------------------------------------------------------------
void ClientGroupChatRoomPrivate::onChatRoomInsertRequested (const shared_ptr<AbstractChatRoom> &chatRoom) {
L_Q();
q->getCore()->getPrivate()->insertChatRoom(chatRoom);
}
void ClientGroupChatRoomPrivate::onChatRoomInsertInDatabaseRequested (const shared_ptr<AbstractChatRoom> &chatRoom) {
L_Q();
q->getCore()->getPrivate()->insertChatRoomWithDb(chatRoom);
}
// -----------------------------------------------------------------------------
void ClientGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr<const CallSession> &session) {
L_Q_T(RemoteConference, qConference);
......@@ -335,7 +347,7 @@ void ClientGroupChatRoom::onConferenceCreated (const IdentityAddress &addr) {
dConference->focus->getPrivate()->clearDevices();
dConference->focus->getPrivate()->addDevice(addr);
d->chatRoomId = ChatRoomId(addr, d->chatRoomId.getLocalAddress());
getCore()->getPrivate()->insertChatRoom(getSharedFromThis());
d->chatRoomListener->onChatRoomInsertRequested(getSharedFromThis());
}
void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
......@@ -354,9 +366,8 @@ void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
L_D();
d->setState(ChatRoom::State::Created);
CorePrivate *dCore = getCore()->getPrivate();
dCore->insertChatRoomWithDb(getSharedFromThis());
dCore->mainDb->addEvent(make_shared<ConferenceEvent>(
d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis());
getCore()->getPrivate()->mainDb->addEvent(make_shared<ConferenceEvent>(
EventLog::Type::ConferenceCreated,
time(nullptr),
d->chatRoomId
......
......@@ -30,6 +30,8 @@ LINPHONE_BEGIN_NAMESPACE
class ClientGroupChatRoomPrivate;
class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConference {
friend class ClientGroupToBasicChatRoomPrivate;
public:
// TODO: Make me private.
ClientGroupChatRoom (
......
......@@ -17,8 +17,11 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "client-group-chat-room-p.h"
#include "client-group-to-basic-chat-room.h"
#include "proxy-chat-room-p.h"
#include "c-wrapper/c-wrapper.h"
#include "core/core-p.h"
// =============================================================================
......@@ -30,15 +33,50 @@ LINPHONE_BEGIN_NAMESPACE
class ClientGroupToBasicChatRoomPrivate : public ProxyChatRoomPrivate {
public:
inline void sendChatMessage (const shared_ptr<ChatMessage> &chatMessage) override {
ProxyChatRoomPrivate::sendChatMessage(chatMessage);
// TODO: Try migration.
void onChatRoomInsertRequested (const shared_ptr<AbstractChatRoom> &chatRoom) override {
L_Q();
// Insert the proxy chat room instead of the real one
q->getCore()->getPrivate()->insertChatRoom(q->getSharedFromThis());
}
inline void onChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) override {
ProxyChatRoomPrivate::onChatMessageReceived(chatMessage);
// TODO: Try migration.
void onChatRoomInsertInDatabaseRequested (const shared_ptr<AbstractChatRoom> &chatRoom) override {
L_Q();
// Insert the proxy chat room instead of the real one
q->getCore()->getPrivate()->insertChatRoomWithDb(q->getSharedFromThis());
}
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override {
if (!(chatRoom->getCapabilities() & static_cast<int>(ChatRoom::Capabilities::Conference)))
return;
static_pointer_cast<ClientGroupChatRoom>(chatRoom)->getPrivate()->onCallSessionSetReleased(session);
}
void onCallSessionStateChanged (
const shared_ptr<const CallSession> &session,
LinphoneCallState newState,
const string &message
) override {
L_Q();
shared_ptr<ClientGroupChatRoom> cgcr = dynamic_pointer_cast<ClientGroupChatRoom>(chatRoom);
if (!cgcr)
return;
if ((newState == LinphoneCallError) && (cgcr->getState() == ChatRoom::State::CreationPending)
&& (invitedAddresses.size() == 1)) {
cgcr->getPrivate()->setCallSessionListener(cgcr->getPrivate());
cgcr->getPrivate()->setChatRoomListener(cgcr->getPrivate());
cgcr->getPrivate()->setState(ChatRoom::State::CreationFailed);
Core::deleteChatRoom(q->getSharedFromThis());
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(q);
L_SET_CPP_PTR_FROM_C_OBJECT(lcr, cgcr->getCore()->getOrCreateBasicChatRoom(invitedAddresses.front()));
return;
}
cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message);
}
private:
list<IdentityAddress> invitedAddresses;
L_DECLARE_PUBLIC(ClientGroupToBasicChatRoom);
};
// =============================================================================
......@@ -46,4 +84,27 @@ public:
ClientGroupToBasicChatRoom::ClientGroupToBasicChatRoom (const shared_ptr<ChatRoom> &chatRoom) :
ProxyChatRoom(*new ClientGroupToBasicChatRoomPrivate, chatRoom) {}
void ClientGroupToBasicChatRoom::addParticipant (
const IdentityAddress &participantAddress,
const CallSessionParams *params,
bool hasMedia
) {
L_D();
if (getState() == ChatRoom::State::Instantiated) {
d->invitedAddresses.clear();
d->invitedAddresses.push_back(participantAddress);
}
ProxyChatRoom::addParticipant(participantAddress, params, hasMedia);
}
void ClientGroupToBasicChatRoom::addParticipants (
const std::list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
) {
L_D();
if ((getState() == ChatRoom::State::Instantiated) && (addresses.size() == 1))
d->invitedAddresses = addresses;
ProxyChatRoom::addParticipants(addresses, params, hasMedia);
}
LINPHONE_END_NAMESPACE
......@@ -32,6 +32,17 @@ class LINPHONE_PUBLIC ClientGroupToBasicChatRoom : public ProxyChatRoom {
public:
ClientGroupToBasicChatRoom (const std::shared_ptr<ChatRoom> &chatRoom);
void addParticipant (
const IdentityAddress &participantAddress,
const CallSessionParams *params,
bool hasMedia
) override;
void addParticipants (
const std::list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
) override;
private:
L_DECLARE_PRIVATE(ClientGroupToBasicChatRoom);
L_DISABLE_COPY(ClientGroupToBasicChatRoom);
......
......@@ -65,11 +65,22 @@ time_t ProxyChatRoom::getLastUpdateTime () const {
}
// -----------------------------------------------------------------------------
ProxyChatRoom::State ProxyChatRoom::getState () const {
ProxyChatRoom::CapabilitiesMask ProxyChatRoom::getCapabilities () const {
L_D();
return d->chatRoom->getCapabilities() | static_cast<int>(ProxyChatRoom::Capabilities::Proxy);
}
ProxyChatRoom::State ProxyChatRoom::getState () const {
L_D();
return d->chatRoom->getState();
}
bool ProxyChatRoom::hasBeenLeft () const {
L_D();
return d->chatRoom->hasBeenLeft();
}
// -----------------------------------------------------------------------------
list<shared_ptr<EventLog>> ProxyChatRoom::getHistory (int nLast) const {
......@@ -252,4 +263,11 @@ void ProxyChatRoom::leave () {
d->chatRoom->leave();
}
// -----------------------------------------------------------------------------
const shared_ptr<AbstractChatRoom> &ProxyChatRoom::getProxiedChatRoom () const {
L_D();
return d->chatRoom;
}
LINPHONE_END_NAMESPACE
......@@ -39,7 +39,9 @@ public:
time_t getCreationTime () const override;
time_t getLastUpdateTime () const override;
CapabilitiesMask getCapabilities () const override;
State getState () const override;
bool hasBeenLeft () const override;
std::list<std::shared_ptr<EventLog>> getHistory (int nLast) const override;
std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const override;
......@@ -102,6 +104,8 @@ public:
void join () override;
void leave () override;
const std::shared_ptr<AbstractChatRoom> &getProxiedChatRoom () const;
protected:
ProxyChatRoom (ProxyChatRoomPrivate &p, const std::shared_ptr<ChatRoom> &chatRoom);
......
......@@ -21,14 +21,13 @@
#define _SERVER_GROUP_CHAT_ROOM_P_H_
#include "chat-room-p.h"
#include "conference/session/call-session-listener.h"
#include "server-group-chat-room.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ServerGroupChatRoomPrivate : public ChatRoomPrivate, public CallSessionListener {
class ServerGroupChatRoomPrivate : public ChatRoomPrivate {
public:
std::shared_ptr<Participant> addParticipant (const IdentityAddress &participantAddress);
void removeParticipant (const std::shared_ptr<const Participant> &participant);
......@@ -55,6 +54,11 @@ private:
void finalizeCreation ();
bool isAdminLeft () const;
// ChatRoomListener
void onChatRoomInsertRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
void onChatRoomInsertInDatabaseRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
void onChatRoomDeleteRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
// CallSessionListener
void onCallSessionStateChanged (
const std::shared_ptr<const CallSession> &session,
......@@ -63,6 +67,7 @@ private:
) override;
std::list<std::shared_ptr<Participant>> removedParticipants;
ChatRoomListener *chatRoomListener = this;
L_DECLARE_PUBLIC(ServerGroupChatRoom);
};
......
......@@ -46,6 +46,8 @@ class LINPHONE_PUBLIC Core : public Object {
friend class ChatRoom;
friend class ChatRoomPrivate;
friend class ClientGroupChatRoom;
friend class ClientGroupChatRoomPrivate;
friend class ClientGroupToBasicChatRoomPrivate;
friend class LocalConferenceEventHandlerPrivate;
friend class MainDb;
friend class MainDbChatMessageKey;
......
......@@ -121,6 +121,7 @@ static void configure_core_for_conference (LinphoneCore *core, const char* usern
linphone_core_set_conference_factory_uri(core, factoryUri);
bctbx_free(factoryUri);
linphone_config_set_int(linphone_core_get_config(core), "sip", "use_cpim", 1);
linphone_core_set_linphone_specs(core, "groupchat");
}
static void _configure_core_for_conference (LinphoneCoreManager *lcm, LinphoneAddress *factoryAddr) {
......@@ -1339,6 +1340,46 @@ static void multiple_is_composing_notification(void) {
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;
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_set_linphone_specs(pauline->lc, NULL);
start_core_for_conference(coresManagerList);
participantsAddresses = bctbx_list_append(participantsAddresses, linphone_address_new(linphone_core_get_identity(pauline->lc)));
stats initialMarieStats = marie->stat;
// Marie creates a new group chat room
LinphoneChatRoom *chatRoom = linphone_core_create_client_group_chat_room(marie->lc, "Fallback");
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateInstantiated, initialMarieStats.number_of_LinphoneChatRoomStateInstantiated + 1, 100));
// Add participants
linphone_chat_room_add_participants(chatRoom, 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_LinphoneChatRoomStateCreationPending, initialMarieStats.number_of_LinphoneChatRoomStateCreationPending + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreationFailed, initialMarieStats.number_of_LinphoneChatRoomStateCreationFailed + 1, 10000));
BC_ASSERT_TRUE(wait_for_list(coresList, &marie->stat.number_of_LinphoneChatRoomStateCreated, initialMarieStats.number_of_LinphoneChatRoomStateCreated + 1, 10000));
BC_ASSERT_EQUAL(linphone_chat_room_get_nb_participants(chatRoom), 1, int, "%d");
BC_ASSERT_TRUE(linphone_chat_room_get_capabilities(chatRoom) & LinphoneChatRoomCapabilitiesBasic);
bctbx_list_free_with_data(participantsAddresses, (bctbx_list_free_func)linphone_address_unref);
participantsAddresses = NULL;
// Clean db from chat room
linphone_core_delete_chat_room(marie->lc, chatRoom);
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"),
......@@ -1355,7 +1396,9 @@ test_t group_chat_tests[] = {
TEST_TWO_TAGS("Reinvited after removed from group chat room", group_chat_room_reinvited_after_removed, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Notify after disconnection", group_chat_room_notify_after_disconnection, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Send refer to all participants devices", group_chat_room_send_refer_to_all_devices, "Server", "LeaksMemory"),
TEST_TWO_TAGS("Send multiple is composing", multiple_is_composing_notification, "Server", "LeaksMemory")
TEST_TWO_TAGS("Send multiple is composing", multiple_is_composing_notification, "Server", "LeaksMemory"),
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_suite_t group_chat_test_suite = {
......
......@@ -4,7 +4,6 @@ sip_tcp_port=-1
sip_tls_port=-1
default_proxy=0
ping_with_options=0
composing_idle_timeout=1
[auth_info_0]
......
......@@ -5,7 +5,6 @@ sip_tls_port=5093
default_proxy=0
ping_with_options=0
[auth_info_0]
username=laure
userid=laure
......
......@@ -4,7 +4,6 @@ sip_tcp_port=-1
sip_tls_port=-1
default_proxy=0
ping_with_options=0
composing_idle_timeout=1
[auth_info_0]
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment