From 436ae921afbc5c2b461ee9b2d8fa9b1c869ed274 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Remko=20Tron=C3=A7on?= Date: Fri, 17 Jul 2009 09:03:16 +0200 Subject: Implement LinkLocalServiceInfo TXT record. diff --git a/Nim/main.cpp b/Nim/main.cpp index 607cc80..6747d4a 100644 --- a/Nim/main.cpp +++ b/Nim/main.cpp @@ -14,6 +14,7 @@ #include "Swiften/EventLoop/SimpleEventLoop.h" #include "Swiften/EventLoop/EventOwner.h" #include "Swiften/Elements/Stanza.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" #include "Swiften/LinkLocal/LinkLocalRoster.h" #include "Swiften/LinkLocal/DNSSDService.h" #include "Swiften/LinkLocal/AppleDNSSDService.h" @@ -63,7 +64,16 @@ class Server { if (!dnsSDServiceRegistered_) { dnsSDServiceRegistered_ = true; dnsSDService_->onServiceRegistered.connect(boost::bind(&Server::handleServiceRegistered, this, _1)); - dnsSDService_->registerService(session->getJID().toBare().toString(), linkLocalConnectionPort_, std::map()); + LinkLocalServiceInfo info; + info.setFirstName("Remko"); + info.setLastName("Tron\xc3\xe7on"); + 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); } } diff --git a/Swiften/Base/ByteArray.h b/Swiften/Base/ByteArray.h index 88e3fae..bcc3756 100644 --- a/Swiften/Base/ByteArray.h +++ b/Swiften/Base/ByteArray.h @@ -55,6 +55,11 @@ namespace Swift { return result; } + ByteArray& operator+=(const ByteArray& b) { + data_.insert(data_.end(), b.data_.begin(), b.data_.end()); + return *this; + } + friend bool operator==(const ByteArray& a, const ByteArray& b) { return a.data_ == b.data_; } diff --git a/Swiften/LinkLocal/AppleDNSSDService.cpp b/Swiften/LinkLocal/AppleDNSSDService.cpp index 3b71f74..4dd74eb 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.cpp +++ b/Swiften/LinkLocal/AppleDNSSDService.cpp @@ -6,6 +6,7 @@ #include #include "Swiften/EventLoop/MainEventLoop.h" +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" namespace Swift { @@ -44,12 +45,12 @@ void AppleDNSSDService::start() { thread = new boost::thread(boost::bind(&AppleDNSSDService::doStart, shared_from_this())); } -void AppleDNSSDService::registerService(const String& name, int port, const std::map&) { - // TODO: Use properties +void AppleDNSSDService::registerService(const String& name, int port, const LinkLocalServiceInfo& info) { boost::lock_guard lock(sdRefsMutex); assert(!registerSDRef); - DNSServiceErrorType result = DNSServiceRegister(®isterSDRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, 0, NULL, &AppleDNSSDService::handleServiceRegisteredGlobal, this); + ByteArray txtRecord = info.toTXTRecord(); + DNSServiceErrorType result = DNSServiceRegister(®isterSDRef, 0, 0, name.getUTF8Data(), "_presence._tcp", NULL, NULL, port, txtRecord.getSize(), txtRecord.getData(), &AppleDNSSDService::handleServiceRegisteredGlobal, this); interruptSelect(); if (result != kDNSServiceErr_NoError) { onError(); diff --git a/Swiften/LinkLocal/AppleDNSSDService.h b/Swiften/LinkLocal/AppleDNSSDService.h index 3607ce0..6299a96 100644 --- a/Swiften/LinkLocal/AppleDNSSDService.h +++ b/Swiften/LinkLocal/AppleDNSSDService.h @@ -14,7 +14,7 @@ namespace Swift { AppleDNSSDService(); ~AppleDNSSDService(); - virtual void registerService(const String& name, int port, const std::map& properties); + virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&); virtual void unregisterService(); virtual void start(); virtual void stop(); diff --git a/Swiften/LinkLocal/DNSSDService.h b/Swiften/LinkLocal/DNSSDService.h index 3437c58..214cad4 100644 --- a/Swiften/LinkLocal/DNSSDService.h +++ b/Swiften/LinkLocal/DNSSDService.h @@ -6,6 +6,8 @@ #include "Swiften/Base/String.h" namespace Swift { + class LinkLocalServiceInfo; + class DNSSDService { public: struct Service { @@ -18,7 +20,7 @@ namespace Swift { virtual ~DNSSDService(); - virtual void registerService(const String& name, int port, const std::map& properties) = 0; + virtual void registerService(const String& name, int port, const LinkLocalServiceInfo&) = 0; virtual void unregisterService() = 0; virtual void start() = 0; diff --git a/Swiften/LinkLocal/LinkLocalServiceInfo.cpp b/Swiften/LinkLocal/LinkLocalServiceInfo.cpp new file mode 100644 index 0000000..99f83b8 --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalServiceInfo.cpp @@ -0,0 +1,48 @@ +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" + +#include + +namespace Swift { + +ByteArray LinkLocalServiceInfo::toTXTRecord() const { + ByteArray result(getEncoded("txtvers=1")); + if (!firstName.isEmpty()) { + result += getEncoded("1st=" + firstName); + } + if (!lastName.isEmpty()) { + result += getEncoded("last=" + lastName); + } + if (!email.isEmpty()) { + result += getEncoded("email=" + email); + } + if (jid.isValid()) { + result += getEncoded("jid=" + jid.toString()); + } + if (!message.isEmpty()) { + result += getEncoded("msg=" + message); + } + if (!nick.isEmpty()) { + result += getEncoded("nick=" + nick); + } + if (port) { + result += getEncoded("port.p2pj=" + String(boost::lexical_cast(*port))); + } + + switch (status) { + case Available: result += getEncoded("status=avail"); break; + case Away: result += getEncoded("status=away"); break; + case DND: result += getEncoded("status=dnd"); break; + } + + return result; +} + +ByteArray LinkLocalServiceInfo::getEncoded(const String& s) { + ByteArray sizeByte; + sizeByte.resize(1); + assert(s.getLength() < 256); + sizeByte[0] = s.getUTF8Size(); + return sizeByte + ByteArray(s); +} + +} diff --git a/Swiften/LinkLocal/LinkLocalServiceInfo.h b/Swiften/LinkLocal/LinkLocalServiceInfo.h new file mode 100644 index 0000000..bd5286b --- /dev/null +++ b/Swiften/LinkLocal/LinkLocalServiceInfo.h @@ -0,0 +1,56 @@ +#pragma once + +#include + +#include "Swiften/Base/ByteArray.h" +#include "Swiften/Base/String.h" +#include "Swiften/JID/JID.h" + +namespace Swift { + + class LinkLocalServiceInfo { + public: + enum Status { Available, Away, DND }; + + LinkLocalServiceInfo() : status(Available) {} + + const String& getFirstName() const { return firstName; } + void setFirstName(const String& f) { firstName = f; } + + const String& getLastName() const { return lastName; } + void setLastName(const String& l) { lastName = l; } + + const String& getEMail() const { return email; } + void setEMail(const String& e) { email = e; } + + const JID& getJID() const { return jid; } + void setJID(const JID& j) { jid = j; } + + const String& getMessage() const { return message; } + void setMessage(const String& m) { message = m; } + + const String& getNick() const { return nick; } + void setNick(const String& n) { nick = n; } + + Status getStatus() const { return status; } + void setStatus(Status s) { status = s; } + + boost::optional getPort() const { return port; } + void setPort(int p) { port = p; } + + ByteArray toTXTRecord() const; + + private: + static ByteArray getEncoded(const String&); + + private: + String firstName; + String lastName; + String email; + JID jid; + String message; + String nick; + Status status; + boost::optional port; + }; +} diff --git a/Swiften/LinkLocal/Makefile.inc b/Swiften/LinkLocal/Makefile.inc index 54315da..683447c 100644 --- a/Swiften/LinkLocal/Makefile.inc +++ b/Swiften/LinkLocal/Makefile.inc @@ -1,9 +1,12 @@ SWIFTEN_SOURCES += \ Swiften/LinkLocal/DNSSDService.cpp \ - Swiften/LinkLocal/LinkLocalRoster.cpp + Swiften/LinkLocal/LinkLocalRoster.cpp \ + Swiften/LinkLocal/LinkLocalServiceInfo.cpp ifeq ($(MACOSX),1) SWIFTEN_SOURCES += \ Swiften/LinkLocal/AppleDNSSDService.cpp endif + +include Swiften/LinkLocal/UnitTest/Makefile.inc diff --git a/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp new file mode 100644 index 0000000..8efe4ae --- /dev/null +++ b/Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp @@ -0,0 +1,26 @@ +#include +#include + +#include "Swiften/LinkLocal/LinkLocalServiceInfo.h" + +using namespace Swift; + +class LinkLocalServiceInfoTest : public CppUnit::TestFixture { + CPPUNIT_TEST_SUITE(LinkLocalServiceInfoTest); + CPPUNIT_TEST(testGetTXTRecord); + CPPUNIT_TEST_SUITE_END(); + + public: + LinkLocalServiceInfoTest() {} + + void testGetTXTRecord() { + LinkLocalServiceInfo info; + info.setFirstName("Remko"); + info.setLastName("Tron\xc3\xe7on"); + info.setStatus(LinkLocalServiceInfo::Away); + + CPPUNIT_ASSERT_EQUAL(ByteArray("\x09txtvers=1\x09" + String("1st=Remko\x0dlast=Tron\xc3\xe7on\x0bstatus=away")), info.toTXTRecord()); + } +}; + +CPPUNIT_TEST_SUITE_REGISTRATION(LinkLocalServiceInfoTest); diff --git a/Swiften/LinkLocal/UnitTest/Makefile.inc b/Swiften/LinkLocal/UnitTest/Makefile.inc new file mode 100644 index 0000000..abc1180 --- /dev/null +++ b/Swiften/LinkLocal/UnitTest/Makefile.inc @@ -0,0 +1,2 @@ +UNITTEST_SOURCES += \ + Swiften/LinkLocal/UnitTest/LinkLocalServiceInfoTest.cpp -- cgit v0.10.2-6-g49f6