summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2009-07-18 14:48:20 (GMT)
committerRemko Tronçon <git@el-tramo.be>2009-07-18 14:48:20 (GMT)
commit4052a822acd9da9dab6a8e2343c6170fb08dd8d6 (patch)
tree588914d2cc33ea3ed8362acaca0b885853945a50
parent70e454fd02597c9a71ed89356a572e48256f8349 (diff)
downloadswift-4052a822acd9da9dab6a8e2343c6170fb08dd8d6.zip
swift-4052a822acd9da9dab6a8e2343c6170fb08dd8d6.tar.bz2
Implement outgoing presence bridge.
-rw-r--r--Nim/main.cpp77
-rw-r--r--Swiften/LinkLocal/AppleDNSSDService.cpp56
-rw-r--r--Swiften/LinkLocal/AppleDNSSDService.h1
-rw-r--r--Swiften/LinkLocal/DNSSDService.h1
-rw-r--r--Swiften/LinkLocal/LinkLocalRoster.cpp3
5 files changed, 94 insertions, 44 deletions
diff --git a/Nim/main.cpp b/Nim/main.cpp
index 024ecd1..8166534 100644
--- a/Nim/main.cpp
+++ b/Nim/main.cpp
@@ -1,5 +1,3 @@
-// TODO: Prohibit multiple logins
-
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
@@ -54,6 +52,8 @@ class Server {
serverFromNetworkConnectionServer_->start();
dnsSDService_ = boost::shared_ptr<AppleDNSSDService>(new AppleDNSSDService());
+ dnsSDService_->onServiceRegistered.connect(boost::bind(&Server::handleServiceRegistered, this, _1));
+
linkLocalRoster_ = boost::shared_ptr<LinkLocalRoster>(new LinkLocalRoster(dnsSDService_));
linkLocalRoster_->onRosterChanged.connect(boost::bind(&Server::handleRosterChanged, this, _1));
linkLocalRoster_->onPresenceChanged.connect(boost::bind(&Server::handlePresenceChanged, this, _1));
@@ -67,7 +67,6 @@ class Server {
}
serverFromClientSession_ = boost::shared_ptr<ServerFromClientSession>(new ServerFromClientSession(idGenerator_.generateID(), c, &payloadParserFactories_, &payloadSerializers_, &userRegistry_));
serverFromClientSession_->onStanzaReceived.connect(boost::bind(&Server::handleStanzaReceived, this, _1, serverFromClientSession_));
- serverFromClientSession_->onSessionStarted.connect(boost::bind(&Server::handleSessionStarted, this, serverFromClientSession_));
serverFromClientSession_->onSessionFinished.connect(boost::bind(&Server::handleSessionFinished, this, serverFromClientSession_));
serverFromClientSession_->start();
}
@@ -76,34 +75,21 @@ class Server {
std::cout << "Incoming link local connection" << std::endl;
}
- void handleSessionStarted(boost::shared_ptr<ServerFromClientSession> session) {
- if (!dnsSDServiceRegistered_) {
- dnsSDServiceRegistered_ = true;
- dnsSDService_->onServiceRegistered.connect(boost::bind(&Server::handleServiceRegistered, this, _1));
- LinkLocalServiceInfo info;
- info.setFirstName("Remko");
- info.setLastName("Tron\xc3\xa7on");
- info.setEMail("email@example.com");
- info.setJID(JID("jid@example.com"));
- info.setMessage("I'm not Here");
- info.setNick("Remko");
- info.setStatus(LinkLocalServiceInfo::Away);
- info.setPort(linkLocalConnectionPort_);
- dnsSDService_->registerService(session->getJID().toBare().toString(), linkLocalConnectionPort_, info);
- }
- }
-
void handleServiceRegistered(const DNSSDService::Service& service) {
std::cout << "Service registered " << service.name << " " << service.type << " " << service.domain << std::endl;
}
void handleSessionFinished(boost::shared_ptr<ServerFromClientSession>) {
serverFromClientSession_.reset();
-
- std::cout << "Service unregistered" << std::endl;
- dnsSDServiceRegistered_ = false;
+ unregisterService();
rosterRequested_ = false;
- dnsSDService_->unregisterService();
+ }
+
+ void unregisterService() {
+ if (dnsSDServiceRegistered_) {
+ dnsSDServiceRegistered_ = false;
+ dnsSDService_->unregisterService();
+ }
}
void handleStanzaReceived(boost::shared_ptr<Stanza> stanza, boost::shared_ptr<ServerFromClientSession> session) {
@@ -111,7 +97,22 @@ class Server {
if (!stanza->getTo().isValid()) {
stanza->setTo(JID(session->getDomain()));
}
- if (!stanza->getTo().isValid() || stanza->getTo() == session->getDomain() || stanza->getTo() == session->getJID().toBare()) {
+
+ if (boost::shared_ptr<Presence> presence = boost::dynamic_pointer_cast<Presence>(stanza)) {
+ if (presence->getType() == Presence::Available) {
+ if (!dnsSDServiceRegistered_) {
+ dnsSDServiceRegistered_ = true;
+ dnsSDService_->registerService(session->getJID().toBare().toString(), linkLocalConnectionPort_, getLinkLocalServiceInfo(presence));
+ }
+ else {
+ dnsSDService_->updateService(getLinkLocalServiceInfo(presence));
+ }
+ }
+ else {
+ unregisterService();
+ }
+ }
+ else if (!stanza->getTo().isValid() || stanza->getTo() == session->getDomain() || stanza->getTo() == session->getJID().toBare()) {
if (boost::shared_ptr<IQ> iq = boost::dynamic_pointer_cast<IQ>(stanza)) {
if (iq->getPayload<RosterPayload>()) {
if (iq->getType() == IQ::Get) {
@@ -156,6 +157,32 @@ class Server {
}
}
+ LinkLocalServiceInfo getLinkLocalServiceInfo(boost::shared_ptr<Presence> presence) {
+ LinkLocalServiceInfo info;
+ info.setFirstName("Remko");
+ info.setLastName("Tron\xc3\xa7on");
+ info.setEMail("email@example.com");
+ info.setJID(JID("jid@example.com"));
+ info.setMessage(presence->getStatus());
+ info.setNick("Remko");
+ switch (presence->getShow()) {
+ case StatusShow::Online:
+ case StatusShow::None:
+ case StatusShow::FFC:
+ info.setStatus(LinkLocalServiceInfo::Available);
+ break;
+ case StatusShow::Away:
+ case StatusShow::XA:
+ info.setStatus(LinkLocalServiceInfo::Away);
+ break;
+ case StatusShow::DND:
+ info.setStatus(LinkLocalServiceInfo::DND);
+ break;
+ }
+ info.setPort(linkLocalConnectionPort_);
+ return info;
+ }
+
private:
IDGenerator idGenerator_;
BoostIOServiceThread boostIOServiceThread_;
diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp
index 18cdcb0..d4befd1 100644
--- a/Swiften/LinkLocal/AppleDNSSDService.cpp
+++ b/Swiften/LinkLocal/AppleDNSSDService.cpp
@@ -55,6 +55,13 @@ void AppleDNSSDService::registerService(const String& name, int port, const Link
interruptSelect();
}
+void AppleDNSSDService::updateService(const LinkLocalServiceInfo& info) {
+ boost::lock_guard<boost::mutex> lock(sdRefsMutex);
+ assert(registerSDRef);
+ ByteArray txtRecord = info.toTXTRecord();
+ DNSServiceUpdateRecord(registerSDRef, NULL, NULL, txtRecord.getSize(), txtRecord.getData(), 0);
+}
+
void AppleDNSSDService::unregisterService() {
boost::lock_guard<boost::mutex> lock(sdRefsMutex);
@@ -91,6 +98,7 @@ void AppleDNSSDService::stopResolvingService(const Service& service) {
void AppleDNSSDService::resolveHostname(const String& hostname, int interfaceIndex) {
boost::lock_guard<boost::mutex> lock(sdRefsMutex);
+ std::cout << "Resolve " << hostname << std::endl;
DNSServiceRef hostnameResolveSDRef;
DNSServiceErrorType result = DNSServiceGetAddrInfo(&hostnameResolveSDRef, 0, interfaceIndex, kDNSServiceProtocol_IPv4, hostname.getUTF8Data(), &AppleDNSSDService::handleHostnameResolvedGlobal, this);
@@ -110,11 +118,14 @@ void AppleDNSSDService::doStart() {
onStarted();
// Listen for new services
- assert(!browseSDRef);
- DNSServiceErrorType result = DNSServiceBrowse(&browseSDRef, 0, 0, "_presence._tcp", 0, &AppleDNSSDService::handleServiceDiscoveredGlobal , this);
- if (result != kDNSServiceErr_NoError) {
- std::cerr << "Error creating browse query" << std::endl;
- haveError = true;
+ {
+ boost::lock_guard<boost::mutex> lock(sdRefsMutex);
+ assert(!browseSDRef);
+ DNSServiceErrorType result = DNSServiceBrowse(&browseSDRef, 0, 0, "_presence._tcp", 0, &AppleDNSSDService::handleServiceDiscoveredGlobal , this);
+ if (result != kDNSServiceErr_NoError) {
+ std::cerr << "Error creating browse query" << std::endl;
+ haveError = true;
+ }
}
// Run the main loop
@@ -148,6 +159,7 @@ void AppleDNSSDService::doStart() {
// Hostname resolving
for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {
+ std::cout << "Adding ostname resolve " << std::endl;
int hostnameResolveSocket = DNSServiceRefSockFD(*i);
maxSocket = std::max(maxSocket, hostnameResolveSocket);
FD_SET(hostnameResolveSocket, &fdSet);
@@ -181,6 +193,7 @@ void AppleDNSSDService::doStart() {
for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {
if (FD_ISSET(DNSServiceRefSockFD(*i), &fdSet)) {
DNSServiceProcessResult(*i);
+ std::cout << "Removing hostnameResolve" << std::endl;
hostnameResolveSDRefs.erase(std::remove(hostnameResolveSDRefs.begin(), hostnameResolveSDRefs.end(), *i), hostnameResolveSDRefs.end());
DNSServiceRefDeallocate(*i);
break; // Stop the loop, because we removed an element
@@ -189,23 +202,28 @@ void AppleDNSSDService::doStart() {
}
}
- for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) {
- DNSServiceRefDeallocate(i->second);
- }
- resolveSDRefs.clear();
+ {
+ boost::lock_guard<boost::mutex> lock(sdRefsMutex);
- for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {
- DNSServiceRefDeallocate(*i);
- }
- hostnameResolveSDRefs.clear();
+ for (ServiceSDRefMap::const_iterator i = resolveSDRefs.begin(); i != resolveSDRefs.end(); ++i) {
+ DNSServiceRefDeallocate(i->second);
+ }
+ resolveSDRefs.clear();
- if (registerSDRef) {
- DNSServiceRefDeallocate(registerSDRef);
- registerSDRef = NULL;
- }
+ for (HostnameSDRefs::const_iterator i = hostnameResolveSDRefs.begin(); i != hostnameResolveSDRefs.end(); ++i) {
+ std::cout << "Removing hostnameResolve" << std::endl;
+ DNSServiceRefDeallocate(*i);
+ }
+ hostnameResolveSDRefs.clear();
+
+ if (registerSDRef) {
+ DNSServiceRefDeallocate(registerSDRef);
+ registerSDRef = NULL;
+ }
- DNSServiceRefDeallocate(browseSDRef);
- browseSDRef = NULL;
+ DNSServiceRefDeallocate(browseSDRef);
+ browseSDRef = NULL;
+ }
MainEventLoop::postEvent(boost::bind(boost::ref(onStopped), haveError), shared_from_this());
}
diff --git a/Swiften/LinkLocal/AppleDNSSDService.h b/Swiften/LinkLocal/AppleDNSSDService.h
index cdeafed..fe4a648 100644
--- a/Swiften/LinkLocal/AppleDNSSDService.h
+++ b/Swiften/LinkLocal/AppleDNSSDService.h
@@ -18,6 +18,7 @@ namespace Swift {
virtual void stop();
virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&);
+ virtual void updateService(const LinkLocalServiceInfo&);
virtual void unregisterService();
virtual void startResolvingService(const Service&);
diff --git a/Swiften/LinkLocal/DNSSDService.h b/Swiften/LinkLocal/DNSSDService.h
index 3dd8c7b..9689352 100644
--- a/Swiften/LinkLocal/DNSSDService.h
+++ b/Swiften/LinkLocal/DNSSDService.h
@@ -55,6 +55,7 @@ namespace Swift {
virtual void stop() = 0;
virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&) = 0;
+ virtual void updateService(const LinkLocalServiceInfo&) = 0;
virtual void unregisterService() = 0;
virtual void startResolvingService(const Service&) = 0;
diff --git a/Swiften/LinkLocal/LinkLocalRoster.cpp b/Swiften/LinkLocal/LinkLocalRoster.cpp
index aedea77..89bfa55 100644
--- a/Swiften/LinkLocal/LinkLocalRoster.cpp
+++ b/Swiften/LinkLocal/LinkLocalRoster.cpp
@@ -81,6 +81,9 @@ void LinkLocalRoster::handleServiceAdded(const DNSSDService::Service& service) {
}
void LinkLocalRoster::handleServiceRemoved(const DNSSDService::Service& service) {
+ if (selfService && *selfService == service) {
+ return;
+ }
dnsSDService->stopResolvingService(service);
services.erase(service);
boost::shared_ptr<RosterPayload> roster(new RosterPayload());