From 120117f7b3cac1ba1a53bf5cc63cfbaddac6b8c5 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 7 Nov 2017 15:27:09 +0100 Subject: [PATCH] Add the SimpleAddress class to ease the comparison of addresses for the conference participants and the list of chat rooms. --- src/CMakeLists.txt | 3 + src/address/address.cpp | 16 ++- src/address/address.h | 3 + src/address/simple-address-p.h | 41 ++++++ src/address/simple-address.cpp | 117 ++++++++++++++++++ src/address/simple-address.h | 65 ++++++++++ src/chat/chat-room/client-group-chat-room.cpp | 2 +- src/conference/conference.cpp | 14 +-- .../local-conference-event-handler.cpp | 18 ++- src/conference/participant-p.h | 6 +- src/conference/participant.cpp | 13 +- src/conference/participant.h | 4 +- src/core/core-chat-room.cpp | 76 ++++++------ 13 files changed, 307 insertions(+), 71 deletions(-) create mode 100644 src/address/simple-address-p.h create mode 100644 src/address/simple-address.cpp create mode 100644 src/address/simple-address.h diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 53ae3b8ff..e668511fb 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -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 diff --git a/src/address/address.cpp b/src/address/address.cpp index 257fe7e1b..551975285 100644 --- a/src/address/address.cpp +++ b/src/address/address.cpp @@ -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) diff --git a/src/address/address.h b/src/address/address.h index af3dc0f1f..540bf7be4 100644 --- a/src/address/address.h +++ b/src/address/address.h @@ -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); diff --git a/src/address/simple-address-p.h b/src/address/simple-address-p.h new file mode 100644 index 000000000..49ac82f7f --- /dev/null +++ b/src/address/simple-address-p.h @@ -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_ diff --git a/src/address/simple-address.cpp b/src/address/simple-address.cpp new file mode 100644 index 000000000..19a1da395 --- /dev/null +++ b/src/address/simple-address.cpp @@ -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 diff --git a/src/address/simple-address.h b/src/address/simple-address.h new file mode 100644 index 000000000..4a76a83ee --- /dev/null +++ b/src/address/simple-address.h @@ -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_ diff --git a/src/chat/chat-room/client-group-chat-room.cpp b/src/chat/chat-room/client-group-chat-room.cpp index a850e6c57..b5430c0e5 100644 --- a/src/chat/chat-room/client-group-chat-room.cpp +++ b/src/chat/chat-room/client-group-chat-room.cpp @@ -49,7 +49,7 @@ shared_ptr ClientGroupChatRoomPrivate::createSession () { shared_ptr focus = qConference->getPrivate()->focus; shared_ptr 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; diff --git a/src/conference/conference.cpp b/src/conference/conference.cpp index c0ac545ab..1ad341793 100644 --- a/src/conference/conference.cpp +++ b/src/conference/conference.cpp @@ -212,12 +212,9 @@ void Conference::onResetFirstVideoFrameDecoded (const shared_ptr 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 Conference::findParticipant (const shared_ptrme->getAddress(); - cleanedMe.setPort(0); - Address cleanedAddr = addr; - cleanedAddr.setPort(0); - return cleanedAddr == cleanedMe; + SimpleAddress simpleAddr(addr); + return d->me->getAddress() == simpleAddr; } LINPHONE_END_NAMESPACE diff --git a/src/conference/local-conference-event-handler.cpp b/src/conference/local-conference-event-handler.cpp index b731aba69..518dd4abe 100644 --- a/src/conference/local-conference-event-handler.cpp +++ b/src/conference/local-conference-event-handler.cpp @@ -51,29 +51,25 @@ void LocalConferenceEventHandlerPrivate::notifyFullState (const string ¬ify, } void LocalConferenceEventHandlerPrivate::notifyAllExcept (const string ¬ify, 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 ¬ify) { for (const auto &participant : conf->getParticipants()) { if (participant->getPrivate()->isSubscribedToConferenceEventPackage()) - sendNotify(notify, participant->getAddress()); + sendNotify(notify, participant->getContactAddress()); } } void LocalConferenceEventHandlerPrivate::notifyParticipant (const string ¬ify, const Address &addr) { - Address cleanedAddr(addr); - cleanedAddr.setPort(0); - shared_ptr participant = conf->findParticipant(cleanedAddr); + SimpleAddress simpleAddr(addr); + shared_ptr 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) { diff --git a/src/conference/participant-p.h b/src/conference/participant-p.h index 258c65d7b..58993cd97 100644 --- a/src/conference/participant-p.h +++ b/src/conference/participant-p.h @@ -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::const_iterator findDevice (const Address &gruu) const; const std::list &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 session; diff --git a/src/conference/participant.cpp b/src/conference/participant.cpp index ecafa17fd..cf2e370b4 100644 --- a/src/conference/participant.cpp +++ b/src/conference/participant.cpp @@ -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 { diff --git a/src/conference/participant.h b/src/conference/participant.h index aefe33fab..41c0fab02 100644 --- a/src/conference/participant.h +++ b/src/conference/participant.h @@ -23,6 +23,7 @@ #include #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: diff --git a/src/core/core-chat-room.cpp b/src/core/core-chat-room.cpp index 91a25a0f2..369d9ea17 100644 --- a/src/core/core-chat-room.cpp +++ b/src/core/core-chat-room.cpp @@ -19,6 +19,7 @@ #include +#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 CorePrivate::createBasicChatRoom (const Address &peerAddres void CorePrivate::insertChatRoom (const shared_ptr &chatRoom) { L_ASSERT(chatRoom); - Address cleanedPeerAddress = getCleanedPeerAddress(chatRoom->getPeerAddress()); - + const SimpleAddress simpleAddr(chatRoom->getPeerAddress()); const string peerAddress = chatRoom->getCapabilities() & static_cast(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 &chatRoom) { - return peerAddress == chatRoom->getPeerAddress().asStringUriOnly(); + auto it = find_if(chatRooms.begin(), chatRooms.end(), [&peerAddr, &simpleAddr](const shared_ptr &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) { L_ASSERT(chatRoom->getState() == ChatRoom::State::Created); + const SimpleAddress simpleAddr(chatRoom->getPeerAddress()); ChatRoom::CapabilitiesMask capabilities = chatRoom->getCapabilities(); mainDb->insertChatRoom( capabilities & static_cast(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> &Core::getChatRooms () const { return d->chatRooms; } -shared_ptr Core::findChatRoom (const Address &peerAddress) const { +shared_ptr 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() : 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() : it->second; + } + return shared_ptr(); } shared_ptr Core::createClientGroupChatRoom (const string &subject) { @@ -199,11 +193,11 @@ shared_ptr Core::getOrCreateBasicChatRoom (const string &peerAddress, void Core::deleteChatRoom (const shared_ptr &chatRoom) { CorePrivate *d = chatRoom->getCore()->getPrivate(); - const Address cleanedPeerAddress = getCleanedPeerAddress(chatRoom->getPeerAddress()); + const SimpleAddress simpleAddr(chatRoom->getPeerAddress()); d->deleteChatRoomWithDb( chatRoom->getCapabilities() & static_cast(ChatRoom::Capabilities::Conference) - ? resolveWorkaroundClientGroupChatRoomAddress(*d, cleanedPeerAddress) - : cleanedPeerAddress.asStringUriOnly() + ? resolveWorkaroundClientGroupChatRoomAddress(*d, simpleAddr) + : simpleAddr.asString() ); }