Commit 8298c5ea authored by Ronan's avatar Ronan Committed by Ronan

fix(chat-room): handle correctly errors + avoid re-creation of one-to-one chat room

parent fc67d35e
......@@ -122,7 +122,9 @@ static void call_received(SalCallOp *h) {
}
// TODO: handle media conference creation if the "text" feature tag is not present
return;
} else if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
}
if (sal_address_has_param(h->getRemoteContactAddress(), "text")) {
linphone_address_unref(toAddr);
linphone_address_unref(fromAddr);
if (linphone_core_conference_server_enabled(lc)) {
......
......@@ -81,20 +81,24 @@ const IdentityAddress &BasicChatRoom::getConferenceAddress () const {
return Utils::getEmptyConstRefObject<IdentityAddress>();
}
void BasicChatRoom::addParticipant (const IdentityAddress &, const CallSessionParams *, bool) {
bool BasicChatRoom::addParticipant (const IdentityAddress &, const CallSessionParams *, bool) {
lError() << "addParticipant() is not allowed on a BasicChatRoom";
return false;
}
void BasicChatRoom::addParticipants (const list<IdentityAddress> &, const CallSessionParams *, bool) {
bool BasicChatRoom::addParticipants (const list<IdentityAddress> &, const CallSessionParams *, bool) {
lError() << "addParticipants() is not allowed on a BasicChatRoom";
return false;
}
void BasicChatRoom::removeParticipant (const shared_ptr<Participant> &) {
bool BasicChatRoom::removeParticipant (const shared_ptr<Participant> &) {
lError() << "removeParticipant() is not allowed on a BasicChatRoom";
return false;
}
void BasicChatRoom::removeParticipants (const list<shared_ptr<Participant>> &) {
bool BasicChatRoom::removeParticipants (const list<shared_ptr<Participant>> &) {
lError() << "removeParticipants() is not allowed on a BasicChatRoom";
return false;
}
shared_ptr<Participant> BasicChatRoom::findParticipant (const IdentityAddress &) const {
......
......@@ -45,11 +45,11 @@ public:
bool canHandleParticipants () const 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;
bool addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
bool addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
bool removeParticipant (const std::shared_ptr<Participant> &participant) override;
bool removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &addr) const override;
......
......@@ -351,17 +351,17 @@ void ClientGroupChatRoom::deleteFromDb () {
d->chatRoomListener->onChatRoomDeleteRequested(getSharedFromThis());
}
void ClientGroupChatRoom::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
bool ClientGroupChatRoom::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
L_D();
if ((getState() != ChatRoom::State::Instantiated) && (getState() != ChatRoom::State::Created)) {
lError() << "Cannot add participants to the ClientGroupChatRoom in a state other than Instantiated or Created";
return;
return false;
}
if ((getState() == ChatRoom::State::Created) && (d->capabilities & ClientGroupChatRoom::Capabilities::OneToOne)) {
lError() << "Cannot add more participants to a OneToOne ClientGroupChatRoom";
return;
return false;
}
LinphoneCore *cCore = getCore()->getCCore();
......@@ -386,9 +386,11 @@ void ClientGroupChatRoom::addParticipant (const IdentityAddress &addr, const Cal
referOp->sendRefer(referToAddr.getPrivate()->getInternalAddress());
referOp->unref();
}
return true;
}
void ClientGroupChatRoom::addParticipants (
bool ClientGroupChatRoom::addParticipants (
const list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
......@@ -396,8 +398,10 @@ void ClientGroupChatRoom::addParticipants (
L_D();
list<IdentityAddress> addressesList = d->cleanAddressesList(addresses);
if (addressesList.empty())
return;
if (addressesList.empty()) {
lError() << "No participants given.";
return false;
}
if ((getState() == ChatRoom::State::Instantiated)
&& (addressesList.size() == 1)
......@@ -405,6 +409,14 @@ void ClientGroupChatRoom::addParticipants (
"misc", "one_to_one_chat_room_enabled", TRUE))
) {
d->capabilities |= ClientGroupChatRoom::Capabilities::OneToOne;
const IdentityAddress &me = getMe()->getAddress();
const IdentityAddress &participant = addresses.front();
auto existingChatRoom = getCore()->findOneToOneChatRoom(getLocalAddress(), participant);
if (existingChatRoom) {
lError() << "Trying to create already existing one-to-one chatroom with participants: " <<
me << ", " << participant;
return false;
}
}
if (getState() == ChatRoom::State::Instantiated) {
......@@ -422,9 +434,11 @@ void ClientGroupChatRoom::addParticipants (
for (const auto &addr : addresses)
addParticipant(addr, params, hasMedia);
}
return true;
}
void ClientGroupChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
bool ClientGroupChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
LinphoneCore *cCore = getCore()->getCCore();
SalReferOp *referOp = new SalReferOp(cCore->sal);
......@@ -436,10 +450,12 @@ void ClientGroupChatRoom::removeParticipant (const shared_ptr<Participant> &part
referToAddr.setUriParam("method", "BYE");
referOp->sendRefer(referToAddr.getPrivate()->getInternalAddress());
referOp->unref();
return true;
}
void ClientGroupChatRoom::removeParticipants (const list<shared_ptr<Participant>> &participants) {
RemoteConference::removeParticipants(participants);
bool ClientGroupChatRoom::removeParticipants (const list<shared_ptr<Participant>> &participants) {
return RemoteConference::removeParticipants(participants);
}
shared_ptr<Participant> ClientGroupChatRoom::findParticipant (const IdentityAddress &addr) const {
......
......@@ -76,11 +76,11 @@ public:
void deleteFromDb () 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;
bool addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
bool addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
bool removeParticipant (const std::shared_ptr<Participant> &participant) override;
bool removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &addr) const override;
......
......@@ -105,7 +105,7 @@ private:
ClientGroupToBasicChatRoom::ClientGroupToBasicChatRoom (const shared_ptr<ChatRoom> &chatRoom) :
ProxyChatRoom(*new ClientGroupToBasicChatRoomPrivate, chatRoom) {}
void ClientGroupToBasicChatRoom::addParticipant (
bool ClientGroupToBasicChatRoom::addParticipant (
const IdentityAddress &participantAddress,
const CallSessionParams *params,
bool hasMedia
......@@ -115,9 +115,9 @@ void ClientGroupToBasicChatRoom::addParticipant (
d->invitedAddresses.clear();
d->invitedAddresses.push_back(participantAddress);
}
ProxyChatRoom::addParticipant(participantAddress, params, hasMedia);
return ProxyChatRoom::addParticipant(participantAddress, params, hasMedia);
}
void ClientGroupToBasicChatRoom::addParticipants (
bool ClientGroupToBasicChatRoom::addParticipants (
const list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
......@@ -125,7 +125,7 @@ void ClientGroupToBasicChatRoom::addParticipants (
L_D();
if ((getState() == ChatRoom::State::Instantiated) && (addresses.size() == 1))
d->invitedAddresses = addresses;
ProxyChatRoom::addParticipants(addresses, params, hasMedia);
return ProxyChatRoom::addParticipants(addresses, params, hasMedia);
}
LINPHONE_END_NAMESPACE
......@@ -32,12 +32,12 @@ class LINPHONE_PUBLIC ClientGroupToBasicChatRoom : public ProxyChatRoom {
public:
ClientGroupToBasicChatRoom (const std::shared_ptr<ChatRoom> &chatRoom);
void addParticipant (
bool addParticipant (
const IdentityAddress &participantAddress,
const CallSessionParams *params,
bool hasMedia
) override;
void addParticipants (
bool addParticipants (
const std::list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
......
......@@ -230,7 +230,7 @@ bool ProxyChatRoom::canHandleParticipants () const {
return d->chatRoom->canHandleParticipants();
}
void ProxyChatRoom::addParticipant (
bool ProxyChatRoom::addParticipant (
const IdentityAddress &participantAddress,
const CallSessionParams *params,
bool hasMedia
......@@ -239,7 +239,7 @@ void ProxyChatRoom::addParticipant (
return d->chatRoom->addParticipant(participantAddress, params, hasMedia);
}
void ProxyChatRoom::addParticipants (
bool ProxyChatRoom::addParticipants (
const list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
......@@ -248,14 +248,14 @@ void ProxyChatRoom::addParticipants (
return d->chatRoom->addParticipants(addresses, params, hasMedia);
}
void ProxyChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
bool ProxyChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
L_D();
d->chatRoom->removeParticipant(participant);
return d->chatRoom->removeParticipant(participant);
}
void ProxyChatRoom::removeParticipants (const list<shared_ptr<Participant>> &participants) {
bool ProxyChatRoom::removeParticipants (const list<shared_ptr<Participant>> &participants) {
L_D();
d->chatRoom->removeParticipants(participants);
return d->chatRoom->removeParticipants(participants);
}
shared_ptr<Participant> ProxyChatRoom::findParticipant (const IdentityAddress &participantAddress) const {
......
......@@ -85,19 +85,19 @@ public:
bool canHandleParticipants () const override;
void addParticipant (
bool addParticipant (
const IdentityAddress &participantAddress,
const CallSessionParams *params,
bool hasMedia
) override;
void addParticipants (
bool addParticipants (
const std::list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
bool removeParticipant (const std::shared_ptr<Participant> &participant) override;
bool removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &participantAddress) const override;
......
......@@ -885,17 +885,17 @@ bool ServerGroupChatRoom::hasBeenLeft () const {
// -----------------------------------------------------------------------------
void ServerGroupChatRoom::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
bool ServerGroupChatRoom::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
L_D();
L_D_T(LocalConference, dConference);
if (d->findFilteredParticipant(addr)) {
lInfo() << this << ": Not adding participant '" << addr.asString() << "' because it is already a participant";
return;
return false;
}
if ((d->capabilities & ServerGroupChatRoom::Capabilities::OneToOne) && (getParticipantCount() == 2)) {
lInfo() << this << ": Not adding participant '" << addr.asString() << "' because this OneToOne chat room already has 2 participants";
return;
return false;
}
lInfo() << this << ": Adding participant '" << addr.asString() << "'";
......@@ -909,10 +909,12 @@ void ServerGroupChatRoom::addParticipant (const IdentityAddress &addr, const Cal
LinphoneAddress *laddr = linphone_address_new(addr.asString().c_str());
CALL_CHAT_ROOM_CBS(cr, ParticipantDeviceFetchRequested, participant_device_fetch_requested, cr, laddr);
linphone_address_unref(laddr);
return true;
}
void ServerGroupChatRoom::addParticipants (const list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) {
LocalConference::addParticipants(addresses, params, hasMedia);
bool ServerGroupChatRoom::addParticipants (const list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) {
return LocalConference::addParticipants(addresses, params, hasMedia);
}
bool ServerGroupChatRoom::canHandleParticipants () const {
......@@ -961,7 +963,7 @@ void ServerGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
}
}
void ServerGroupChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
bool ServerGroupChatRoom::removeParticipant (const shared_ptr<Participant> &participant) {
L_D();
for (const auto &device : participant->getPrivate()->getDevices()) {
if ((d->getParticipantDeviceState(device) == ParticipantDevice::State::Leaving)
......@@ -973,10 +975,11 @@ void ServerGroupChatRoom::removeParticipant (const shared_ptr<Participant> &part
d->byeDevice(device);
}
d->removeParticipant(participant);
return true;
}
void ServerGroupChatRoom::removeParticipants (const list<shared_ptr<Participant>> &participants) {
LocalConference::removeParticipants(participants);
bool ServerGroupChatRoom::removeParticipants (const list<shared_ptr<Participant>> &participants) {
return LocalConference::removeParticipants(participants);
}
void ServerGroupChatRoom::setParticipantAdminStatus (const shared_ptr<Participant> &participant, bool isAdmin) {
......
......@@ -63,15 +63,15 @@ public:
bool canHandleParticipants () const override;
void addParticipant (const IdentityAddress &address, const CallSessionParams *params, bool hasMedia) override;
void addParticipants (
bool addParticipant (const IdentityAddress &address, const CallSessionParams *params, bool hasMedia) override;
bool addParticipants (
const std::list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
bool removeParticipant (const std::shared_ptr<Participant> &participant) override;
bool removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &participantAddress) const override;
......
......@@ -36,12 +36,12 @@ class LINPHONE_PUBLIC ConferenceInterface {
public:
virtual ~ConferenceInterface () = default;
virtual void addParticipant (
virtual bool addParticipant (
const IdentityAddress &participantAddress,
const CallSessionParams *params,
bool hasMedia
) = 0;
virtual void addParticipants (
virtual bool addParticipants (
const std::list<IdentityAddress> &addresses,
const CallSessionParams *params,
bool hasMedia
......@@ -55,8 +55,8 @@ public:
virtual const std::string &getSubject () const = 0;
virtual void join () = 0;
virtual void leave () = 0;
virtual void removeParticipant (const std::shared_ptr<Participant> &participant) = 0;
virtual void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) = 0;
virtual bool removeParticipant (const std::shared_ptr<Participant> &participant) = 0;
virtual bool removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) = 0;
virtual void setParticipantAdminStatus (const std::shared_ptr<Participant> &participant, bool isAdmin) = 0;
virtual void setSubject (const std::string &subject) = 0;
};
......
......@@ -58,16 +58,20 @@ shared_ptr<Participant> Conference::getActiveParticipant () const {
// -----------------------------------------------------------------------------
void Conference::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
bool Conference::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
lError() << "Conference class does not handle addParticipant() generically";
return false;
}
void Conference::addParticipants (const list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) {
bool Conference::addParticipants (const list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) {
list<IdentityAddress> sortedAddresses(addresses);
sortedAddresses.sort();
sortedAddresses.unique();
for (const auto &addr: sortedAddresses)
addParticipant(addr, params, hasMedia);
bool soFarSoGood = true;
for (const auto &address : sortedAddresses)
soFarSoGood &= addParticipant(address, params, hasMedia);
return soFarSoGood;
}
bool Conference::canHandleParticipants () const {
......@@ -102,13 +106,16 @@ void Conference::join () {}
void Conference::leave () {}
void Conference::removeParticipant (const shared_ptr<Participant> &participant) {
bool Conference::removeParticipant (const shared_ptr<Participant> &participant) {
lError() << "Conference class does not handle removeParticipant() generically";
return false;
}
void Conference::removeParticipants (const list<shared_ptr<Participant>> &participants) {
bool Conference::removeParticipants (const list<shared_ptr<Participant>> &participants) {
bool soFarSoGood = true;
for (const auto &p : participants)
removeParticipant(p);
soFarSoGood &= removeParticipant(p);
return soFarSoGood;
}
void Conference::setParticipantAdminStatus (const shared_ptr<Participant> &participant, bool isAdmin) {
......
......@@ -52,8 +52,8 @@ public:
std::shared_ptr<ParticipantDevice> findParticipantDevice (const std::shared_ptr<const CallSession> &session) const;
/* ConferenceInterface */
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override;
bool addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
bool addParticipants (const std::list<IdentityAddress> &addresses, const CallSessionParams *params, bool hasMedia) override;
bool canHandleParticipants () const override;
std::shared_ptr<Participant> findParticipant (const IdentityAddress &addr) const override;
const IdentityAddress &getConferenceAddress () const override;
......@@ -63,8 +63,8 @@ public:
const std::string &getSubject () const override;
void join () override;
void leave () override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
void removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
bool removeParticipant (const std::shared_ptr<Participant> &participant) override;
bool removeParticipants (const std::list<std::shared_ptr<Participant>> &participants) override;
void setParticipantAdminStatus (const std::shared_ptr<Participant> &participant, bool isAdmin) override;
void setSubject (const std::string &subject) override;
......
......@@ -41,28 +41,30 @@ LocalConference::~LocalConference () {
// -----------------------------------------------------------------------------
void LocalConference::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
bool LocalConference::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
L_D();
shared_ptr<Participant> participant = findParticipant(addr);
if (participant) {
lInfo() << "Not adding participant '" << addr.asString() << "' because it is already a participant of the LocalConference";
return;
return false;
}
participant = make_shared<Participant>(this, addr);
participant->getPrivate()->createSession(*this, params, hasMedia, d->listener);
d->participants.push_back(participant);
if (!d->activeParticipant)
d->activeParticipant = participant;
return true;
}
void LocalConference::removeParticipant (const shared_ptr<Participant> &participant) {
bool LocalConference::removeParticipant (const shared_ptr<Participant> &participant) {
L_D();
for (const auto &p : d->participants) {
if (participant->getAddress() == p->getAddress()) {
d->participants.remove(p);
return;
return true;
}
}
return false;
}
LINPHONE_END_NAMESPACE
......@@ -36,8 +36,8 @@ public:
virtual ~LocalConference ();
/* ConferenceInterface */
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
bool addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
bool removeParticipant (const std::shared_ptr<Participant> &participant) override;
private:
L_DECLARE_PRIVATE(LocalConference);
......
......@@ -44,28 +44,30 @@ RemoteConference::~RemoteConference () {
// -----------------------------------------------------------------------------
void RemoteConference::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
bool RemoteConference::addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) {
L_D();
shared_ptr<Participant> participant = findParticipant(addr);
if (participant) {
lInfo() << "Not adding participant '" << addr.asString() << "' because it is already a participant of the RemoteConference";
return;
return false;
}
participant = make_shared<Participant>(this, addr);
participant->getPrivate()->createSession(*this, params, hasMedia, d->listener);
d->participants.push_back(participant);
if (!d->activeParticipant)
d->activeParticipant = participant;
return true;
}
void RemoteConference::removeParticipant (const shared_ptr<Participant> &participant) {
bool RemoteConference::removeParticipant (const shared_ptr<Participant> &participant) {
L_D();
for (const auto &p : d->participants) {
if (participant->getAddress() == p->getAddress()) {
d->participants.remove(p);
return;
return true;
}
}
return false;
}
// -----------------------------------------------------------------------------
......
......@@ -37,8 +37,8 @@ public:
virtual ~RemoteConference ();
/* ConferenceInterface */
void addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
void removeParticipant (const std::shared_ptr<Participant> &participant) override;
bool addParticipant (const IdentityAddress &addr, const CallSessionParams *params, bool hasMedia) override;
bool removeParticipant (const std::shared_ptr<Participant> &participant) override;
protected:
/* ConferenceListener */
......
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