Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Retrieve Participant List, Send Message to Channel and Real JID lookup of participants proxy JID #89

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Sync registry with requested roster
This allows different client of same user to connect to server and retrieves already connected channels.

License:
This patch is BSD-licensed, see Documentation/Licenses/BSD-simplified.txt for details.

Test-Information:
Tests added for joining and leaving MIX channels as in XEP-0369, which passes.
Tested on Ubuntu 16.04 LTS.

Change-Id: I31d0b68528ea0653685e6bcbc66e8131cb2c0eb4
  • Loading branch information
tarun018 committed Aug 21, 2017
commit 24a3bd08912e2c81f012e46377caf7456b9a9255
201 changes: 128 additions & 73 deletions Limber/MIXMockServer.cpp

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions Swiften/Client/Client.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ Client::Client(const JID& jid, const SafeString& password, NetworkFactories* net
directedPresenceSender = new DirectedPresenceSender(stanzaChannelPresenceSender);
discoManager = new ClientDiscoManager(getIQRouter(), directedPresenceSender, networkFactories->getCryptoProvider());

mixRegistry = new MIXRegistry(getJID(), getIQRouter(), getRoster());
mixRegistry = std::make_unique<MIXRegistry>(getJID(), getIQRouter(), getRoster());

mucRegistry = new MUCRegistry();
mucManager = new MUCManager(getStanzaChannel(), getIQRouter(), directedPresenceSender, mucRegistry);
Expand Down Expand Up @@ -121,7 +121,7 @@ Client::~Client() {
delete avatarManager;
delete vcardManager;

delete mixRegistry;
mixRegistry.reset();

delete mucManager;
delete mucRegistry;
Expand Down
4 changes: 2 additions & 2 deletions Swiften/Client/Client.h
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ namespace Swift {
PresenceSender* getPresenceSender() const;

MIXRegistry* getMIXRegistry() const {
return mixRegistry;
return mixRegistry.get();
}

MUCManager* getMUCManager() const {
Expand Down Expand Up @@ -196,7 +196,7 @@ namespace Swift {
PresenceOracle* presenceOracle;
DirectedPresenceSender* directedPresenceSender;
StanzaChannelPresenceSender* stanzaChannelPresenceSender;
MIXRegistry* mixRegistry;
std::unique_ptr<MIXRegistry> mixRegistry;
MUCRegistry* mucRegistry;
VCardManager* vcardManager;
AvatarManager* avatarManager;
Expand Down
4 changes: 2 additions & 2 deletions Swiften/Elements/RosterPayload.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ namespace Swift {
version_ = version;
}

bool hasMIXAnnotationSupport() const {
bool hasRequestMIXAnnotations() const {
return hasAnnotate_;
}

void setSupportsMIXAnnotations(bool hasAnnotate) {
void setRequestMIXAnnotations(bool hasAnnotate) {
hasAnnotate_ = hasAnnotate;
}

Expand Down
56 changes: 37 additions & 19 deletions Swiften/Examples/MIXListAndJoin/MIXListAndJoin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static void handleChannelJoined(const JID& jid) {
assert(mixRegistry_);
assert(mixRegistry_->getMIXInstance(jid));

cout << "Successfully joined channel " << jid << std::endl;
std::cout << "Successfully joined channel " << jid << std::endl;

//trying to rejoin the same channel joined. Should not send the iq request. Will print a warning.
mixRegistry_->joinChannel(mixChannelJID, supportedNodes);
Expand All @@ -57,83 +57,101 @@ static void handleChannelJoined(const JID& jid) {
// Can perform other functions with MIXImpl object: mix.

// Finally leave channel.
mixRegistry_->leaveChannel(mixChannelJID);
// This is commented to check the sync between different users using different clients(resources) to connect.
//mixRegistry_->leaveChannel(mixChannelJID);
}

static void handleChannelJoinFailed(ErrorPayload::ref /*error*/) {
cout << "Channel Join Failed." << std::endl;
std::cout << "Channel Join Failed." << std::endl;
}

static void handleChannelLeft(const JID& jid) {
assert(mixRegistry_);
assert(!mixRegistry_->getMIXInstance(jid));

cout << "Successfully left channel " << jid << std::endl;
std::cout << "Successfully left channel " << jid << std::endl;
}

static void handleRosterPopulated() {
XMPPRoster* xmppRoster = client->getRoster();
int channelCount = 0;
std::cout << "Already Joined channels: " << std::endl;
for (auto item : xmppRoster->getItems()) {
channelCount++;
std::cout << "\t" << channelCount << ". " << item.getName() << " - " << item.getJID() << std::endl;
}
if (channelCount == 0) {
std::cout << "No channels already joined." << std::endl;
}
std::cout << std::endl;
// Still issuing this join to check for warning.
mixRegistry_->joinChannel(mixChannelJID, supportedNodes);
}

static void handleChannelNodesSupported(std::shared_ptr<DiscoItems> items, ErrorPayload::ref error) {
if (error) {
cout << "Error fetching list of nodes for " << mixChannelJID << endl;
std::cout << "Error fetching list of nodes for " << mixChannelJID << std::endl;
return;
}

// Successfully received supported nodes.
int nodeCount = 0;
cout << "Nodes supported by channel " << mixChannelJID << endl;
std::cout << "Nodes supported by channel " << mixChannelJID << std::endl;
for (auto&& item : items->getItems()) {
nodeCount++;
cout << "\t" << nodeCount << ". " << item.getName() << std::endl;
std::cout << "\t" << nodeCount << ". " << item.getName() << std::endl;
supportedNodes.insert(item.getName());
}
cout << endl;
std::cout << std::endl;

// Initialize MIX Registry and send join request.
client->requestRoster(true);
mixRegistry_ = client->getMIXRegistry();
mixRegistry_->onChannelJoined.connect(&handleChannelJoined);
mixRegistry_->onChannelJoinFailed.connect(&handleChannelJoinFailed);
mixRegistry_->onChannelLeft.connect(&handleChannelLeft);

mixRegistry_->joinChannel(mixChannelJID, supportedNodes);
XMPPRoster* xmppRoster = client->getRoster();
xmppRoster->onInitialRosterPopulated.connect(&handleRosterPopulated);
client->requestRoster(true);
}

static void handleChannelItemsResponse(std::shared_ptr<DiscoItems> items, ErrorPayload::ref error) {
if (error) {
cout << "Error fetching list of channels." << endl;
std::cout << "Error fetching list of channels." << std::endl;
return;
}

//Successfully received the list of available channels.
int channelCount = 0;
cout << "List of rooms at " << mixServiceDomain << endl;
std::cout << "List of rooms at " << mixServiceDomain << std::endl;
for (auto&& item : items->getItems()) {
channelCount++;
cout << "\t" << channelCount << ". " << item.getJID().getNode() << " - " << item.getJID() << std::endl;
std::cout << "\t" << channelCount << ". " << item.getJID().getNode() << " - " << item.getJID() << std::endl;
if (channelCount == 1) {
mixChannelJID = item.getJID();
}
}
cout << endl;
std::cout << std::endl;

// Get the list of MIX nodes supported by MIX channel to be joined.
if (mixChannelJID.isValid()) {
auto discoItemsRequest = GetDiscoItemsRequest::create(mixChannelJID, std::string("mix"), client->getIQRouter());
discoItemsRequest->onResponse.connect(&handleChannelNodesSupported);

cout << "Request supported nodes for MIX channel: " << mixChannelJID << endl;
std::cout << "Request supported nodes for MIX channel: " << mixChannelJID << std::endl;
discoItemsRequest->send();
}
}

static void handleConnected() {
//Successfully connected.
cout << "Connected" << std::endl;
std::cout << "Connected" << std::endl;

auto discoItemsRequest = GetDiscoItemsRequest::create(mixServiceDomain, client->getIQRouter());
discoItemsRequest->onResponse.connect(&handleChannelItemsResponse);

//See the list of available channels.
cout << "Request list of channels." << endl;
std::cout << "Request list of channels." << std::endl;
discoItemsRequest->send();
}

Expand All @@ -149,7 +167,7 @@ int main(int argc, char* argv[]) {
Log::setLogLevel(Log::Severity::warning);

if (argc != 4) {
cout << "Usage: ./" << argv[0] << " <jid> <password> <mix_service_domain>" << endl;
std::cout << "Usage: ./" << argv[0] << " <jid> <password> <mix_service_domain>" << std::endl;
ret = -1;
}
else {
Expand All @@ -164,7 +182,7 @@ int main(int argc, char* argv[]) {
client->onConnected.connect(&handleConnected);
client->onDisconnected.connect(&handleDisconnected);

cout << "Connecting..." << flush;
std::cout << "Connecting..." << std::flush;
client->connect(options);
{
Timer::ref timer = networkFactories.getTimerFactory()->createTimer(30000);
Expand Down
23 changes: 20 additions & 3 deletions Swiften/MIX/MIXRegistry.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,37 @@
namespace Swift {

MIXRegistry::MIXRegistry(const JID& ownJID, IQRouter* iqRouter, XMPPRoster* xmppRoster) : ownJID_(ownJID), iqRouter_(iqRouter), xmppRoster_(xmppRoster) {
xmppRoster_->onJIDAdded.connect(boost::bind(&MIXRegistry::handleJIDAdded, this, _1));
xmppRoster_->onJIDRemoved.connect(boost::bind(&MIXRegistry::handleJIDRemoved, this, _1));
xmppRoster_->onInitialRosterPopulated.connect(boost::bind(&MIXRegistry::syncRegistryWithRoster, this));
}

MIXRegistry::~MIXRegistry() {

}

void MIXRegistry::syncRegistryWithRoster() {
SWIFT_LOG(debug) << "Syncing with roster items. " << std::endl;
for (auto item : xmppRoster_->getItems()) {
if (item.isMIXChannel()) {
SWIFT_LOG(debug) << item.getJID() << std::endl;
auto i = entries_.find(item.getJID());
if (i == entries_.end()) {
SWIFT_LOG(debug) << "Adding " << item.getJID() << std::endl;
entries_.insert(std::make_pair(item.getJID(), std::make_shared<MIXImpl>(ownJID_, item.getJID(), iqRouter_)));
}
}
}
xmppRoster_->onJIDAdded.connect(boost::bind(&MIXRegistry::handleJIDAdded, this, _1));
xmppRoster_->onJIDRemoved.connect(boost::bind(&MIXRegistry::handleJIDRemoved, this, _1));
}

void MIXRegistry::joinChannel(const JID& channelJID, const std::unordered_set<std::string>& nodes) {
SWIFT_LOG(debug) << "Joining Channel " << channelJID << std::endl;
auto i = entries_.find(channelJID);
if (i != entries_.end()) {
SWIFT_LOG(warning) << "Channel already joined: " << channelJID << std::endl;
return;
}
SWIFT_LOG(debug) << "Sending request for joining channel " << channelJID << std::endl;
auto joinPayload = std::make_shared<MIXJoin>();
joinPayload->setChannel(channelJID);
for (auto node : nodes) {
Expand Down Expand Up @@ -65,7 +82,7 @@ void MIXRegistry::handleJIDRemoved(const JID& jid) {
}
}

std::unordered_set<MIXImpl::ref> MIXRegistry::getChannels() {
const std::unordered_set<MIXImpl::ref> MIXRegistry::getChannels() {
std::unordered_set<MIXImpl::ref> results;
for (const auto& entry : entries_) {
results.insert(entry.second);
Expand Down
7 changes: 6 additions & 1 deletion Swiften/MIX/MIXRegistry.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ namespace Swift {

~MIXRegistry();

/**
* Sync based on initially populated roster.
*/
void syncRegistryWithRoster();

/**
* Join a MIX Channel with subscriptions.
*/
Expand All @@ -47,7 +52,7 @@ namespace Swift {
/**
* Get MIX objects for all joinedChannels.
*/
std::unordered_set<MIXImpl::ref> getChannels();
const std::unordered_set<MIXImpl::ref> getChannels();

/**
* Get MIX instance for a joined channel.
Expand Down
2 changes: 2 additions & 0 deletions Swiften/MIX/UnitTest/MIXRegistryTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ class MIXRegistryTest : public ::testing::Test {

TEST_F(MIXRegistryTest, testJoinAndLeaveChannel) {
auto testling = getMIXRegistry();
testling->syncRegistryWithRoster();

std::unordered_set<std::string> nodes;
nodes.insert(std::string("urn:xmpp:mix:nodes:messages"));
Expand Down Expand Up @@ -122,6 +123,7 @@ TEST_F(MIXRegistryTest, testJoinAndLeaveChannel) {

TEST_F(MIXRegistryTest, testFailedJoin) {
auto testling = getMIXRegistry();
testling->syncRegistryWithRoster();

std::unordered_set<std::string> nodes;
nodes.insert(std::string("urn:xmpp:mix:nodes:messages"));
Expand Down
2 changes: 1 addition & 1 deletion Swiften/Parser/PayloadParsers/RosterParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ void RosterParser::handleStartElement(const std::string& element, const std::str
currentItem_.setSubscriptionRequested();
}
} else if (element == "annotate" && ns == "urn:xmpp:mix:roster:0") {
getPayloadInternal()->setSupportsMIXAnnotations(true);
getPayloadInternal()->setRequestMIXAnnotations(true);
}
}
else if (level_ == ItemLevel) {
Expand Down
12 changes: 6 additions & 6 deletions Swiften/Roster/XMPPRosterImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ XMPPRosterImpl::~XMPPRosterImpl() {

void XMPPRosterImpl::addContact(const JID& jid, const std::string& name, const std::vector<std::string>& groups, RosterItemPayload::Subscription subscription, bool isMIXChannel) {
JID bareJID(jid.toBare());
std::map<JID, XMPPRosterItem>::iterator i = entries_.find(bareJID);
auto i = entries_.find(bareJID);
if (i != entries_.end()) {
std::string oldName = i->second.getName();
std::vector<std::string> oldGroups = i->second.getGroups();
Expand All @@ -41,7 +41,7 @@ void XMPPRosterImpl::clear() {
}

bool XMPPRosterImpl::isMIXChannel(const JID& jid) {
std::map<JID, XMPPRosterItem>::const_iterator i = entries_.find(jid.toBare());
auto i = entries_.find(jid.toBare());
if (i != entries_.end()) {
return i->second.isMIXChannel();
} else {
Expand All @@ -54,7 +54,7 @@ bool XMPPRosterImpl::containsJID(const JID& jid) {
}

std::string XMPPRosterImpl::getNameForJID(const JID& jid) const {
std::map<JID, XMPPRosterItem>::const_iterator i = entries_.find(jid.toBare());
auto i = entries_.find(jid.toBare());
if (i != entries_.end()) {
return i->second.getName();
}
Expand All @@ -64,7 +64,7 @@ std::string XMPPRosterImpl::getNameForJID(const JID& jid) const {
}

std::vector<std::string> XMPPRosterImpl::getGroupsForJID(const JID& jid) {
std::map<JID, XMPPRosterItem>::iterator i = entries_.find(jid.toBare());
auto i = entries_.find(jid.toBare());
if (i != entries_.end()) {
return i->second.getGroups();
}
Expand All @@ -74,7 +74,7 @@ std::vector<std::string> XMPPRosterImpl::getGroupsForJID(const JID& jid) {
}

RosterItemPayload::Subscription XMPPRosterImpl::getSubscriptionStateForJID(const JID& jid) {
std::map<JID, XMPPRosterItem>::iterator i = entries_.find(jid.toBare());
auto i = entries_.find(jid.toBare());
if (i != entries_.end()) {
return i->second.getSubscription();
}
Expand All @@ -92,7 +92,7 @@ std::vector<XMPPRosterItem> XMPPRosterImpl::getItems() const {
}

boost::optional<XMPPRosterItem> XMPPRosterImpl::getItem(const JID& jid) const {
std::map<JID, XMPPRosterItem>::const_iterator i = entries_.find(jid.toBare());
auto i = entries_.find(jid.toBare());
if (i != entries_.end()) {
return i->second;
}
Expand Down
2 changes: 1 addition & 1 deletion Swiften/Serializer/PayloadSerializers/RosterSerializer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ std::string RosterSerializer::serializePayload(std::shared_ptr<RosterPayload> ro
queryElement.addNode(itemElement);
}

if (roster->hasMIXAnnotationSupport()) {
if (roster->hasRequestMIXAnnotations()) {
auto annotateElement = std::make_shared<XMLElement>("annotate", "urn:xmpp:mix:roster:0");
queryElement.addNode(annotateElement);
}
Expand Down