Add the SimpleAddress class to ease the comparison of addresses for the conference participants and the list of chat rooms.

This commit is contained in:
Ghislain MARY 2017-11-07 15:27:09 +01:00
parent 5e13c30a04
commit 120117f7b3
13 changed files with 307 additions and 71 deletions

View file

@ -23,6 +23,8 @@
set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
address/address-p.h
address/address.h
address/simple-address-p.h
address/simple-address.h
c-wrapper/c-wrapper.h
c-wrapper/internal/c-sal.h
c-wrapper/internal/c-tools.h
@ -134,6 +136,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
address/address.cpp
address/simple-address.cpp
c-wrapper/api/c-address.cpp
c-wrapper/api/c-call-cbs.cpp
c-wrapper/api/c-call-params.cpp

View file

@ -22,6 +22,7 @@
#include "address-p.h"
#include "c-wrapper/c-wrapper.h"
#include "logger/logger.h"
#include "address/simple-address.h"
// =============================================================================
@ -34,8 +35,7 @@ LINPHONE_BEGIN_NAMESPACE
Address::Address (const string &address) : ClonableObject(*new AddressPrivate) {
L_D();
if (!(d->internalAddress = sal_address_new(L_STRING_TO_C(address)))) {
lWarning() << "Cannot create address, bad uri [" << address << "].";
return;
lWarning() << "Cannot create Address, bad uri [" << address << "]";
}
}
@ -46,6 +46,18 @@ Address::Address (const Address &src) : ClonableObject(*new AddressPrivate) {
d->internalAddress = sal_address_clone(salAddress);
}
Address::Address (const SimpleAddress &src) : ClonableObject(*new AddressPrivate) {
L_D();
string uri = src.getScheme() + ":" + src.getUsername() + "@";
if (src.getDomain().find(':') != string::npos)
uri += "[" + src.getDomain() + "]";
else
uri += src.getDomain();
if (!(d->internalAddress = sal_address_new(L_STRING_TO_C(uri)))) {
lWarning() << "Cannot create Address, bad SimpleAddress source";
}
}
Address::~Address () {
L_D();
if (d->internalAddress)

View file

@ -28,6 +28,7 @@
LINPHONE_BEGIN_NAMESPACE
class AddressPrivate;
class SimpleAddress;
class LINPHONE_PUBLIC Address : public ClonableObject {
// TODO: Remove me later.
@ -36,10 +37,12 @@ class LINPHONE_PUBLIC Address : public ClonableObject {
friend class ClientGroupChatRoomPrivate;
friend class ServerGroupChatRoom;
friend class ServerGroupChatRoomPrivate;
friend class SimpleAddress;
public:
explicit Address (const std::string &address = "");
Address (const Address &src);
Address (const SimpleAddress &src);
~Address ();
Address &operator= (const Address &src);

View file

@ -0,0 +1,41 @@
/*
* simple-address-p.h
* Copyright (C) 2010-2017 Belledonne Communications SARL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _SIMPLE_ADDRESS_P_H_
#define _SIMPLE_ADDRESS_P_H_
#include "simple-address.h"
#include "object/clonable-object-p.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class SimpleAddressPrivate : public ClonableObjectPrivate {
private:
std::string scheme;
std::string username;
std::string domain;
L_DECLARE_PUBLIC(SimpleAddress);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _SIMPLE_ADDRESS_P_H_

View file

@ -0,0 +1,117 @@
/*
* simple-address.cpp
* Copyright (C) 2010-2017 Belledonne Communications SARL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#include "linphone/utils/utils.h"
#include "simple-address-p.h"
#include "c-wrapper/c-wrapper.h"
#include "logger/logger.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
// -----------------------------------------------------------------------------
SimpleAddress::SimpleAddress (const string &address) : ClonableObject(*new SimpleAddressPrivate) {
L_D();
Address tmpAddress(address);
if (tmpAddress.isValid()) {
d->scheme = tmpAddress.getScheme();
d->username = tmpAddress.getUsername();
d->domain = tmpAddress.getDomain();
}
}
SimpleAddress::SimpleAddress (const SimpleAddress &src) : ClonableObject(*new SimpleAddressPrivate) {
L_D();
d->scheme = src.getScheme();
d->username = src.getUsername();
d->domain = src.getDomain();
}
SimpleAddress::SimpleAddress (const Address &src) : ClonableObject(*new SimpleAddressPrivate) {
L_D();
d->scheme = src.getScheme();
d->username = src.getUsername();
d->domain = src.getDomain();
}
SimpleAddress &SimpleAddress::operator= (const SimpleAddress &src) {
L_D();
if (this != &src) {
d->scheme = src.getScheme();
d->username = src.getUsername();
d->domain = src.getDomain();
}
return *this;
}
bool SimpleAddress::operator== (const SimpleAddress &address) const {
return asString() == address.asString();
}
bool SimpleAddress::operator!= (const SimpleAddress &address) const {
return !(*this == address);
}
bool SimpleAddress::operator< (const SimpleAddress &address) const {
return asString() < address.asString();
}
const string &SimpleAddress::getScheme () const {
L_D();
return d->scheme;
}
const string &SimpleAddress::getUsername () const {
L_D();
return d->username;
}
bool SimpleAddress::setUsername (const string &username) {
L_D();
d->username = username;
return true;
}
const string &SimpleAddress::getDomain () const {
L_D();
return d->domain;
}
bool SimpleAddress::setDomain (const string &domain) {
L_D();
d->domain = domain;
return true;
}
string SimpleAddress::asString () const {
Address tmpAddress(*this);
return tmpAddress.asString();
}
string SimpleAddress::asStringUriOnly () const {
Address tmpAddress(*this);
return tmpAddress.asStringUriOnly();
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,65 @@
/*
* simple-address.h
* Copyright (C) 2010-2017 Belledonne Communications SARL
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef _SIMPLE_ADDRESS_H_
#define _SIMPLE_ADDRESS_H_
#include "object/clonable-object.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Address;
class SimpleAddressPrivate;
class LINPHONE_PUBLIC SimpleAddress : public ClonableObject {
public:
explicit SimpleAddress (const std::string &address = "");
SimpleAddress (const SimpleAddress &src);
SimpleAddress (const Address &src);
~SimpleAddress () = default;
SimpleAddress &operator= (const SimpleAddress &src);
bool operator== (const SimpleAddress &address) const;
bool operator!= (const SimpleAddress &address) const;
bool operator< (const SimpleAddress &address) const;
const std::string &getScheme () const;
const std::string &getUsername () const;
bool setUsername (const std::string &username);
const std::string &getDomain () const;
bool setDomain (const std::string &domain);
bool isSip () const;
std::string asString () const;
std::string asStringUriOnly () const;
private:
L_DECLARE_PRIVATE(SimpleAddress);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _SIMPLE_ADDRESS_H_

View file

@ -49,7 +49,7 @@ shared_ptr<CallSession> ClientGroupChatRoomPrivate::createSession () {
shared_ptr<Participant> focus = qConference->getPrivate()->focus;
shared_ptr<CallSession> session = focus->getPrivate()->createSession(*q, &csp, false, q);
const Address &myAddress = q->getMe()->getAddress();
session->configure(LinphoneCallOutgoing, nullptr, nullptr, myAddress, focus->getAddress());
session->configure(LinphoneCallOutgoing, nullptr, nullptr, myAddress, focus->getContactAddress());
session->initiateOutgoing();
Address addr = myAddress;

View file

@ -212,12 +212,9 @@ void Conference::onResetFirstVideoFrameDecoded (const shared_ptr<const CallSessi
shared_ptr<Participant> Conference::findParticipant (const Address &addr) const {
L_D();
Address testedAddr = addr;
testedAddr.setPort(0);
SimpleAddress simpleAddr(addr);
for (const auto &participant : d->participants) {
Address participantAddr = participant->getAddress();
participantAddr.setPort(0);
if (testedAddr.weakEqual(participantAddr))
if (participant->getAddress() == simpleAddr)
return participant;
}
@ -237,11 +234,8 @@ shared_ptr<Participant> Conference::findParticipant (const shared_ptr<const Call
bool Conference::isMe (const Address &addr) const {
L_D();
Address cleanedMe = d->me->getAddress();
cleanedMe.setPort(0);
Address cleanedAddr = addr;
cleanedAddr.setPort(0);
return cleanedAddr == cleanedMe;
SimpleAddress simpleAddr(addr);
return d->me->getAddress() == simpleAddr;
}
LINPHONE_END_NAMESPACE

View file

@ -51,29 +51,25 @@ void LocalConferenceEventHandlerPrivate::notifyFullState (const string &notify,
}
void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string &notify, const Address &addr) {
Address cleanedAddr(addr);
cleanedAddr.setPort(0);
SimpleAddress simpleAddr(addr);
for (const auto &participant : conf->getParticipants()) {
Address cleanedParticipantAddr(participant->getAddress());
cleanedParticipantAddr.setPort(0);
if (participant->getPrivate()->isSubscribedToConferenceEventPackage() && !cleanedAddr.weakEqual(cleanedParticipantAddr))
sendNotify(notify, participant->getAddress());
if (participant->getPrivate()->isSubscribedToConferenceEventPackage() && (participant->getAddress() != simpleAddr))
sendNotify(notify, participant->getContactAddress());
}
}
void LocalConferenceEventHandlerPrivate::notifyAll (const string &notify) {
for (const auto &participant : conf->getParticipants()) {
if (participant->getPrivate()->isSubscribedToConferenceEventPackage())
sendNotify(notify, participant->getAddress());
sendNotify(notify, participant->getContactAddress());
}
}
void LocalConferenceEventHandlerPrivate::notifyParticipant (const string &notify, const Address &addr) {
Address cleanedAddr(addr);
cleanedAddr.setPort(0);
shared_ptr<Participant> participant = conf->findParticipant(cleanedAddr);
SimpleAddress simpleAddr(addr);
shared_ptr<Participant> participant = conf->findParticipant(simpleAddr);
if (participant->getPrivate()->isSubscribedToConferenceEventPackage())
sendNotify(notify, participant->getAddress());
sendNotify(notify, participant->getContactAddress());
}
string LocalConferenceEventHandlerPrivate::createNotify (ConferenceType confInfo, int notifyId, bool isFullState) {

View file

@ -44,15 +44,17 @@ public:
inline bool isSubscribedToConferenceEventPackage () const { return _isSubscribedToConferenceEventPackage; }
inline void subscribeToConferenceEventPackage (bool value) { _isSubscribedToConferenceEventPackage = value; }
inline void removeSession () { session.reset(); }
inline void setAddress (const Address &newAddr) { addr = newAddr; }
inline void setAddress (const SimpleAddress &newAddr) { addr = newAddr; }
inline void setAdmin (bool isAdmin) { this->isAdmin = isAdmin; }
inline void setContactAddress (const Address &contactAddr) { this->contactAddr = contactAddr; }
const std::list<ParticipantDevice>::const_iterator findDevice (const Address &gruu) const;
const std::list<ParticipantDevice> &getDevices () const;
void addDevice (const Address &gruu);
void removeDevice (const Address &gruu);
private:
Address addr;
SimpleAddress addr;
Address contactAddr;
bool isAdmin = false;
bool _isSubscribedToConferenceEventPackage = false;
std::shared_ptr<CallSession> session;

View file

@ -70,21 +70,28 @@ void ParticipantPrivate::removeDevice (const Address &gruu) {
Participant::Participant (const Address &address) : Object(*new ParticipantPrivate) {
L_D();
d->addr = address;
d->contactAddr = address;
d->addr = SimpleAddress(address);
}
Participant::Participant (Address &&address) : Object(*new ParticipantPrivate) {
L_D();
d->addr = move(address);
d->contactAddr = move(address);
d->addr = SimpleAddress(address);
}
// -----------------------------------------------------------------------------
const Address& Participant::getAddress () const {
const SimpleAddress& Participant::getAddress () const {
L_D();
return d->addr;
}
const Address& Participant::getContactAddress () const {
L_D();
return d->contactAddr;
}
// -----------------------------------------------------------------------------
bool Participant::isAdmin () const {

View file

@ -23,6 +23,7 @@
#include <list>
#include "address/address.h"
#include "address/simple-address.h"
#include "object/object.h"
#include "conference/params/call-session-params.h"
#include "conference/participant-device.h"
@ -52,7 +53,8 @@ public:
explicit Participant (const Address &address);
explicit Participant (Address &&address);
const Address& getAddress () const;
const SimpleAddress& getAddress () const;
const Address& getContactAddress () const;
bool isAdmin () const;
private:

View file

@ -19,6 +19,7 @@
#include <algorithm>
#include "address/simple-address.h"
#include "chat/chat-room/basic-chat-room.h"
#include "chat/chat-room/chat-room-p.h"
#include "chat/chat-room/real-time-text-chat-room.h"
@ -38,28 +39,18 @@ LINPHONE_BEGIN_NAMESPACE
// Helpers.
// -----------------------------------------------------------------------------
static inline Address getCleanedPeerAddress (const Address &peerAddress) {
if (!peerAddress.isValid())
return Address();
Address cleanedAddress = peerAddress;
cleanedAddress.clean();
cleanedAddress.setPort(0);
return cleanedAddress;
}
// TODO: Remove me later.
static inline string resolveWorkaroundClientGroupChatRoomAddress (
const CorePrivate &corePrivate,
const Address &peerAddress
const SimpleAddress &peerAddr
) {
const char *uri = linphone_core_get_conference_factory_uri(corePrivate.cCore);
if (!uri)
return "";
Address workaroundAddress = peerAddress;
workaroundAddress.setDomain(Address(uri).getDomain());
return workaroundAddress.asStringUriOnly();
SimpleAddress workaroundAddr(peerAddr);
workaroundAddr.setDomain(Address(uri).getDomain());
return workaroundAddr.asString();
}
// -----------------------------------------------------------------------------
@ -85,48 +76,48 @@ shared_ptr<ChatRoom> CorePrivate::createBasicChatRoom (const Address &peerAddres
void CorePrivate::insertChatRoom (const shared_ptr<ChatRoom> &chatRoom) {
L_ASSERT(chatRoom);
Address cleanedPeerAddress = getCleanedPeerAddress(chatRoom->getPeerAddress());
const SimpleAddress simpleAddr(chatRoom->getPeerAddress());
const string peerAddress = chatRoom->getCapabilities() & static_cast<int>(ChatRoom::Capabilities::Conference)
? resolveWorkaroundClientGroupChatRoomAddress(*this, cleanedPeerAddress)
: cleanedPeerAddress.asStringUriOnly();
? resolveWorkaroundClientGroupChatRoomAddress(*this, simpleAddr)
: simpleAddr.asString();
deleteChatRoom(peerAddress);
chatRooms.push_back(chatRoom);
chatRoomsByUri[peerAddress] = chatRoom;
}
void CorePrivate::deleteChatRoom (const string &peerAddress) {
auto it = chatRoomsByUri.find(peerAddress);
void CorePrivate::deleteChatRoom (const string &peerAddr) {
const SimpleAddress simpleAddr(peerAddr);
auto it = chatRoomsByUri.find(simpleAddr.asString());
if (it != chatRoomsByUri.end()) {
auto it = find_if(chatRooms.begin(), chatRooms.end(), [&peerAddress](const shared_ptr<const ChatRoom> &chatRoom) {
return peerAddress == chatRoom->getPeerAddress().asStringUriOnly();
auto it = find_if(chatRooms.begin(), chatRooms.end(), [&peerAddr, &simpleAddr](const shared_ptr<const ChatRoom> &chatRoom) {
return peerAddr == simpleAddr.asString();
});
if (it != chatRooms.end()) {
chatRooms.erase(it);
return;
}
lError() << "Unable to remove chat room: " << peerAddress;
lError() << "Unable to remove chat room: " << peerAddr;
}
}
void CorePrivate::insertChatRoomWithDb (const shared_ptr<ChatRoom> &chatRoom) {
L_ASSERT(chatRoom->getState() == ChatRoom::State::Created);
const SimpleAddress simpleAddr(chatRoom->getPeerAddress());
ChatRoom::CapabilitiesMask capabilities = chatRoom->getCapabilities();
mainDb->insertChatRoom(
capabilities & static_cast<int>(ChatRoom::Capabilities::Conference)
? resolveWorkaroundClientGroupChatRoomAddress(*this, chatRoom->getPeerAddress())
: chatRoom->getPeerAddress().asStringUriOnly(),
? resolveWorkaroundClientGroupChatRoomAddress(*this, simpleAddr)
: simpleAddr.asString(),
capabilities
);
}
void CorePrivate::deleteChatRoomWithDb (const string &peerAddress) {
deleteChatRoom(peerAddress);
mainDb->deleteChatRoom(peerAddress);
void CorePrivate::deleteChatRoomWithDb (const string &peerAddr) {
const SimpleAddress simpleAddr(peerAddr);
deleteChatRoom(simpleAddr.asString());
mainDb->deleteChatRoom(simpleAddr.asString());
}
// -----------------------------------------------------------------------------
@ -136,21 +127,24 @@ const list<shared_ptr<ChatRoom>> &Core::getChatRooms () const {
return d->chatRooms;
}
shared_ptr<ChatRoom> Core::findChatRoom (const Address &peerAddress) const {
shared_ptr<ChatRoom> Core::findChatRoom (const Address &peerAddr) const {
L_D();
Address cleanedAddress = getCleanedPeerAddress(peerAddress);
auto it = d->chatRoomsByUri.find(cleanedAddress.asStringUriOnly());
const SimpleAddress simpleAddr(peerAddr);
auto it = d->chatRoomsByUri.find(simpleAddr.asString());
if (it != d->chatRoomsByUri.cend())
return it->second;
lInfo() << "Unable to find chat room: `" << peerAddress.asStringUriOnly() << "`.";
lInfo() << "Unable to find chat room: `" << simpleAddr.asString() << "`";
// TODO: Remove me, temp workaround.
const string workaroundAddress = resolveWorkaroundClientGroupChatRoomAddress(*d, cleanedAddress);
lWarning() << "Workaround: searching chat room with: `" << workaroundAddress << "`.";
it = d->chatRoomsByUri.find(workaroundAddress);
return it == d->chatRoomsByUri.cend() ? shared_ptr<ChatRoom>() : it->second;
const string workaroundAddress = resolveWorkaroundClientGroupChatRoomAddress(*d, simpleAddr);
if (!workaroundAddress.empty()) {
lWarning() << "Workaround: searching chat room with: `" << workaroundAddress << "`";
it = d->chatRoomsByUri.find(workaroundAddress);
return it == d->chatRoomsByUri.cend() ? shared_ptr<ChatRoom>() : it->second;
}
return shared_ptr<ChatRoom>();
}
shared_ptr<ChatRoom> Core::createClientGroupChatRoom (const string &subject) {
@ -199,11 +193,11 @@ shared_ptr<ChatRoom> Core::getOrCreateBasicChatRoom (const string &peerAddress,
void Core::deleteChatRoom (const shared_ptr<const ChatRoom> &chatRoom) {
CorePrivate *d = chatRoom->getCore()->getPrivate();
const Address cleanedPeerAddress = getCleanedPeerAddress(chatRoom->getPeerAddress());
const SimpleAddress simpleAddr(chatRoom->getPeerAddress());
d->deleteChatRoomWithDb(
chatRoom->getCapabilities() & static_cast<int>(ChatRoom::Capabilities::Conference)
? resolveWorkaroundClientGroupChatRoomAddress(*d, cleanedPeerAddress)
: cleanedPeerAddress.asStringUriOnly()
? resolveWorkaroundClientGroupChatRoomAddress(*d, simpleAddr)
: simpleAddr.asString()
);
}