Commit 20ca9b9e authored by Ronan's avatar Ronan Committed by Ronan

fix(ClientGroupChatRoom): avoid crash when two INVITEs are received in the...

fix(ClientGroupChatRoom): avoid crash when two INVITEs are received in the chat room creation process
parent 3e46dadc
......@@ -149,9 +149,11 @@ static void call_received(SalCallOp *h) {
}
if (!chatRoom) {
string endToEndEncrypted = L_C_TO_STRING(sal_custom_header_find(h->getRecvCustomHeaders(), "End-To-End-Encrypted"));
bool encrypted = (endToEndEncrypted == "true");
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom(
h->getSubject(), h->getRemoteContact(), h->getRemoteBody(), false, encrypted
h->getSubject(),
ConferenceId(IdentityAddress(h->getRemoteContact()), IdentityAddress(h->getTo())),
h->getRemoteBody(),
endToEndEncrypted == "true"
);
}
......@@ -851,15 +853,6 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
}
}
}
} else {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ConferenceId(addr, IdentityAddress(op->getTo()))
);
if (!chatRoom)
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), Content(), false, false);
chatRoom->join();
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
}
}
......
......@@ -96,11 +96,11 @@ LinphoneChatRoom *linphone_core_get_chat_room_2 (
}
LinphoneChatRoom *linphone_core_create_client_group_chat_room (LinphoneCore *lc, const char *subject, bool_t fallback) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject), !!fallback));
return L_GET_C_BACK_PTR(L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject), !!fallback, false));
}
LinphoneChatRoom *linphone_core_create_client_group_chat_room_2 (LinphoneCore *lc, const char *subject, bool_t fallback, bool_t encrypted) {
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject), !!fallback, !!encrypted));
return L_GET_C_BACK_PTR(L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom(L_C_TO_STRING(subject), !!fallback, !!encrypted));
}
LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc, LinphonePrivate::SalCallOp *op) {
......
......@@ -2250,6 +2250,9 @@ static void linphone_core_internal_subscribe_received(LinphoneCore *lc, Linphone
}
static void _linphone_core_conference_subscription_state_changed (LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) {
if (!linphone_core_conference_server_enabled(lc))
return;
const LinphoneAddress *resource = linphone_event_get_resource(lev);
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(LinphonePrivate::ConferenceId(
IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(resource)),
......@@ -2375,7 +2378,7 @@ static void linphone_core_init(LinphoneCore * lc, LinphoneCoreCbs *cbs, LpConfig
#endif
lc->network_last_status = FALSE;
lc->sip_network_state.global_state = FALSE;
lc->sip_network_state.user_state = TRUE;
lc->media_network_state.global_state = FALSE;
......
......@@ -78,7 +78,7 @@ public:
}
migrationRealTime = currentRealTime;
clientGroupChatRoom = static_pointer_cast<ClientGroupChatRoom>(
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", Content(), false, false)
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), false, false)
);
clientGroupChatRoom->getPrivate()->setCallSessionListener(this);
clientGroupChatRoom->getPrivate()->setChatRoomListener(this);
......
......@@ -246,28 +246,42 @@ void ClientGroupChatRoomPrivate::acceptSession (const shared_ptr<CallSession> &s
ClientGroupChatRoom::ClientGroupChatRoom (
const shared_ptr<Core> &core,
const string &uri,
const IdentityAddress &me,
const IdentityAddress &focus,
const ConferenceId &conferenceId,
const string &subject,
const Content &content,
bool encrypted
) : ChatRoom(*new ClientGroupChatRoomPrivate, core, ConferenceId(IdentityAddress(), me)),
RemoteConference(core, me, nullptr) {
) :
ChatRoom(*new ClientGroupChatRoomPrivate, core, conferenceId),
RemoteConference(core, conferenceId.getLocalAddress(), nullptr) {
L_D();
L_D_T(RemoteConference, dConference);
IdentityAddress focusAddr(uri);
dConference->focus = make_shared<Participant>(this, focusAddr);
dConference->focus->getPrivate()->addDevice(focusAddr);
RemoteConference::setSubject(subject);
list<IdentityAddress> identAddresses = Conference::parseResourceLists(content);
for (const auto &addr : identAddresses)
for (const auto &addr : Conference::parseResourceLists(content))
dConference->participants.push_back(make_shared<Participant>(this, addr));
if (encrypted)
d->capabilities |= ClientGroupChatRoom::Capabilities::Encrypted;
dConference->focus = make_shared<Participant>(this, focus);
dConference->focus->getPrivate()->addDevice(focus);
}
ClientGroupChatRoom::ClientGroupChatRoom (
const shared_ptr<Core> &core,
const string &factoryUri,
const IdentityAddress &me,
const string &subject,
bool encrypted
) : ClientGroupChatRoom(
core,
IdentityAddress(factoryUri),
ConferenceId(IdentityAddress(), me),
subject,
Content(),
encrypted
) {}
ClientGroupChatRoom::ClientGroupChatRoom (
const shared_ptr<Core> &core,
const ConferenceId &conferenceId,
......@@ -282,8 +296,9 @@ RemoteConference(core, me->getAddress(), nullptr) {
L_D();
L_D_T(RemoteConference, dConference);
d->capabilities |= capabilities & ClientGroupChatRoom::Capabilities::OneToOne;
d->capabilities |= capabilities & ClientGroupChatRoom::Capabilities::Encrypted;
d->capabilities |=
(capabilities & ClientGroupChatRoom::Capabilities::OneToOne) |
(capabilities & ClientGroupChatRoom::Capabilities::Encrypted);
const IdentityAddress &peerAddress = conferenceId.getPeerAddress();
dConference->focus = make_shared<Participant>(this, peerAddress);
dConference->focus->getPrivate()->addDevice(peerAddress);
......
......@@ -33,35 +33,13 @@ enum class SecurityLevel;
class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConference {
friend class BasicToClientGroupChatRoomPrivate;
friend class ClientGroupToBasicChatRoomPrivate;
friend class Core;
friend class CorePrivate;
friend class LimeX3dhEncryptionEngine;
friend class MediaSessionPrivate;
friend class MainDb;
public:
L_OVERRIDE_SHARED_FROM_THIS(ClientGroupChatRoom);
// TODO: Make me private.
ClientGroupChatRoom (
const std::shared_ptr<Core> &core,
const std::string &factoryUri,
const IdentityAddress &me,
const std::string &subject,
const Content &content,
bool encrypted = false
);
ClientGroupChatRoom (
const std::shared_ptr<Core> &core,
const ConferenceId &conferenceId,
std::shared_ptr<Participant> &me,
AbstractChatRoom::CapabilitiesMask capabilities,
const std::string &subject,
std::list<std::shared_ptr<Participant>> &&participants,
unsigned int lastNotifyId,
bool hasBeenLeft = false
);
~ClientGroupChatRoom ();
std::shared_ptr<Core> getCore () const;
......@@ -105,6 +83,35 @@ public:
void leave () override;
private:
ClientGroupChatRoom (
const std::shared_ptr<Core> &core,
const IdentityAddress &focus,
const ConferenceId &conferenceId,
const std::string &subject,
const Content &content,
bool encrypted
);
ClientGroupChatRoom (
const std::shared_ptr<Core> &core,
const std::string &factoryUri,
const IdentityAddress &me,
const std::string &subject,
bool encrypted
);
// Create a chat room from the main database.
ClientGroupChatRoom (
const std::shared_ptr<Core> &core,
const ConferenceId &conferenceId,
std::shared_ptr<Participant> &me,
AbstractChatRoom::CapabilitiesMask capabilities,
const std::string &subject,
std::list<std::shared_ptr<Participant>> &&participants,
unsigned int lastNotifyId,
bool hasBeenLeft = false
);
// TODO: Move me in ClientGroupChatRoomPrivate.
// ALL METHODS AFTER THIS POINT.
......
......@@ -102,63 +102,67 @@ shared_ptr<AbstractChatRoom> CorePrivate::createBasicChatRoom (
return chatRoom;
}
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, const Content &content, bool fallback, bool encrypted) {
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (
const string &subject,
const ConferenceId &conferenceId,
const Content &content,
bool encrypted
) {
L_Q();
string usedUri;
string from;
{
LinphoneProxyConfig *proxy = nullptr;
if (uri.empty()) {
proxy = linphone_core_get_default_proxy_config(q->getCCore());
if (!proxy)
return nullptr;
const char *conferenceFactoryUri = linphone_proxy_config_get_conference_factory_uri(proxy);
if (!conferenceFactoryUri)
return nullptr;
usedUri = conferenceFactoryUri;
} else {
LinphoneAddress *addr = linphone_address_new(uri.c_str());
proxy = linphone_core_lookup_known_proxy(q->getCCore(), addr);
linphone_address_unref(addr);
usedUri = uri;
}
if (proxy) {
const LinphoneAddress *contactAddr = linphone_proxy_config_get_contact(proxy);
if (contactAddr) {
char *cFrom = linphone_address_as_string(contactAddr);
from = string(cFrom);
bctbx_free(cFrom);
} else
from = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_proxy_config_get_identity_address(proxy))->asString();
}
}
shared_ptr<ClientGroupChatRoom> clientGroupChatRoom(new ClientGroupChatRoom(
q->getSharedFromThis(),
conferenceId.getPeerAddress(),
conferenceId,
subject,
content,
encrypted
));
clientGroupChatRoom->getPrivate()->setState(ChatRoom::State::Instantiated);
noCreatedClientGroupChatRooms[clientGroupChatRoom.get()] = clientGroupChatRoom;
return clientGroupChatRoom;
}
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const string &subject, bool fallback, bool encrypted) {
L_Q();
LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(q->getCCore());
if (!proxy)
return nullptr;
const LinphoneAddress *contactAddr = linphone_proxy_config_get_contact(proxy);
const Address *me = L_GET_CPP_PTR_FROM_C_OBJECT(contactAddr
? contactAddr
: linphone_proxy_config_get_identity_address(proxy)
);
const char *conferenceFactoryUri = linphone_proxy_config_get_conference_factory_uri(proxy);
if (!conferenceFactoryUri)
return nullptr;
shared_ptr<ClientGroupChatRoom> clientGroupChatRoom(new ClientGroupChatRoom(
q->getSharedFromThis(),
conferenceFactoryUri,
IdentityAddress(*me),
subject,
encrypted
));
shared_ptr<AbstractChatRoom> chatRoom;
{
shared_ptr<ClientGroupChatRoom> clientGroupChatRoom = make_shared<ClientGroupChatRoom>(
q->getSharedFromThis(),
usedUri,
IdentityAddress(from),
subject,
content,
encrypted
);
if (fallback) {
// Create a ClientGroupToBasicChatRoom to handle fallback from ClientGroupChatRoom to BasicGroupChatRoom if
// only one participant is invited and that it does not support group chat.
chatRoom = make_shared<ClientGroupToBasicChatRoom>(clientGroupChatRoom);
ClientGroupChatRoomPrivate *dClientGroupChatRoom = clientGroupChatRoom->getPrivate();
dClientGroupChatRoom->setCallSessionListener(chatRoom->getPrivate());
dClientGroupChatRoom->setChatRoomListener(chatRoom->getPrivate());
} else
chatRoom = clientGroupChatRoom;
if (fallback) {
// Create a ClientGroupToBasicChatRoom to handle fallback from ClientGroupChatRoom to BasicGroupChatRoom if
// only one participant is invited and that it does not support group chat
chatRoom = make_shared<ClientGroupToBasicChatRoom>(clientGroupChatRoom);
dClientGroupChatRoom->setCallSessionListener(chatRoom->getPrivate());
dClientGroupChatRoom->setChatRoomListener(chatRoom->getPrivate());
} else
chatRoom = clientGroupChatRoom;
}
chatRoom->getPrivate()->setState(ChatRoom::State::Instantiated);
noCreatedClientGroupChatRooms[chatRoom.get()] = chatRoom;
return chatRoom;
}
......@@ -280,7 +284,7 @@ shared_ptr<AbstractChatRoom> Core::findOneToOneChatRoom (
shared_ptr<AbstractChatRoom> Core::createClientGroupChatRoom (const string &subject, bool fallback, bool encrypted) {
L_D();
return d->createClientGroupChatRoom(subject, "", Content(), fallback, encrypted);
return d->createClientGroupChatRoom(subject, fallback, encrypted);
}
shared_ptr<AbstractChatRoom> Core::getOrCreateBasicChatRoom (const ConferenceId &conferenceId, bool isRtt) {
......
......@@ -67,7 +67,16 @@ public:
void insertChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
void insertChatRoomWithDb (const std::shared_ptr<AbstractChatRoom> &chatRoom, unsigned int notifyId = 0);
std::shared_ptr<AbstractChatRoom> createBasicChatRoom (const ConferenceId &conferenceId, AbstractChatRoom::CapabilitiesMask capabilities);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", const Content &content = Content(), bool fallback = true, bool encrypted = false);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (
const std::string &subject,
const ConferenceId &conferenceId,
const Content &content,
bool encrypted
);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, bool fallback, bool encrypted);
void replaceChatRoom (const std::shared_ptr<AbstractChatRoom> &replacedChatRoom, const std::shared_ptr<AbstractChatRoom> &newChatRoom);
std::unique_ptr<MainDb> mainDb;
......
......@@ -2582,7 +2582,7 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
", local=" + conferenceId.getLocalAddress().asString() + ").";
continue;
}
auto clientGroupChatRoom = make_shared<ClientGroupChatRoom>(
shared_ptr<ClientGroupChatRoom> clientGroupChatRoom(new ClientGroupChatRoom(
core,
conferenceId,
me,
......@@ -2591,7 +2591,7 @@ list<shared_ptr<AbstractChatRoom>> MainDb::getChatRooms () const {
move(participants),
lastNotifyId,
hasBeenLeft
);
));
chatRoom = clientGroupChatRoom;
conference = clientGroupChatRoom.get();
AbstractChatRoomPrivate *dChatRoom = chatRoom->getPrivate();
......
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