summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/Presence/PresenceOracle.cpp')
-rw-r--r--Swiften/Presence/PresenceOracle.cpp27
1 files changed, 21 insertions, 6 deletions
diff --git a/Swiften/Presence/PresenceOracle.cpp b/Swiften/Presence/PresenceOracle.cpp
index 59dff41..e4129fb 100644
--- a/Swiften/Presence/PresenceOracle.cpp
+++ b/Swiften/Presence/PresenceOracle.cpp
@@ -1,37 +1,38 @@
1/* 1/*
2 * Copyright (c) 2010 Isode Limited. 2 * Copyright (c) 2010-2015 Isode Limited.
3 * All rights reserved. 3 * All rights reserved.
4 * See the COPYING file for more information. 4 * See the COPYING file for more information.
5 */ 5 */
6 6
7#include "PresenceOracle.h" 7#include <Swiften/Presence/PresenceOracle.h>
8 8
9#include <boost/bind.hpp> 9#include <boost/bind.hpp>
10 10
11#include <Swiften/Client/StanzaChannel.h> 11#include <Swiften/Client/StanzaChannel.h>
12#include <Swiften/Roster/XMPPRoster.h>
12 13
13namespace Swift { 14namespace Swift {
14 15
15PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel) { 16PresenceOracle::PresenceOracle(StanzaChannel* stanzaChannel, XMPPRoster* roster) : stanzaChannel_(stanzaChannel), xmppRoster_(roster) {
16 stanzaChannel_ = stanzaChannel;
17 stanzaChannel_->onPresenceReceived.connect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1)); 17 stanzaChannel_->onPresenceReceived.connect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
18 stanzaChannel_->onAvailableChanged.connect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1)); 18 stanzaChannel_->onAvailableChanged.connect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
19 xmppRoster_->onJIDRemoved.connect(boost::bind(&PresenceOracle::handleJIDRemoved, this, _1));
19} 20}
20 21
21PresenceOracle::~PresenceOracle() { 22PresenceOracle::~PresenceOracle() {
22 stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1)); 23 stanzaChannel_->onPresenceReceived.disconnect(boost::bind(&PresenceOracle::handleIncomingPresence, this, _1));
23 stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1)); 24 stanzaChannel_->onAvailableChanged.disconnect(boost::bind(&PresenceOracle::handleStanzaChannelAvailableChanged, this, _1));
25 xmppRoster_->onJIDRemoved.disconnect(boost::bind(&PresenceOracle::handleJIDRemoved, this, _1));
24} 26}
25 27
26void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) { 28void PresenceOracle::handleStanzaChannelAvailableChanged(bool available) {
27 if (available) { 29 if (available) {
28 entries_.clear(); 30 entries_.clear();
29 } 31 }
30} 32}
31 33
32
33void PresenceOracle::handleIncomingPresence(Presence::ref presence) { 34void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
34 JID bareJID(presence->getFrom().toBare()); 35 JID bareJID(presence->getFrom().toBare());
35 if (presence->getType() == Presence::Subscribe) { 36 if (presence->getType() == Presence::Subscribe) {
36 } 37 }
37 else { 38 else {
@@ -41,11 +42,11 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
41 passedPresence = Presence::ref(new Presence()); 42 passedPresence = Presence::ref(new Presence());
42 passedPresence->setType(Presence::Unavailable); 43 passedPresence->setType(Presence::Unavailable);
43 passedPresence->setFrom(bareJID); 44 passedPresence->setFrom(bareJID);
44 passedPresence->setStatus(presence->getStatus()); 45 passedPresence->setStatus(presence->getStatus());
45 } 46 }
46 std::map<JID, boost::shared_ptr<Presence> > jidMap = entries_[bareJID]; 47 PresenceMap jidMap = entries_[bareJID];
47 if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) { 48 if (passedPresence->getFrom().isBare() && presence->getType() == Presence::Unavailable) {
48 /* Have a bare-JID only presence of offline */ 49 /* Have a bare-JID only presence of offline */
49 jidMap.clear(); 50 jidMap.clear();
50 } else if (passedPresence->getType() == Presence::Available) { 51 } else if (passedPresence->getType() == Presence::Available) {
51 /* Don't have a bare-JID only offline presence once there are available presences */ 52 /* Don't have a bare-JID only offline presence once there are available presences */
@@ -59,10 +60,24 @@ void PresenceOracle::handleIncomingPresence(Presence::ref presence) {
59 entries_[bareJID] = jidMap; 60 entries_[bareJID] = jidMap;
60 onPresenceChange(passedPresence); 61 onPresenceChange(passedPresence);
61 } 62 }
62} 63}
63 64
65void PresenceOracle::handleJIDRemoved(const JID& removedJID) {
66 /* 3921bis says that we don't follow up with an unavailable, so simulate this ourselves */
67 Presence::ref unavailablePresence = Presence::ref(new Presence());
68 unavailablePresence->setType(Presence::Unavailable);
69 unavailablePresence->setFrom(removedJID);
70
71 if (entries_.find(removedJID) != entries_.end()) {
72 entries_[removedJID].clear();
73 entries_[removedJID][removedJID] = unavailablePresence;
74 }
75
76 onPresenceChange(unavailablePresence);
77}
78
64Presence::ref PresenceOracle::getLastPresence(const JID& jid) const { 79Presence::ref PresenceOracle::getLastPresence(const JID& jid) const {
65 PresencesMap::const_iterator i = entries_.find(jid.toBare()); 80 PresencesMap::const_iterator i = entries_.find(jid.toBare());
66 if (i == entries_.end()) { 81 if (i == entries_.end()) {
67 return Presence::ref(); 82 return Presence::ref();
68 } 83 }