Commit 359b7bde authored by Ghislain MARY's avatar Ghislain MARY

Handle one-to-one chat rooms and quit the client group chat room when deleting it.

parent 1e350eda
...@@ -80,11 +80,30 @@ static void call_received(SalCallOp *h) { ...@@ -80,11 +80,30 @@ static void call_received(SalCallOp *h) {
LinphoneAddress *toAddr = linphone_address_new(h->get_to()); LinphoneAddress *toAddr = linphone_address_new(h->get_to());
if (_linphone_core_is_conference_creation(lc, toAddr)) { if (_linphone_core_is_conference_creation(lc, toAddr)) {
if (sal_address_has_param(h->get_remote_contact_address(), "text"))
_linphone_core_create_server_group_chat_room(lc, h);
// TODO: handle media conference creation if the "text" feature tag is not present
linphone_address_unref(toAddr); linphone_address_unref(toAddr);
linphone_address_unref(fromAddr); linphone_address_unref(fromAddr);
if (sal_address_has_param(h->get_remote_contact_address(), "text")) {
bool oneToOneChatRoom = false;
const char *oneToOneChatRoomStr = sal_custom_header_find(h->get_recv_custom_header(), "One-To-One-Chat-Room");
if (oneToOneChatRoomStr && (strcmp(oneToOneChatRoomStr, "true") == 0))
oneToOneChatRoom = true;
if (oneToOneChatRoom) {
IdentityAddress from(h->get_from());
list<IdentityAddress> identAddresses = ServerGroupChatRoom::parseResourceLists(h->get_remote_body());
if (identAddresses.size() != 1) {
h->decline(SalReasonNotAcceptable, nullptr);
return;
}
IdentityAddress confAddr = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb->findOneToOneConferenceChatRoomAddress(from, identAddresses.front());
if (confAddr.isValid()) {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ChatRoomId(confAddr, confAddr));
L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->confirmRecreation(h);
return;
}
}
_linphone_core_create_server_group_chat_room(lc, h);
}
// TODO: handle media conference creation if the "text" feature tag is not present
return; return;
} else if (sal_address_has_param(h->get_remote_contact_address(), "text")) { } else if (sal_address_has_param(h->get_remote_contact_address(), "text")) {
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom( shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
......
...@@ -92,7 +92,7 @@ LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc ...@@ -92,7 +92,7 @@ LinphoneChatRoom *_linphone_core_create_server_group_chat_room (LinphoneCore *lc
} }
void linphone_core_delete_chat_room (LinphoneCore *, LinphoneChatRoom *cr) { void linphone_core_delete_chat_room (LinphoneCore *, LinphoneChatRoom *cr) {
LinphonePrivate::Core::deleteChatRoom(L_GET_CPP_PTR_FROM_C_OBJECT(cr)); L_GET_CPP_PTR_FROM_C_OBJECT(cr)->deleteFromDb();
} }
LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to) { LinphoneChatRoom *linphone_core_get_chat_room_from_uri(LinphoneCore *lc, const char *to) {
......
...@@ -29,13 +29,15 @@ ...@@ -29,13 +29,15 @@
F(Created) \ F(Created) \
F(TerminationPending) \ F(TerminationPending) \
F(Terminated) \ F(Terminated) \
F(CreationFailed) F(CreationFailed) \
F(Deleted)
#define L_ENUM_VALUES_CHAT_ROOM_CAPABILITIES(F) \ #define L_ENUM_VALUES_CHAT_ROOM_CAPABILITIES(F) \
F(Basic, 1 << 0) \ F(Basic, 1 << 0) \
F(RealTimeText, 1 << 1) \ F(RealTimeText, 1 << 1) \
F(Conference, 1 << 2) \ F(Conference, 1 << 2) \
F(Proxy, 1 << 3) \ F(Proxy, 1 << 3) \
F(Migratable, 1 << 4) F(Migratable, 1 << 4) \
F(OneToOne, 1 << 5)
#endif // ifndef _L_CHAT_ROOM_ENUMS_H_ #endif // ifndef _L_CHAT_ROOM_ENUMS_H_
...@@ -38,6 +38,7 @@ class LINPHONE_PUBLIC AbstractChatRoom : public Object, public CoreAccessor, pub ...@@ -38,6 +38,7 @@ class LINPHONE_PUBLIC AbstractChatRoom : public Object, public CoreAccessor, pub
friend class ChatMessage; friend class ChatMessage;
friend class ChatMessagePrivate; friend class ChatMessagePrivate;
friend class ClientGroupToBasicChatRoomPrivate; friend class ClientGroupToBasicChatRoomPrivate;
friend class Core;
friend class CorePrivate; friend class CorePrivate;
friend class MainDb; friend class MainDb;
friend class ProxyChatRoomPrivate; friend class ProxyChatRoomPrivate;
...@@ -66,6 +67,7 @@ public: ...@@ -66,6 +67,7 @@ public:
virtual std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const = 0; virtual std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const = 0;
virtual int getHistorySize () const = 0; virtual int getHistorySize () const = 0;
virtual void deleteFromDb () = 0;
virtual void deleteHistory () = 0; virtual void deleteHistory () = 0;
virtual std::shared_ptr<ChatMessage> getLastChatMessageInHistory () const = 0; virtual std::shared_ptr<ChatMessage> getLastChatMessageInHistory () const = 0;
......
...@@ -346,6 +346,12 @@ int ChatRoom::getHistorySize () const { ...@@ -346,6 +346,12 @@ int ChatRoom::getHistorySize () const {
return getCore()->getPrivate()->mainDb->getHistorySize(getChatRoomId()); return getCore()->getPrivate()->mainDb->getHistorySize(getChatRoomId());
} }
void ChatRoom::deleteFromDb () {
L_D();
Core::deleteChatRoom(this->getSharedFromThis());
d->setState(ChatRoom::State::Deleted);
}
void ChatRoom::deleteHistory () { void ChatRoom::deleteHistory () {
getCore()->getPrivate()->mainDb->cleanHistory(getChatRoomId()); getCore()->getPrivate()->mainDb->cleanHistory(getChatRoomId());
} }
......
...@@ -46,6 +46,7 @@ public: ...@@ -46,6 +46,7 @@ public:
std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const override; std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const override;
int getHistorySize () const override; int getHistorySize () const override;
void deleteFromDb () override;
void deleteHistory () override; void deleteHistory () override;
std::shared_ptr<ChatMessage> getLastChatMessageInHistory () const override; std::shared_ptr<ChatMessage> getLastChatMessageInHistory () const override;
......
...@@ -42,6 +42,7 @@ public: ...@@ -42,6 +42,7 @@ public:
// ChatRoomListener // ChatRoomListener
void onChatRoomInsertRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override; void onChatRoomInsertRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
void onChatRoomInsertInDatabaseRequested (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 // CallSessionListener
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override; void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override;
...@@ -50,6 +51,8 @@ public: ...@@ -50,6 +51,8 @@ public:
private: private:
CallSessionListener *callSessionListener = this; CallSessionListener *callSessionListener = this;
ChatRoomListener *chatRoomListener = this; ChatRoomListener *chatRoomListener = this;
ClientGroupChatRoom::CapabilitiesMask capabilities = ClientGroupChatRoom::Capabilities::Conference;
bool deletionOnTerminationEnabled = false;
L_DECLARE_PUBLIC(ClientGroupChatRoom); L_DECLARE_PUBLIC(ClientGroupChatRoom);
}; };
......
...@@ -62,6 +62,8 @@ shared_ptr<CallSession> ClientGroupChatRoomPrivate::createSession () { ...@@ -62,6 +62,8 @@ shared_ptr<CallSession> ClientGroupChatRoomPrivate::createSession () {
CallSessionParams csp; CallSessionParams csp;
csp.addCustomHeader("Require", "recipient-list-invite"); csp.addCustomHeader("Require", "recipient-list-invite");
csp.addCustomContactParameter("text"); csp.addCustomContactParameter("text");
if (capabilities & ClientGroupChatRoom::Capabilities::OneToOne)
csp.addCustomHeader("One-To-One-Chat-Room", "true");
shared_ptr<Participant> focus = qConference->getPrivate()->focus; shared_ptr<Participant> focus = qConference->getPrivate()->focus;
shared_ptr<CallSession> session = focus->getPrivate()->createSession(*q, &csp, false, callSessionListener); shared_ptr<CallSession> session = focus->getPrivate()->createSession(*q, &csp, false, callSessionListener);
...@@ -111,6 +113,12 @@ void ClientGroupChatRoomPrivate::onChatRoomInsertInDatabaseRequested (const shar ...@@ -111,6 +113,12 @@ void ClientGroupChatRoomPrivate::onChatRoomInsertInDatabaseRequested (const shar
q->getCore()->getPrivate()->insertChatRoomWithDb(chatRoom); q->getCore()->getPrivate()->insertChatRoomWithDb(chatRoom);
} }
void ClientGroupChatRoomPrivate::onChatRoomDeleteRequested (const shared_ptr<AbstractChatRoom> &chatRoom) {
L_Q();
q->getCore()->deleteChatRoom(q->getSharedFromThis());
setState(ClientGroupChatRoom::State::Deleted);
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ClientGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr<const CallSession> &session) { void ClientGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr<const CallSession> &session) {
...@@ -164,6 +172,7 @@ ClientGroupChatRoom::ClientGroupChatRoom ( ...@@ -164,6 +172,7 @@ ClientGroupChatRoom::ClientGroupChatRoom (
const shared_ptr<Core> &core, const shared_ptr<Core> &core,
const ChatRoomId &chatRoomId, const ChatRoomId &chatRoomId,
shared_ptr<Participant> &me, shared_ptr<Participant> &me,
AbstractChatRoom::CapabilitiesMask capabilities,
const string &subject, const string &subject,
list<shared_ptr<Participant>> &&participants, list<shared_ptr<Participant>> &&participants,
unsigned int lastNotifyId unsigned int lastNotifyId
...@@ -189,7 +198,8 @@ shared_ptr<Core> ClientGroupChatRoom::getCore () const { ...@@ -189,7 +198,8 @@ shared_ptr<Core> ClientGroupChatRoom::getCore () const {
} }
ClientGroupChatRoom::CapabilitiesMask ClientGroupChatRoom::getCapabilities () const { ClientGroupChatRoom::CapabilitiesMask ClientGroupChatRoom::getCapabilities () const {
return Capabilities::Conference; L_D();
return d->capabilities;
} }
bool ClientGroupChatRoom::hasBeenLeft () const { bool ClientGroupChatRoom::hasBeenLeft () const {
...@@ -208,6 +218,16 @@ const IdentityAddress &ClientGroupChatRoom::getConferenceAddress () const { ...@@ -208,6 +218,16 @@ const IdentityAddress &ClientGroupChatRoom::getConferenceAddress () const {
return RemoteConference::getConferenceAddress(); return RemoteConference::getConferenceAddress();
} }
void ClientGroupChatRoom::deleteFromDb () {
L_D();
if (!hasBeenLeft()) {
d->deletionOnTerminationEnabled = true;
leave();
return;
}
d->chatRoomListener->onChatRoomDeleteRequested(getSharedFromThis());
}
void ClientGroupChatRoom::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) { void ClientGroupChatRoom::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
list<IdentityAddress> addresses; list<IdentityAddress> addresses;
addresses.push_back(addr); addresses.push_back(addr);
...@@ -231,6 +251,19 @@ void ClientGroupChatRoom::addParticipants ( ...@@ -231,6 +251,19 @@ void ClientGroupChatRoom::addParticipants (
return; return;
} }
if ((getState() == ChatRoom::State::Created) && (d->capabilities & ClientGroupChatRoom::Capabilities::OneToOne)) {
lError() << "Cannot add more participants to a OneToOne ClientGroupChatRoom";
return;
}
if ((getState() == ChatRoom::State::Instantiated)
&& (addressesList.size() == 1)
&& (linphone_config_get_bool(linphone_core_get_config(L_GET_C_BACK_PTR(getCore())),
"misc", "one_to_one_chat_room_enabled", TRUE))
) {
d->capabilities |= ClientGroupChatRoom::Capabilities::OneToOne;
}
Content content; Content content;
content.setBody(getResourceLists(addressesList)); content.setBody(getResourceLists(addressesList));
content.setContentType("application/resource-lists+xml"); content.setContentType("application/resource-lists+xml");
...@@ -372,6 +405,11 @@ void ClientGroupChatRoom::onConferenceCreated (const IdentityAddress &addr) { ...@@ -372,6 +405,11 @@ void ClientGroupChatRoom::onConferenceCreated (const IdentityAddress &addr) {
d->chatRoomListener->onChatRoomInsertRequested(getSharedFromThis()); d->chatRoomListener->onChatRoomInsertRequested(getSharedFromThis());
} }
void ClientGroupChatRoom::onConferenceKeywordsChanged (const vector<string> &keywords) {
L_D();
d->capabilities |= ClientGroupChatRoom::Capabilities::OneToOne;
}
void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) { void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
L_D(); L_D();
L_D_T(RemoteConference, dConference); L_D_T(RemoteConference, dConference);
...@@ -382,6 +420,10 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) { ...@@ -382,6 +420,10 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
time(nullptr), time(nullptr),
d->chatRoomId d->chatRoomId
)); ));
if (d->deletionOnTerminationEnabled) {
d->deletionOnTerminationEnabled = false;
d->chatRoomListener->onChatRoomDeleteRequested(getSharedFromThis());
}
} }
void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) { void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
......
...@@ -32,6 +32,7 @@ class ClientGroupChatRoomPrivate; ...@@ -32,6 +32,7 @@ class ClientGroupChatRoomPrivate;
class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConference { class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConference {
friend class BasicToClientGroupChatRoomPrivate; friend class BasicToClientGroupChatRoomPrivate;
friend class ClientGroupToBasicChatRoomPrivate; friend class ClientGroupToBasicChatRoomPrivate;
friend class Core;
public: public:
L_OVERRIDE_SHARED_FROM_THIS(ClientGroupChatRoom); L_OVERRIDE_SHARED_FROM_THIS(ClientGroupChatRoom);
...@@ -48,6 +49,7 @@ public: ...@@ -48,6 +49,7 @@ public:
const std::shared_ptr<Core> &core, const std::shared_ptr<Core> &core,
const ChatRoomId &chatRoomId, const ChatRoomId &chatRoomId,
std::shared_ptr<Participant> &me, std::shared_ptr<Participant> &me,
AbstractChatRoom::CapabilitiesMask capabilities,
const std::string &subject, const std::string &subject,
std::list<std::shared_ptr<Participant>> &&participants, std::list<std::shared_ptr<Participant>> &&participants,
unsigned int lastNotifyId unsigned int lastNotifyId
...@@ -63,6 +65,8 @@ public: ...@@ -63,6 +65,8 @@ public:
bool canHandleParticipants () const override; bool canHandleParticipants () const override;
bool canHandleCpim () const override; bool canHandleCpim () const override;
void deleteFromDb () override;
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override; void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override; void addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override;
...@@ -88,6 +92,7 @@ private: ...@@ -88,6 +92,7 @@ private:
// ALL METHODS AFTER THIS POINT. // ALL METHODS AFTER THIS POINT.
void onConferenceCreated (const IdentityAddress &addr) override; void onConferenceCreated (const IdentityAddress &addr) override;
void onConferenceKeywordsChanged (const std::vector<std::string> &keywords) override;
void onConferenceTerminated (const IdentityAddress &addr) override; void onConferenceTerminated (const IdentityAddress &addr) override;
void onFirstNotifyReceived (const IdentityAddress &addr) override; void onFirstNotifyReceived (const IdentityAddress &addr) override;
void onParticipantAdded (const std::shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) override; void onParticipantAdded (const std::shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) override;
......
...@@ -46,6 +46,12 @@ public: ...@@ -46,6 +46,12 @@ public:
q->getCore()->getPrivate()->insertChatRoomWithDb(q->getSharedFromThis()); q->getCore()->getPrivate()->insertChatRoomWithDb(q->getSharedFromThis());
} }
void onChatRoomDeleteRequested (const shared_ptr<AbstractChatRoom> &chatRoom) override {
L_Q();
q->getCore()->deleteChatRoom(q->getSharedFromThis());
setState(AbstractChatRoom::State::Deleted);
}
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override { void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override {
if (!(chatRoom->getCapabilities() & ChatRoom::Capabilities::Conference)) if (!(chatRoom->getCapabilities() & ChatRoom::Capabilities::Conference))
return; return;
......
...@@ -190,6 +190,11 @@ int ProxyChatRoom::getHistorySize () const { ...@@ -190,6 +190,11 @@ int ProxyChatRoom::getHistorySize () const {
return d->chatRoom->getHistorySize(); return d->chatRoom->getHistorySize();
} }
void ProxyChatRoom::deleteFromDb () {
L_D();
d->chatRoom->deleteFromDb();
}
void ProxyChatRoom::deleteHistory () { void ProxyChatRoom::deleteHistory () {
L_D(); L_D();
d->chatRoom->deleteHistory(); d->chatRoom->deleteHistory();
......
...@@ -47,6 +47,7 @@ public: ...@@ -47,6 +47,7 @@ public:
std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const override; std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const override;
int getHistorySize () const override; int getHistorySize () const override;
void deleteFromDb () override;
void deleteHistory () override; void deleteHistory () override;
std::shared_ptr<ChatMessage> getLastChatMessageInHistory () const override; std::shared_ptr<ChatMessage> getLastChatMessageInHistory () const override;
......
...@@ -35,6 +35,7 @@ public: ...@@ -35,6 +35,7 @@ public:
void confirmCreation (); void confirmCreation ();
void confirmJoining (SalCallOp *op); void confirmJoining (SalCallOp *op);
void confirmRecreation (SalCallOp *op);
IdentityAddress generateConferenceAddress (const std::shared_ptr<Participant> &me) const; IdentityAddress generateConferenceAddress (const std::shared_ptr<Participant> &me) const;
...@@ -43,10 +44,9 @@ public: ...@@ -43,10 +44,9 @@ public:
void update (SalCallOp *op); void update (SalCallOp *op);
void dispatchMessage (const IdentityAddress &fromAddress, const Content &content); void dispatchMessage (const IdentityAddress &fromAddress, const Content &content);
void setConferenceAddress (const IdentityAddress &conferenceAddress); void setConferenceAddress (const IdentityAddress &conferenceAddress);
void setParticipantDevices (const IdentityAddress &addr, const std::list<IdentityAddress> &devices); void setParticipantDevices (const IdentityAddress &addr, const std::list<IdentityAddress> &devices);
void addCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &participantCompatible); void addCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &compatibleParticipants);
LinphoneReason onSipMessageReceived (SalOp *op, const SalMessage *message) override; LinphoneReason onSipMessageReceived (SalOp *op, const SalMessage *message) override;
...@@ -63,12 +63,14 @@ private: ...@@ -63,12 +63,14 @@ private:
// CallSessionListener // CallSessionListener
void onCallSessionStateChanged ( void onCallSessionStateChanged (
const std::shared_ptr<const CallSession> &session, const std::shared_ptr<const CallSession> &session,
CallSession::State state, CallSession::State newState,
const std::string &message const std::string &message
) override; ) override;
std::list<std::shared_ptr<Participant>> removedParticipants; std::list<std::shared_ptr<Participant>> removedParticipants;
ChatRoomListener *chatRoomListener = this; ChatRoomListener *chatRoomListener = this;
ServerGroupChatRoom::CapabilitiesMask capabilities = ServerGroupChatRoom::Capabilities::Conference;
bool joiningPendingAfterCreation = false;
L_DECLARE_PUBLIC(ServerGroupChatRoom); L_DECLARE_PUBLIC(ServerGroupChatRoom);
}; };
......
...@@ -46,6 +46,8 @@ void ServerGroupChatRoomPrivate::confirmCreation () {} ...@@ -46,6 +46,8 @@ void ServerGroupChatRoomPrivate::confirmCreation () {}
void ServerGroupChatRoomPrivate::confirmJoining (SalCallOp *) {} void ServerGroupChatRoomPrivate::confirmJoining (SalCallOp *) {}
void ServerGroupChatRoomPrivate::confirmRecreation (SalCallOp *) {}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
IdentityAddress ServerGroupChatRoomPrivate::generateConferenceAddress (const shared_ptr<Participant> &me) const { IdentityAddress ServerGroupChatRoomPrivate::generateConferenceAddress (const shared_ptr<Participant> &me) const {
...@@ -110,6 +112,7 @@ LocalConference(core, IdentityAddress(op->get_to()), nullptr) { ...@@ -110,6 +112,7 @@ LocalConference(core, IdentityAddress(op->get_to()), nullptr) {
ServerGroupChatRoom::ServerGroupChatRoom ( ServerGroupChatRoom::ServerGroupChatRoom (
const shared_ptr<Core> &core, const shared_ptr<Core> &core,
const IdentityAddress &peerAddress, const IdentityAddress &peerAddress,
AbstractChatRoom::CapabilitiesMask capabilities,
const string &subject, const string &subject,
list<shared_ptr<Participant>> &&participants, list<shared_ptr<Participant>> &&participants,
unsigned int lastNotifyId unsigned int lastNotifyId
......
...@@ -39,11 +39,16 @@ public: ...@@ -39,11 +39,16 @@ public:
ServerGroupChatRoom ( ServerGroupChatRoom (
const std::shared_ptr<Core> &core, const std::shared_ptr<Core> &core,
const IdentityAddress &peerAddress, const IdentityAddress &peerAddress,
AbstractChatRoom::CapabilitiesMask capabilities,
const std::string &subject, const std::string &subject,
std::list<std::shared_ptr<Participant>> &&participants, std::list<std::shared_ptr<Participant>> &&participants,
unsigned int lastNotifyId unsigned int lastNotifyId
); );
std::shared_ptr<Core> getCore () const;
std::shared_ptr<Participant> findParticipant (const std::shared_ptr<const CallSession> &session) const;
CapabilitiesMask getCapabilities () const override; CapabilitiesMask getCapabilities () const override;
bool hasBeenLeft () const override; bool hasBeenLeft () const override;
......
...@@ -22,6 +22,7 @@ ...@@ -22,6 +22,7 @@
#include <ctime> #include <ctime>
#include <string> #include <string>
#include <vector>
#include "linphone/utils/general.h" #include "linphone/utils/general.h"
...@@ -36,6 +37,7 @@ class IdentityAddress; ...@@ -36,6 +37,7 @@ class IdentityAddress;
class ConferenceListener { class ConferenceListener {
public: public:
virtual void onConferenceCreated (const IdentityAddress &addr) = 0; virtual void onConferenceCreated (const IdentityAddress &addr) = 0;
virtual void onConferenceKeywordsChanged (const std::vector<std::string> &keywords) {}
virtual void onConferenceTerminated (const IdentityAddress &addr) = 0; virtual void onConferenceTerminated (const IdentityAddress &addr) = 0;
virtual void onFirstNotifyReceived (const IdentityAddress &addr) = 0; virtual void onFirstNotifyReceived (const IdentityAddress &addr) = 0;
virtual void onParticipantAdded (const std::shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) = 0; virtual void onParticipantAdded (const std::shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) = 0;
......
...@@ -37,7 +37,7 @@ public: ...@@ -37,7 +37,7 @@ public:
void notifyFullState (const std::string &notify, const std::shared_ptr<ParticipantDevice> &device); void notifyFullState (const std::string &notify, const std::shared_ptr<ParticipantDevice> &device);
void notifyAllExcept (const std::string &notify, const std::shared_ptr<Participant> &exceptParticipant); void notifyAllExcept (const std::string &notify, const std::shared_ptr<Participant> &exceptParticipant);
void notifyAll (const std::string &notify); void notifyAll (const std::string &notify);
std::string createNotifyFullState (int notifyId = -1); std::string createNotifyFullState (int notifyId = -1, bool oneToOne = false);
std::string createNotifyMultipart (int notifyId); std::string createNotifyMultipart (int notifyId);
std::string createNotifyParticipantAdded (const Address &addr, int notifyId = -1); std::string createNotifyParticipantAdded (const Address &addr, int notifyId = -1);
std::string createNotifyParticipantRemoved (const Address &addr, int notifyId = -1); std::string createNotifyParticipantRemoved (const Address &addr, int notifyId = -1);
......
...@@ -107,13 +107,17 @@ string LocalConferenceEventHandlerPrivate::createNotify (ConferenceType confInfo ...@@ -107,13 +107,17 @@ string LocalConferenceEventHandlerPrivate::createNotify (ConferenceType confInfo
return notify.str(); return notify.str();
} }
string LocalConferenceEventHandlerPrivate::createNotifyFullState (int notifyId) { string LocalConferenceEventHandlerPrivate::createNotifyFullState (int notifyId, bool oneToOne) {
string entity = conf->getConferenceAddress().asString(); string entity = conf->getConferenceAddress().asString();
string subject = conf->getSubject(); string subject = conf->getSubject();
ConferenceType confInfo = ConferenceType(entity); ConferenceType confInfo = ConferenceType(entity);
UsersType users; UsersType users;
ConferenceDescriptionType confDescr = ConferenceDescriptionType(); ConferenceDescriptionType confDescr = ConferenceDescriptionType();
confDescr.setSubject(subject); confDescr.setSubject(subject);
if (oneToOne) {
KeywordsType keywords(sizeof(char), "one-to-one");
confDescr.setKeywords(keywords);
}
confInfo.setUsers(users); confInfo.setUsers(users);
confInfo.setConferenceDescription((const ConferenceDescriptionType) confDescr); confInfo.setConferenceDescription((const ConferenceDescriptionType) confDescr);
...@@ -357,18 +361,13 @@ string LocalConferenceEventHandlerPrivate::createNotifyParticipantDeviceRemoved ...@@ -357,18 +361,13 @@ string LocalConferenceEventHandlerPrivate::createNotifyParticipantDeviceRemoved
LocalConferenceEventHandler::LocalConferenceEventHandler (LocalConference *localConference, unsigned int notify) : LocalConferenceEventHandler::LocalConferenceEventHandler (LocalConference *localConference, unsigned int notify) :
Object(*new LocalConferenceEventHandlerPrivate) { Object(*new LocalConferenceEventHandlerPrivate) {
L_D(); L_D();
xercesc::XMLPlatformUtils::Initialize();
d->conf = localConference; d->conf = localConference;
d->lastNotify = notify; d->lastNotify = notify;
} }
LocalConferenceEventHandler::~LocalConferenceEventHandler () {
xercesc::XMLPlatformUtils::Terminate();
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev) { void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev, bool oneToOne) {
L_D(); L_D();
const LinphoneAddress *lAddr = linphone_event_get_from(lev); const LinphoneAddress *lAddr = linphone_event_get_from(lev);
char *addrStr = linphone_address_as_string(lAddr); char *addrStr = linphone_address_as_string(lAddr);
...@@ -396,7 +395,7 @@ void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev) { ...@@ -396,7 +395,7 @@ void LocalConferenceEventHandler::subscribeReceived (LinphoneEvent *lev) {
device->setConferenceSubscribeEvent(lev); device->setConferenceSubscribeEvent(lev);
if (lastNotify == 0) { if (lastNotify == 0) {
lInfo() << "Sending initial notify of conference:" << d->conf->getConferenceAddress().asString() << " to: " << device->getAddress().asString(); lInfo() << "Sending initial notify of conference:" << d->conf->getConferenceAddress().asString() << " to: " << device->getAddress().asString();
d->notifyFullState(d->createNotifyFullState(static_cast<int>(d->lastNotify)), device); d->notifyFullState(d->createNotifyFullState(static_cast<int>(d->lastNotify), oneToOne), device);
} else if (lastNotify < d->lastNotify) { } else if (lastNotify < d->lastNotify) {
lInfo() << "Sending all missed notify [" << lastNotify << "-" << d->lastNotify << lInfo() << "Sending all missed notify [" << lastNotify << "-" << d->lastNotify <<
"] for conference:" << d->conf->getConferenceAddress().asString() << "] for conference:" << d->conf->getConferenceAddress().asString() <<
......
...@@ -42,9 +42,8 @@ class LocalConferenceEventHandlerPrivate; ...@@ -42,9 +42,8 @@ class LocalConferenceEventHandlerPrivate;
class LocalConferenceEventHandler : public Object { class LocalConferenceEventHandler : public Object {
public: public:
LocalConferenceEventHandler (LocalConference *localConference, unsigned int notify = 0); LocalConferenceEventHandler (LocalConference *localConference, unsigned int notify = 0);
~LocalConferenceEventHandler ();
void subscribeReceived (LinphoneEvent *lev); void subscribeReceived (LinphoneEvent *lev, bool oneToOne = false);
std::shared_ptr<ConferenceParticipantEvent> notifyParticipantAdded (const Address &addr); std::shared_ptr<ConferenceParticipantEvent> notifyParticipantAdded (const Address &addr);
std::shared_ptr<ConferenceParticipantEvent> notifyParticipantRemoved (const Address &addr); std::shared_ptr<ConferenceParticipantEvent> notifyParticipantRemoved (const Address &addr);
std::shared_ptr<ConferenceParticipantEvent> notifyParticipantSetAdmin (const Address &addr, bool isAdmin); std::shared_ptr<ConferenceParticipantEvent> notifyParticipantSetAdmin (const Address &addr, bool isAdmin);
......
...@@ -17,6 +17,8 @@ ...@@ -17,6 +17,8 @@
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/ */
#include <sstream>
#include "linphone/utils/utils.h" #include "linphone/utils/utils.h"
#include "conference/remote-conference.h" #include "conference/remote-conference.h"
...@@ -53,20 +55,30 @@ void RemoteConferenceEventHandlerPrivate::simpleNotifyReceived (const string &xm ...@@ -53,20 +55,30 @@ void RemoteConferenceEventHandlerPrivate::simpleNotifyReceived (const string &xm
IdentityAddress entityAddress(confInfo->getEntity().c_str()); IdentityAddress entityAddress(confInfo->getEntity().c_str());
if (entityAddress == chatRoomId.getPeerAddress()) { if (entityAddress == chatRoomId.getPeerAddress()) {
if ( if (confInfo->getConferenceDescription().present()) {
confInfo->getConferenceDescription().present() && if (confInfo->getConferenceDescription().get().getSubject().present() &&
confInfo->getConferenceDescription().get().getSubject().present() && !confInfo->getConferenceDescription().get().getSubject().get().empty()
!confInfo->getConferenceDescription().get().getSubject().get().empty() ) {
) confListener->onSubjectChanged(
confListener->onSubjectChanged( make_shared<ConferenceSubjectEvent>(
make_shared<ConferenceSubjectEvent>( tm,
tm, chatRoomId,
chatRoomId, lastNotify,
lastNotify, confInfo->getConferenceDescription().get().getSubject().get()
confInfo->getConferenceDescription().get().getSubject().get() ),
), isFullState
isFullState );