Commit b9eaf0a7 authored by Ghislain MARY's avatar Ghislain MARY

Prevent ChatRoom C++ objects from being leaked.

parent d41fb1f9
......@@ -748,10 +748,12 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
return;
}
} else {
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ChatRoomId(addr, IdentityAddress(op->get_to()))));
if (!cr)
cr = _linphone_client_group_chat_room_new(lc, addr.asString().c_str(), nullptr, FALSE);
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->join();
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
ChatRoomId(addr, IdentityAddress(op->get_to()))
);
if (!chatRoom)
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), false);
chatRoom->join();
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
return;
}
......
......@@ -2145,6 +2145,7 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve
while ((part = linphone_content_get_part(body, i))) {
i++;
L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(part));
linphone_content_unref(part);
}
} else
L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(body));
......@@ -3449,7 +3450,7 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L
LinphoneProxyConfig *default_cfg=lc->default_proxy;
if (linphone_address_get_domain(uri) == NULL) {
ms_message("cannot seach for proxy for uri [%p] if no domain set. returning default",uri);
ms_message("Cannot look for proxy for uri [%p] that has no domain set, returning default", uri);
return default_cfg;
}
/*return default proxy if it is matching the destination uri*/
......
......@@ -275,7 +275,6 @@ void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj);
void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj);
/*chat*/
LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, const char *uri, const char *subject, bool_t fallback);
LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op);
void linphone_chat_room_set_call(LinphoneChatRoom *cr, LinphoneCall *call);
LinphoneChatRoomCbs * _linphone_chat_room_cbs_new (void);
......
......@@ -29,9 +29,6 @@
#include "c-wrapper/c-wrapper.h"
#include "call/call.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-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"
......@@ -435,7 +432,7 @@ const bctbx_list_t *linphone_chat_room_get_callbacks_list(const LinphoneChatRoom
if (cb) \
cb(__VA_ARGS__); \
} \
bctbx_free(callbacksCopy);
bctbx_list_free(callbacksCopy);
void _linphone_chat_room_notify_is_composing_received(LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) {
NOTIFY_IF_EXIST(IsComposingReceived, is_composing_received, cr, remoteAddr, isComposing)
......@@ -526,49 +523,6 @@ void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) {
// Constructor and destructor functions.
// =============================================================================
LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, const char *uri, const char *subject, bool_t fallback) {
string from;
LinphoneProxyConfig *proxy = nullptr;
if (uri) {
LinphoneAddress *addr = linphone_address_new(uri);
proxy = linphone_core_lookup_known_proxy(core, addr);
linphone_address_unref(addr);
} else {
proxy = linphone_core_get_default_proxy_config(core);
if (!proxy)
return nullptr;
uri = linphone_proxy_config_get_conference_factory_uri(proxy);
if (!uri)
return nullptr;
}
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();
}
}
if (from.empty())
from = linphone_core_get_primary_contact(core);
LinphonePrivate::IdentityAddress me(from);
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));
LinphoneChatRoom *cr = L_INIT(ChatRoom);
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
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));
} else
L_SET_CPP_PTR_FROM_C_OBJECT(cr, cgcr);
L_GET_PRIVATE_FROM_C_OBJECT(cr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
return cr;
}
LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op) {
LinphoneChatRoom *cr = L_INIT(ChatRoom);
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ServerGroupChatRoom>(
......
......@@ -78,7 +78,7 @@ public:
}
migrationRealTime = currentRealTime;
clientGroupChatRoom = static_pointer_cast<ClientGroupChatRoom>(
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), false)
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", false)
);
clientGroupChatRoom->getPrivate()->setCallSessionListener(this);
clientGroupChatRoom->getPrivate()->setChatRoomListener(this);
......
......@@ -33,6 +33,8 @@ LINPHONE_BEGIN_NAMESPACE
class ChatRoomPrivate : public AbstractChatRoomPrivate, public IsComposingListener {
public:
inline void setProxyChatRoom (AbstractChatRoom *value) { proxyChatRoom = value; }
inline void setCreationTime (time_t creationTime) override {
this->creationTime = creationTime;
}
......@@ -67,12 +69,16 @@ public:
void onIsComposingStateChanged (bool isComposing) override;
void onIsRemoteComposingStateChanged (const Address &remoteAddress, bool isComposing) override;
LinphoneChatRoom *getCChatRoom () const;
std::list<IdentityAddress> remoteIsComposing;
std::list<std::shared_ptr<EventLog>> transientEvents;
ChatRoomId chatRoomId;
private:
AbstractChatRoom *proxyChatRoom = nullptr;
ChatRoom::State state = ChatRoom::State::None;
time_t creationTime = std::time(nullptr);
......
......@@ -51,7 +51,7 @@ void ChatRoomPrivate::sendChatMessage (const shared_ptr<ChatMessage> &chatMessag
dChatMessage->setTime(ms_time(0));
dChatMessage->send();
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
LinphoneChatRoom *cr = getCChatRoom();
// TODO: server currently don't stock message, remove condition in the future.
if (!linphone_core_conference_server_enabled(q->getCore()->getCCore())) {
shared_ptr<ConferenceChatMessageEvent> event = static_pointer_cast<ConferenceChatMessageEvent>(
......@@ -129,7 +129,7 @@ list<shared_ptr<ChatMessage>> ChatRoomPrivate::findChatMessages (const string &m
void ChatRoomPrivate::notifyChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
L_Q();
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
LinphoneChatRoom *cr = getCChatRoom();
if (!chatMessage->getPrivate()->getText().empty()) {
/* Legacy API */
LinphoneAddress *fromAddress = linphone_address_new(chatMessage->getFromAddress().asString().c_str());
......@@ -153,7 +153,7 @@ void ChatRoomPrivate::notifyIsComposingReceived (const Address &remoteAddress, b
else
remoteIsComposing.remove(remoteAddress);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
LinphoneChatRoom *cr = getCChatRoom();
LinphoneAddress *lAddr = linphone_address_new(remoteAddress.asString().c_str());
_linphone_chat_room_notify_is_composing_received(cr, lAddr, !!isComposing);
linphone_address_unref(lAddr);
......@@ -163,14 +163,14 @@ void ChatRoomPrivate::notifyIsComposingReceived (const Address &remoteAddress, b
void ChatRoomPrivate::notifyStateChanged () {
L_Q();
linphone_core_notify_chat_room_state_changed(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q), (LinphoneChatRoomState)state);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
LinphoneChatRoom *cr = getCChatRoom();
linphone_core_notify_chat_room_state_changed(q->getCore()->getCCore(), cr, (LinphoneChatRoomState)state);
_linphone_chat_room_notify_state_changed(cr, (LinphoneChatRoomState)state);
}
void ChatRoomPrivate::notifyUndecryptableChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
L_Q();
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
LinphoneChatRoom *cr = getCChatRoom();
_linphone_chat_room_notify_undecryptable_message_received(cr, L_GET_C_BACK_PTR(chatMessage));
linphone_core_notify_message_received_unable_decrypt(q->getCore()->getCCore(), cr, L_GET_C_BACK_PTR(chatMessage));
}
......@@ -262,6 +262,16 @@ void ChatRoomPrivate::onIsRemoteComposingStateChanged (const Address &remoteAddr
notifyIsComposingReceived(remoteAddress, isComposing);
}
// -----------------------------------------------------------------------------
LinphoneChatRoom *ChatRoomPrivate::getCChatRoom () const {
L_Q();
if (proxyChatRoom)
return L_GET_C_BACK_PTR(proxyChatRoom);
else
return L_GET_C_BACK_PTR(q);
}
// =============================================================================
ChatRoom::ChatRoom (ChatRoomPrivate &p, const shared_ptr<Core> &core, const ChatRoomId &chatRoomId) :
......@@ -341,7 +351,9 @@ int ChatRoom::getHistorySize () const {
void ChatRoom::deleteFromDb () {
L_D();
Core::deleteChatRoom(this->getSharedFromThis());
// Keep a ref, otherwise the object might be destroyed before we can set the Deleted state
shared_ptr<AbstractChatRoom> ref = this->getSharedFromThis();
Core::deleteChatRoom(ref);
d->setState(ChatRoom::State::Deleted);
}
......
......@@ -30,6 +30,8 @@ class ChatRoomPrivate;
class LINPHONE_PUBLIC ChatRoom : public AbstractChatRoom {
public:
friend class ProxyChatRoomPrivate;
L_OVERRIDE_SHARED_FROM_THIS(ChatRoom);
const ChatRoomId &getChatRoomId () const override;
......
......@@ -521,7 +521,7 @@ void ClientGroupChatRoom::onParticipantAdded (const shared_ptr<ConferencePartici
d->addEvent(event);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
LinphoneChatRoom *cr = d->getCChatRoom();
_linphone_chat_room_notify_participant_added(cr, L_GET_C_BACK_PTR(event));
}
......@@ -541,7 +541,7 @@ void ClientGroupChatRoom::onParticipantRemoved (const shared_ptr<ConferenceParti
dConference->participants.remove(participant);
d->addEvent(event);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
LinphoneChatRoom *cr = d->getCChatRoom();
_linphone_chat_room_notify_participant_removed(cr, L_GET_C_BACK_PTR(event));
}
......@@ -569,7 +569,7 @@ void ClientGroupChatRoom::onParticipantSetAdmin (const shared_ptr<ConferencePart
d->addEvent(event);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
LinphoneChatRoom *cr = d->getCChatRoom();
_linphone_chat_room_notify_participant_admin_status_changed(cr, L_GET_C_BACK_PTR(event));
}
......@@ -585,7 +585,7 @@ void ClientGroupChatRoom::onSubjectChanged (const shared_ptr<ConferenceSubjectEv
d->addEvent(event);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
LinphoneChatRoom *cr = d->getCChatRoom();
_linphone_chat_room_notify_subject_changed(cr, L_GET_C_BACK_PTR(event));
}
......@@ -609,7 +609,7 @@ void ClientGroupChatRoom::onParticipantDeviceAdded (const shared_ptr<ConferenceP
d->addEvent(event);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
LinphoneChatRoom *cr = d->getCChatRoom();
_linphone_chat_room_notify_participant_device_added(cr, L_GET_C_BACK_PTR(event));
}
......@@ -631,7 +631,7 @@ void ClientGroupChatRoom::onParticipantDeviceRemoved (const shared_ptr<Conferenc
participant->getPrivate()->removeDevice(event->getDeviceAddress());
d->addEvent(event);
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
LinphoneChatRoom *cr = d->getCChatRoom();
_linphone_chat_room_notify_participant_device_removed(cr, L_GET_C_BACK_PTR(event));
}
......
......@@ -33,6 +33,7 @@ class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConfer
friend class BasicToClientGroupChatRoomPrivate;
friend class ClientGroupToBasicChatRoomPrivate;
friend class Core;
friend class CorePrivate;
public:
L_OVERRIDE_SHARED_FROM_THIS(ClientGroupChatRoom);
......
......@@ -48,7 +48,9 @@ public:
void onChatRoomDeleteRequested (const shared_ptr<AbstractChatRoom> &chatRoom) override {
L_Q();
q->getCore()->deleteChatRoom(q->getSharedFromThis());
// Keep a ref, otherwise the object might be destroyed before we can set the Deleted state
shared_ptr<AbstractChatRoom> ref = q->getSharedFromThis();
q->getCore()->deleteChatRoom(ref);
setState(AbstractChatRoom::State::Deleted);
}
......@@ -64,24 +66,23 @@ public:
const string &message
) override {
L_Q();
// Keep a ref, otherwise the object might be destroyed when calling Core::deleteChatRoom()
shared_ptr<AbstractChatRoom> ref = q->getSharedFromThis();
// TODO: Avoid cast, use capabilities.
shared_ptr<ClientGroupChatRoom> cgcr = dynamic_pointer_cast<ClientGroupChatRoom>(chatRoom);
if (!cgcr)
return;
if ((newState == CallSession::State::Error) && (cgcr->getState() == ChatRoom::State::CreationPending)
&& (session->getReason() == LinphoneReasonNotAcceptable) && (invitedAddresses.size() == 1)) {
teardownCallbacks();
teardownProxy();
cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message);
cgcr->getPrivate()->setCallSessionListener(nullptr);
cgcr->getPrivate()->setChatRoomListener(nullptr);
Core::deleteChatRoom(q->getSharedFromThis());
setupCallbacks();
setupProxy();
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(q);
shared_ptr<AbstractChatRoom> bcr = cgcr->getCore()->onlyGetOrCreateBasicChatRoom(invitedAddresses.front());
shared_ptr<AbstractChatRoom> bcr = cgcr->getCore()->getOrCreateBasicChatRoom(invitedAddresses.front());
L_SET_CPP_PTR_FROM_C_OBJECT(lcr, bcr);
bcr->getPrivate()->setState(ChatRoom::State::Instantiated);
cgcr->getCore()->getPrivate()->insertChatRoom(bcr);
bcr->getPrivate()->setState(ChatRoom::State::Created);
cgcr->getCore()->getPrivate()->insertChatRoomWithDb(bcr);
return;
}
cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message);
......
......@@ -73,8 +73,8 @@ public:
chatRoom->getPrivate()->onChatMessageReceived(chatMessage);
}
void setupCallbacks ();
void teardownCallbacks ();
void setupProxy ();
void teardownProxy ();
std::shared_ptr<AbstractChatRoom> chatRoom;
......
......@@ -18,7 +18,7 @@
*/
#include "basic-to-client-group-chat-room.h"
#include "chat-room.h"
#include "chat-room-p.h"
#include "proxy-chat-room-p.h"
#include "c-wrapper/c-wrapper.h"
......@@ -28,98 +28,13 @@ using namespace std;
LINPHONE_BEGIN_NAMESPACE
#define PROXY_CALLBACK(callback, ...) \
LinphoneChatRoomCbs *proxiedCbs = linphone_chat_room_get_current_callbacks(cr); \
ProxyChatRoom *pcr = static_cast<ProxyChatRoom *>(linphone_chat_room_cbs_get_user_data(proxiedCbs)); \
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(pcr->getSharedFromThis()); \
_linphone_chat_room_notify_ ## callback(lcr, ##__VA_ARGS__)
static void chatMessageReceived (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(chat_message_received, event_log);
}
static void chatMessageSent (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(chat_message_sent, event_log);
}
static void conferenceAddressGeneration (LinphoneChatRoom *cr) {
PROXY_CALLBACK(conference_address_generation);
}
static void isComposingReceived (LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) {
PROXY_CALLBACK(is_composing_received, remoteAddr, isComposing);
}
static void messageReceived (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
PROXY_CALLBACK(message_received, msg);
}
static void participantAdded (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(participant_added, event_log);
}
static void participantAdminStatusChanged (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(participant_admin_status_changed, event_log);
}
static void participantDeviceAdded (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(participant_device_added, event_log);
}
static void participantDeviceFetched (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
PROXY_CALLBACK(participant_device_fetched, participantAddr);
}
static void participantDeviceRemoved (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(participant_device_removed, event_log);
}
static void participantRemoved (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(participant_removed, event_log);
}
static void participantsCapabilitiesChecked (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr) {
PROXY_CALLBACK(participants_capabilities_checked, deviceAddr, participantsAddr);
}
static void stateChanged (LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
PROXY_CALLBACK(state_changed, newState);
}
static void subjectChanged (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
PROXY_CALLBACK(subject_changed, event_log);
}
static void undecryptableMessageReceived (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
PROXY_CALLBACK(undecryptable_message_received, msg);
void ProxyChatRoomPrivate::setupProxy () {
L_Q();
static_pointer_cast<ChatRoom>(chatRoom)->getPrivate()->setProxyChatRoom(q);
}
void ProxyChatRoomPrivate::setupCallbacks () {
L_Q();
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(chatRoom);
LinphoneChatRoomCbs *cbs = linphone_factory_create_chat_room_cbs(linphone_factory_get());
linphone_chat_room_cbs_set_user_data(cbs, q);
linphone_chat_room_cbs_set_chat_message_received(cbs, chatMessageReceived);
linphone_chat_room_cbs_set_chat_message_sent(cbs, chatMessageSent);
linphone_chat_room_cbs_set_conference_address_generation(cbs, conferenceAddressGeneration);
linphone_chat_room_cbs_set_is_composing_received(cbs, isComposingReceived);
linphone_chat_room_cbs_set_message_received(cbs, messageReceived);
linphone_chat_room_cbs_set_participant_added(cbs, participantAdded);
linphone_chat_room_cbs_set_participant_admin_status_changed(cbs, participantAdminStatusChanged);
linphone_chat_room_cbs_set_participant_device_added(cbs, participantDeviceAdded);
linphone_chat_room_cbs_set_participant_device_fetched(cbs, participantDeviceFetched);
linphone_chat_room_cbs_set_participant_device_removed(cbs, participantDeviceRemoved);
linphone_chat_room_cbs_set_participant_removed(cbs, participantRemoved);
linphone_chat_room_cbs_set_participants_capabilities_checked(cbs, participantsCapabilitiesChecked);
linphone_chat_room_cbs_set_state_changed(cbs, stateChanged);
linphone_chat_room_cbs_set_subject_changed(cbs, subjectChanged);
linphone_chat_room_cbs_set_undecryptable_message_received(cbs, undecryptableMessageReceived);
linphone_chat_room_add_callbacks(lcr, cbs);
}
void ProxyChatRoomPrivate::teardownCallbacks () {
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(chatRoom);
_linphone_chat_room_clear_callbacks(lcr);
void ProxyChatRoomPrivate::teardownProxy () {
static_pointer_cast<ChatRoom>(chatRoom)->getPrivate()->setProxyChatRoom(nullptr);
}
// -----------------------------------------------------------------------------
......@@ -128,7 +43,7 @@ void ProxyChatRoomPrivate::teardownCallbacks () {
AbstractChatRoom(p, chatRoom->getCore()) {
L_D();
d->chatRoom = chatRoom;
d->setupCallbacks();
d->setupProxy();
}
// -----------------------------------------------------------------------------
......
......@@ -30,6 +30,8 @@ class ChatRoom;
class ProxyChatRoomPrivate;
class LINPHONE_PUBLIC ProxyChatRoom : public AbstractChatRoom {
friend class CorePrivate;
public:
const ChatRoomId &getChatRoomId () const override;
......
......@@ -52,7 +52,7 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, cons
receivedRttCharacters.push_back(cmc);
remoteIsComposing.push_back(q->getPeerAddress());
linphone_core_notify_is_composing_received(cCore, L_GET_C_BACK_PTR(q));
linphone_core_notify_is_composing_received(cCore, getCChatRoom());
if ((character == new_line) || (character == crlf) || (character == lf)) {
// End of message
......
......@@ -34,7 +34,7 @@ class Participant;
class LINPHONE_PUBLIC ConferenceInterface {
public:
virtual ~ConferenceInterface() = default;
virtual ~ConferenceInterface () = default;
virtual void addParticipant (
const IdentityAddress &participantAddress,
......
......@@ -62,6 +62,8 @@ void CallSessionPrivate::notifyReferState () {
void CallSessionPrivate::setState (CallSession::State newState, const string &message) {
L_Q();
// Keep a ref on the CallSession, otherwise it might get destroyed before the end of the method
shared_ptr<CallSession> ref = q->getSharedFromThis();
if (state != newState){
prevState = state;
......
......@@ -23,6 +23,8 @@
#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/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.h"
#include "conference/participant.h"
#include "core-p.h"
......@@ -98,15 +100,59 @@ shared_ptr<AbstractChatRoom> CorePrivate::createBasicChatRoom (
return chatRoom;
}
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const string &subject, bool fallback) {
shared_ptr<AbstractChatRoom> CorePrivate::createClientGroupChatRoom (const string &subject, const string &uri, bool fallback) {
L_Q();
LinphoneChatRoom *lcr = _linphone_client_group_chat_room_new(
q->getCCore(),
nullptr,
L_STRING_TO_C(subject),
fallback ? TRUE : FALSE
);
return lcr ? L_GET_CPP_PTR_FROM_C_OBJECT(lcr) : nullptr;
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<AbstractChatRoom> chatRoom;
{
shared_ptr<ClientGroupChatRoom> clientGroupChatRoom = make_shared<ClientGroupChatRoom>(
q->getSharedFromThis(), usedUri, IdentityAddress(from), subject
);
ClientGroupChatRoomPrivate *dClientGroupChatRoom = clientGroupChatRoom->getPrivate();
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;
}
void CorePrivate::insertChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom) {
......@@ -117,6 +163,9 @@ void CorePrivate::insertChatRoom (const shared_ptr<AbstractChatRoom> &chatRoom)
// Chat room not exist or yes but with the same pointer!
L_ASSERT(it == chatRoomsById.end() || it->second == chatRoom);
if (it == chatRoomsById.end()) {
// Remove chat room from workaround cache.
noCreatedClientGroupChatRooms.erase(chatRoom.get());
chatRooms.push_back(chatRoom);
chatRoomsById[chatRoomId] = chatRoom;
}
......@@ -218,21 +267,7 @@ shared_ptr<AbstractChatRoom> Core::findOneToOneChatRoom (
shared_ptr<AbstractChatRoom> Core::createClientGroupChatRoom (const string &subject) {
L_D();
return d->createClientGroupChatRoom(subject, true);
}
shared_ptr<AbstractChatRoom> Core::onlyGetOrCreateBasicChatRoom (const IdentityAddress &peerAddress, bool isRtt) {
list<shared_ptr<AbstractChatRoom>> chatRooms = findChatRooms(peerAddress);
if (!chatRooms.empty())
return chatRooms.front();
const ChatRoomId &chatRoomId = ChatRoomId(peerAddress, getDefaultLocalAddress(getSharedFromThis(), peerAddress));
shared_ptr<AbstractChatRoom> chatRoom;
BasicChatRoom *basicChatRoom = new BasicChatRoom(getSharedFromThis(), chatRoomId);
chatRoom.reset(basicChatRoom);
return chatRoom;
return d->createClientGroupChatRoom(subject);
}
shared_ptr<AbstractChatRoom> Core::getOrCreateBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt) {
......@@ -283,6 +318,7 @@ shared_ptr<AbstractChatRoom> Core::getOrCreateBasicChatRoomFromUri (const string
void Core::deleteChatRoom (const shared_ptr<const AbstractChatRoom> &chatRoom) {
CorePrivate *d = chatRoom->getCore()->getPrivate();
d->noCreatedClientGroupChatRooms.erase(chatRoom.get());
const ChatRoomId &chatRoomId = chatRoom->getChatRoomId();
auto chatRoomsByIdIt = d->chatRoomsById.find(chatRoomId);
if (chatRoomsByIdIt != d->chatRoomsById.end()) {
......
......@@ -61,7 +61,7 @@ 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, AbstractChatRoom::CapabilitiesMask capabilities);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, bool fallback = true);
std::shared_ptr<AbstractChatRoom> createClientGroupChatRoom (const std::string &subject, const std::string &uri = "", bool fallback = true);
void replaceChatRoom (const std::shared_ptr<AbstractChatRoom> &replacedChatRoom, const std::shared_ptr<AbstractChatRoom> &newChatRoom);
std::unique_ptr<MainDb> mainDb;
......@@ -73,8 +73,12 @@ private:
std::shared_ptr<Call> currentCall;
std::list<std::shared_ptr<AbstractChatRoom>> chatRooms;
std::unordered_map<ChatRoomId, std::shared_ptr<AbstractChatRoom>> chatRoomsById;
// Ugly cache to deal with C code.
std::unordered_map<const AbstractChatRoom *, std::shared_ptr<const AbstractChatRoom>> noCreatedClientGroupChatRooms;
L_DECLARE_PUBLIC(Core);
};
......
......@@ -77,6 +77,10 @@ void CorePrivate::uninit () {
ms_usleep(10000);
}
chatRooms.clear();
chatRoomsById.clear();
noCreatedClientGroupChatRooms.clear();
AddressPrivate::clearSipAddressesCache();
}
......
......@@ -107,8 +107,9 @@ public:
const IdentityAddress &localAddress
);
std::shared_ptr<AbstractChatRoom> onlyGetOrCreateBasicChatRoom (const IdentityAddress &peerAddress, bool isRtt = false);
std::shared_ptr<AbstractChatRoom> getOrCreateBasicChatRoom (const ChatRoomId &chatRoomId, bool isRtt = false);
// TODO: Remove me in the future, a chatroom is identified by a local and peer address now!
std::shared_ptr<AbstractChatRoom> getOrCreateBasicChatRoom (const IdentityAddress &peerAddress, bool isRtt = false);
std::shared_ptr<AbstractChatRoom> getOrCreateBasicChatRoomFromUri (const std::string &uri, bool isRtt = false);
......
......@@ -59,12 +59,14 @@ void SalReferOp::process_request_event_cb(void *op_base, const belle_sip_request
if (!refer_to){
ms_warning("cannot do anything with the refer without destination");
op->reply(SalReasonUnknown);/*is mapped on bad request*/
op->unref();
return;
}
SalAddress *referToAddr = sal_address_new(belle_sip_header_get_unparsed_value(BELLE_SIP_HEADER(refer_to)));
op->root->callbacks.refer_received(op, referToAddr);
/*the app is expected to reply in the callback*/
sal_address_unref(referToAddr);
op->unref();
}
void SalReferOp::fill_cbs() {
......
This diff is collapsed.
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