Fixed PresenceOracle
This commit is contained in:
parent
93418187e2
commit
f035510e47
8 changed files with 204 additions and 11 deletions
|
@ -18,13 +18,12 @@
|
|||
#include <Swiften/FileTransfer/SOCKS5BytestreamServer.h>
|
||||
#include <Swiften/Base/IDGenerator.h>
|
||||
#include <Swiften/Elements/Presence.h>
|
||||
#include <Swiften/Presence/PresenceOracle.h>
|
||||
#include <Swiften/Base/foreach.h>
|
||||
|
||||
|
||||
namespace Swift {
|
||||
|
||||
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
|
||||
CombinedOutgoingFileTransferManager::CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle *presOracle, SOCKS5BytestreamServer *bytestreamServer) : jsManager(jingleSessionManager), iqRouter(router), capsProvider(capsProvider), remoteFactory(remoteFactory), localFactory(localFactory), bytestreamRegistry(bytestreamRegistry), bytestreamProxy(bytestreamProxy), presenceOracle(presOracle), bytestreamServer(bytestreamServer) {
|
||||
idGenerator = new IDGenerator();
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,8 @@
|
|||
|
||||
#include <Swiften/JID/JID.h>
|
||||
|
||||
#include "transport/presenceoracle.h"
|
||||
|
||||
namespace Swift {
|
||||
|
||||
class JingleSessionManager;
|
||||
|
@ -30,7 +32,7 @@ class PresenceOracle;
|
|||
|
||||
class CombinedOutgoingFileTransferManager {
|
||||
public:
|
||||
CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
|
||||
CombinedOutgoingFileTransferManager(JingleSessionManager* jingleSessionManager, IQRouter* router, EntityCapsProvider* capsProvider, RemoteJingleTransportCandidateSelectorFactory* remoteFactory, LocalJingleTransportCandidateGeneratorFactory* localFactory, SOCKS5BytestreamRegistry* bytestreamRegistry, SOCKS5BytestreamProxy* bytestreamProxy, Transport::PresenceOracle* presOracle, SOCKS5BytestreamServer *server);
|
||||
~CombinedOutgoingFileTransferManager();
|
||||
|
||||
boost::shared_ptr<OutgoingFileTransfer> createOutgoingFileTransfer(const JID& from, const JID& to, boost::shared_ptr<ReadBytestream>, const StreamInitiationFileInfo&);
|
||||
|
@ -46,7 +48,7 @@ private:
|
|||
IDGenerator *idGenerator;
|
||||
SOCKS5BytestreamRegistry* bytestreamRegistry;
|
||||
SOCKS5BytestreamProxy* bytestreamProxy;
|
||||
PresenceOracle* presenceOracle;
|
||||
Transport::PresenceOracle* presenceOracle;
|
||||
SOCKS5BytestreamServer *bytestreamServer;
|
||||
};
|
||||
|
||||
|
|
57
include/transport/presenceoracle.h
Normal file
57
include/transport/presenceoracle.h
Normal file
|
@ -0,0 +1,57 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* 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 02111-1301 USA
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <string>
|
||||
#include <Swiften/Elements/Presence.h>
|
||||
#include <Swiften/Client/StanzaChannel.h>
|
||||
|
||||
#include <Swiften/Base/boost_bsignals.h>
|
||||
|
||||
namespace Transport {
|
||||
|
||||
class PresenceOracle {
|
||||
public:
|
||||
PresenceOracle(Swift::StanzaChannel* stanzaChannel);
|
||||
~PresenceOracle();
|
||||
|
||||
Swift::Presence::ref getLastPresence(const Swift::JID&) const;
|
||||
Swift::Presence::ref getHighestPriorityPresence(const Swift::JID& bareJID) const;
|
||||
std::vector<Swift::Presence::ref> getAllPresence(const Swift::JID& bareJID) const;
|
||||
|
||||
public:
|
||||
boost::signal<void (Swift::Presence::ref)> onPresenceChange;
|
||||
|
||||
private:
|
||||
void handleIncomingPresence(Swift::Presence::ref presence);
|
||||
void handleStanzaChannelAvailableChanged(bool);
|
||||
|
||||
private:
|
||||
typedef std::map<Swift::JID, Swift::Presence::ref> PresenceMap;
|
||||
typedef std::map<Swift::JID, PresenceMap> PresencesMap;
|
||||
PresencesMap entries_;
|
||||
Swift::StanzaChannel* stanzaChannel_;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
@ -27,7 +27,6 @@
|
|||
#include "Swiften/Disco/EntityCapsManager.h"
|
||||
#include "Swiften/Disco/CapsManager.h"
|
||||
#include "Swiften/Disco/CapsMemoryStorage.h"
|
||||
#include "Swiften/Presence/PresenceOracle.h"
|
||||
#include "Swiften/Network/BoostTimerFactory.h"
|
||||
#include "Swiften/Network/BoostIOServiceThread.h"
|
||||
#include "Swiften/Server/UserRegistry.h"
|
||||
|
@ -37,6 +36,7 @@
|
|||
#include <boost/bind.hpp>
|
||||
#include "transport/config.h"
|
||||
#include "transport/factory.h"
|
||||
#include "transport/presenceoracle.h"
|
||||
|
||||
namespace Transport {
|
||||
// typedef enum { CLIENT_FEATURE_ROSTERX = 2,
|
||||
|
@ -92,7 +92,7 @@ namespace Transport {
|
|||
|
||||
/// You can use it to check current resource connected for particular user.
|
||||
/// \return Swift::PresenceOracle associated with this Transport::Component.
|
||||
Swift::PresenceOracle *getPresenceOracle();
|
||||
PresenceOracle *getPresenceOracle();
|
||||
|
||||
/// Returns True if the component is in server mode.
|
||||
|
||||
|
@ -179,7 +179,7 @@ namespace Transport {
|
|||
Swift::EntityCapsManager *m_entityCapsManager;
|
||||
Swift::CapsManager *m_capsManager;
|
||||
Swift::CapsMemoryStorage *m_capsMemoryStorage;
|
||||
Swift::PresenceOracle *m_presenceOracle;
|
||||
PresenceOracle *m_presenceOracle;
|
||||
Swift::StanzaChannel *m_stanzaChannel;
|
||||
Swift::IQRouter *m_iqRouter;
|
||||
|
||||
|
|
|
@ -22,7 +22,6 @@
|
|||
|
||||
#include <time.h>
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/Presence/PresenceOracle.h"
|
||||
#include "Swiften/Disco/EntityCapsManager.h"
|
||||
#include "Swiften/Disco/EntityCapsProvider.h"
|
||||
#include "storagebackend.h"
|
||||
|
@ -35,6 +34,7 @@ class Component;
|
|||
class RosterManager;
|
||||
class ConversationManager;
|
||||
class UserManager;
|
||||
class PresenceOracle;
|
||||
struct UserInfo;
|
||||
|
||||
/// Represents online XMPP user.
|
||||
|
@ -125,7 +125,7 @@ class User : public Swift::EntityCapsProvider {
|
|||
UserManager *m_userManager;
|
||||
ConversationManager *m_conversationManager;
|
||||
Swift::EntityCapsManager *m_entityCapsManager;
|
||||
Swift::PresenceOracle *m_presenceOracle;
|
||||
PresenceOracle *m_presenceOracle;
|
||||
UserInfo m_userInfo;
|
||||
void *m_data;
|
||||
bool m_connected;
|
||||
|
|
134
src/presenceoracle.cpp
Normal file
134
src/presenceoracle.cpp
Normal file
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* XMPP - libpurple transport
|
||||
*
|
||||
* Copyright (C) 2009, Jan Kaluza <hanzz@soc.pidgin.im>
|
||||
*
|
||||
* 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 02111-1301 USA
|
||||
*/
|
||||
|
||||
#include "transport/presenceoracle.h"
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using namespace Swift;
|
||||
|
||||
namespace Transport {
|
||||
|
||||
PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel) {
|
||||
stanzaChannel_ = stanzaChannel;
|
||||
stanzaChannel_->onPresenceReceived.connect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
|
||||
stanzaChannel_->onAvailableChanged.connect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
|
||||
}
|
||||
|
||||
PresenceOracle::~PresenceOracle() {
|
||||
stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
|
||||
stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
|
||||
}
|
||||
|
||||
void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) {
|
||||
if (available) {
|
||||
entries_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
|
||||
// ignore presences for some contact, we're checking only presences for the transport itself here.
|
||||
if (!presence->getTo().getNode().empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
JID bareJID(presence->getFrom().toBare());
|
||||
if (presence->getType() == Presence::Subscribe) {
|
||||
}
|
||||
else {
|
||||
Presence::ref passedPresence = presence;
|
||||
if (presence->getType() == Presence::Unsubscribe) {
|
||||
/* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */
|
||||
passedPresence = Presence::ref(new Presence());
|
||||
passedPresence->setType(Presence::Unavailable);
|
||||
passedPresence->setFrom(bareJID);
|
||||
passedPresence->setStatus(presence->getStatus());
|
||||
}
|
||||
std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID];
|
||||
if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) {
|
||||
/* Have a bare-JID only presence of offline */
|
||||
jidMap.clear();
|
||||
} else if (passedPresence->getType() == Presence::Available) {
|
||||
/* Don't have a bare-JID only offline presence once there are available presences */
|
||||
jidMap.erase(bareJID);
|
||||
}
|
||||
if (passedPresence->getType() == Presence::Unavailable && jidMap.size() > 1) {
|
||||
jidMap.erase(passedPresence->getFrom());
|
||||
} else {
|
||||
jidMap[passedPresence->getFrom()] = passedPresence;
|
||||
}
|
||||
entries_[bareJID] = jidMap;
|
||||
onPresenceChange(passedPresence);
|
||||
}
|
||||
}
|
||||
|
||||
Presence::ref PresenceOracle::getLastPresence(const JID& jid) const {
|
||||
PresencesMap::const_iterator i = entries_.find(jid.toBare());
|
||||
if (i == entries_.end()) {
|
||||
return Presence::ref();
|
||||
}
|
||||
PresenceMap presenceMap = i->second;
|
||||
PresenceMap::const_iterator j = presenceMap.find(jid);
|
||||
if (j != presenceMap.end()) {
|
||||
return j->second;
|
||||
}
|
||||
else {
|
||||
return Presence::ref();
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<Presence::ref> PresenceOracle::getAllPresence(const JID& bareJID) const {
|
||||
std::vector<Presence::ref> results;
|
||||
PresencesMap::const_iterator i = entries_.find(bareJID);
|
||||
if (i == entries_.end()) {
|
||||
return results;
|
||||
}
|
||||
PresenceMap presenceMap = i->second;
|
||||
PresenceMap::const_iterator j = presenceMap.begin();
|
||||
for (; j != presenceMap.end(); ++j) {
|
||||
Presence::ref current = j->second;
|
||||
results.push_back(current);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
|
||||
Presence::ref PresenceOracle::getHighestPriorityPresence(const JID& bareJID) const {
|
||||
PresencesMap::const_iterator i = entries_.find(bareJID);
|
||||
if (i == entries_.end()) {
|
||||
return Presence::ref();
|
||||
}
|
||||
PresenceMap presenceMap = i->second;
|
||||
PresenceMap::const_iterator j = presenceMap.begin();
|
||||
Presence::ref highest;
|
||||
for (; j != presenceMap.end(); ++j) {
|
||||
Presence::ref current = j->second;
|
||||
if (!highest
|
||||
|| current->getPriority() > highest->getPriority()
|
||||
|| (current->getPriority() == highest->getPriority()
|
||||
&& StatusShow::typeToAvailabilityOrdering(current->getShow()) > StatusShow::typeToAvailabilityOrdering(highest->getShow()))) {
|
||||
highest = current;
|
||||
}
|
||||
|
||||
}
|
||||
return highest;
|
||||
}
|
||||
|
||||
}
|
|
@ -137,7 +137,7 @@ Component::Component(Swift::EventLoop *loop, Swift::NetworkFactories *factories,
|
|||
m_entityCapsManager = new EntityCapsManager(m_capsManager, m_stanzaChannel);
|
||||
m_entityCapsManager->onCapsChanged.connect(boost::bind(&Component::handleCapsChanged, this, _1));
|
||||
|
||||
m_presenceOracle = new PresenceOracle(m_stanzaChannel);
|
||||
m_presenceOracle = new Transport::PresenceOracle(m_stanzaChannel);
|
||||
m_presenceOracle->onPresenceChange.connect(bind(&Component::handlePresence, this, _1));
|
||||
|
||||
m_discoInfoResponder = new DiscoInfoResponder(m_iqRouter, m_config);
|
||||
|
@ -170,7 +170,7 @@ Swift::StanzaChannel *Component::getStanzaChannel() {
|
|||
return m_stanzaChannel;
|
||||
}
|
||||
|
||||
Swift::PresenceOracle *Component::getPresenceOracle() {
|
||||
Transport::PresenceOracle *Component::getPresenceOracle() {
|
||||
return m_presenceOracle;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "transport/rostermanager.h"
|
||||
#include "transport/usermanager.h"
|
||||
#include "transport/conversationmanager.h"
|
||||
#include "transport/presenceoracle.h"
|
||||
#include "Swiften/Swiften.h"
|
||||
#include "Swiften/Server/ServerStanzaChannel.h"
|
||||
#include "Swiften/Elements/StreamError.h"
|
||||
|
|
Loading…
Add table
Reference in a new issue