summaryrefslogtreecommitdiffstats
path: root/dnssd/publicservice.cpp
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-12-11 03:46:01 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2009-12-11 03:46:01 +0000
commit865f314dd5ed55508f45a32973b709b79a541e36 (patch)
treedc1a3a884bb2fc10a89a3c46313897d22c5771eb /dnssd/publicservice.cpp
parentce4a32fe52ef09d8f5ff1dd22c001110902b60a2 (diff)
downloadtdelibs-865f314dd5ed55508f45a32973b709b79a541e36.tar.gz
tdelibs-865f314dd5ed55508f45a32973b709b79a541e36.zip
kdelibs update to Trinity v3.5.11
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/kdelibs@1061230 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'dnssd/publicservice.cpp')
-rw-r--r--dnssd/publicservice.cpp192
1 files changed, 121 insertions, 71 deletions
diff --git a/dnssd/publicservice.cpp b/dnssd/publicservice.cpp
index 7ba749c53..ad1ebdbb6 100644
--- a/dnssd/publicservice.cpp
+++ b/dnssd/publicservice.cpp
@@ -30,6 +30,12 @@
#include <network/ksocketaddress.h>
#include <kurl.h>
#include <unistd.h>
+#include <avahi-client/client.h>
+#ifdef AVAHI_API_0_6
+#include <avahi-client/publish.h>
+#endif
+#include <avahi-common/alternative.h>
+#include <avahi-common/strlst.h>
#include "sdevent.h"
#include "responder.h"
#include "servicebrowser.h"
@@ -38,16 +44,23 @@
namespace DNSSD
{
static unsigned long publicIP();
-#ifdef HAVE_DNSSD
-void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name,
- const char*, const char*, void *context);
-#endif
-class PublicServicePrivate : public Responder
+
+void publish_callback (AvahiEntryGroup*, AvahiEntryGroupState s, void *context);
+
+class PublicServicePrivate
{
public:
- PublicServicePrivate() : m_published(false)
+ PublicServicePrivate() : m_published(false), m_running(false), m_collision(false), m_group(false)
{}
bool m_published;
+ bool m_running;
+ bool m_collision;
+ AvahiEntryGroup* m_group;
+ void commit()
+ {
+ if (!m_collision) avahi_entry_group_commit(m_group);
+ }
+
};
PublicService::PublicService(const QString& name, const QString& type, unsigned int port,
@@ -55,6 +68,10 @@ PublicService::PublicService(const QString& name, const QString& type, unsigned
: QObject(), ServiceBase(name, type, QString::null, domain, port)
{
d = new PublicServicePrivate;
+ if (Responder::self().client()) {
+ d->m_group = avahi_entry_group_new(Responder::self().client(), publish_callback,this);
+ connect(&Responder::self(),SIGNAL(stateChanged(AvahiClientState)),this,SLOT(clientState(AvahiClientState)));
+ }
if (domain.isNull())
if (Configuration::publishType()==Configuration::EnumPublishType::LAN) m_domain="local.";
else m_domain=Configuration::publishDomain();
@@ -63,114 +80,148 @@ PublicService::PublicService(const QString& name, const QString& type, unsigned
PublicService::~PublicService()
{
- stop();
+ if (d->m_group) avahi_entry_group_free(d->m_group);
delete d;
}
+void PublicService::tryApply()
+{
+ if (fillEntryGroup()) d->commit();
+ else {
+ stop();
+ emit published(false);
+ }
+}
+
void PublicService::setServiceName(const QString& serviceName)
{
m_serviceName = serviceName;
- if (d->isRunning()) {
- stop();
- publishAsync();
- }
+ if (d->m_running) {
+ avahi_entry_group_reset(d->m_group);
+ tryApply();
+ }
}
void PublicService::setDomain(const QString& domain)
{
m_domain = domain;
- if (d->isRunning()) {
- stop();
- publishAsync();
- }
+ if (d->m_running) {
+ avahi_entry_group_reset(d->m_group);
+ tryApply();
+ }
}
void PublicService::setType(const QString& type)
{
m_type = type;
- if (d->isRunning()) {
- stop();
- publishAsync();
- }
+ if (d->m_running) {
+ avahi_entry_group_reset(d->m_group);
+ tryApply();
+ }
}
void PublicService::setPort(unsigned short port)
{
m_port = port;
- if (d->isRunning()) {
- stop();
- publishAsync();
- }
+ if (d->m_running) {
+ avahi_entry_group_reset(d->m_group);
+ tryApply();
+ }
}
-bool PublicService::isPublished() const
+void PublicService::setTextData(const QMap<QString,QString>& textData)
{
- return d->m_published;
+ m_textData = textData;
+ if (d->m_running) {
+ avahi_entry_group_reset(d->m_group);
+ tryApply();
+ }
}
-void PublicService::setTextData(const QMap<QString,QString>& textData)
+bool PublicService::isPublished() const
{
- m_textData = textData;
- if (d->isRunning()) {
- stop();
- publishAsync();
- }
+ return d->m_published;
}
bool PublicService::publish()
{
publishAsync();
- while (d->isRunning() && !d->m_published) d->process();
+ while (d->m_running && !d->m_published) Responder::self().process();
return d->m_published;
}
void PublicService::stop()
{
- d->stop();
- d->m_published = false;
+ if (d->m_group) avahi_entry_group_reset(d->m_group);
+ d->m_published = false;
+}
+bool PublicService::fillEntryGroup()
+{
+ AvahiStringList *s=0;
+ QMap<QString,QString>::ConstIterator itEnd = m_textData.end();
+ for (QMap<QString,QString>::ConstIterator it = m_textData.begin(); it!=itEnd ; ++it)
+ s = avahi_string_list_add_pair(s, it.key().utf8(),it.data().utf8());
+#ifdef AVAHI_API_0_6
+ bool res = (!avahi_entry_group_add_service_strlst(d->m_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC, (AvahiPublishFlags)0,
+ m_serviceName.isNull() ? avahi_client_get_host_name(Responder::self().client()) : m_serviceName.utf8().data(),
+ m_type.ascii(),domainToDNS(m_domain),m_hostName.utf8(),m_port,s));
+#else
+ bool res = (!avahi_entry_group_add_service_strlst(d->m_group, AVAHI_IF_UNSPEC, AVAHI_PROTO_UNSPEC,
+ m_serviceName.isNull() ? avahi_client_get_host_name(Responder::self().client()) : m_serviceName.utf8().data(),
+ m_type.ascii(),m_domain.utf8(),m_hostName.utf8(),m_port,s));
+#endif
+ avahi_string_list_free(s);
+ return res;
}
+void PublicService::clientState(AvahiClientState s)
+{
+ if (!d->m_running) return;
+ switch (s) {
+#ifdef AVAHI_API_0_6
+ case AVAHI_CLIENT_FAILURE:
+#else
+ case AVAHI_CLIENT_S_INVALID:
+ case AVAHI_CLIENT_DISCONNECTED:
+#endif
+ stop();
+ emit published(false);
+ break;
+ case AVAHI_CLIENT_S_REGISTERING:
+ case AVAHI_CLIENT_S_COLLISION:
+ avahi_entry_group_reset(d->m_group);
+ d->m_collision=true;
+ break;
+ case AVAHI_CLIENT_S_RUNNING:
+ if (d->m_collision) {
+ d->m_collision=false;
+ tryApply();
+ }
+ }
+}
+
void PublicService::publishAsync()
{
- if (d->isRunning()) stop();
-#ifdef HAVE_DNSSD
- if (ServiceBrowser::isAvailable()==ServiceBrowser::Working) {
- TXTRecordRef txt;
- TXTRecordCreate(&txt,0,0);
- QMap<QString,QString>::ConstIterator itEnd = m_textData.end();
- for (QMap<QString,QString>::ConstIterator it = m_textData.begin(); it!=itEnd ; ++it) {
- QCString value = it.data().utf8();
- if (TXTRecordSetValue(&txt,it.key().utf8(),value.length(),value)!=kDNSServiceErr_NoError) {
- TXTRecordDeallocate(&txt);
- emit published(false);
- return;
- }
- }
- DNSServiceRef ref;
- if (DNSServiceRegister(&ref,0,0,m_serviceName.utf8(),m_type.ascii(),domainToDNS(m_domain),NULL,
- htons(m_port),TXTRecordGetLength(&txt),TXTRecordGetBytesPtr(&txt),publish_callback,
- reinterpret_cast<void*>(this)) == kDNSServiceErr_NoError) d->setRef(ref);
- TXTRecordDeallocate(&txt);
+ if (d->m_running) stop();
+
+ if (!d->m_group) {
+ emit published(false);
+ return;
}
-#endif
- if (!d->isRunning()) emit published(false);
+ AvahiClientState s=Responder::self().state();
+ d->m_running=true;
+ d->m_collision=true; // make it look like server is getting out of collision to force registering
+ clientState(s);
}
-#ifdef HAVE_DNSSD
-void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode, const char *name,
- const char*, const char*, void *context)
+void publish_callback (AvahiEntryGroup*, AvahiEntryGroupState s, void *context)
{
QObject *obj = reinterpret_cast<QObject*>(context);
- if (errorCode != kDNSServiceErr_NoError) {
- ErrorEvent err;
- QApplication::sendEvent(obj, &err);
- } else {
- PublishEvent pev(QString::fromUtf8(name));
- QApplication::sendEvent(obj, &pev);
- }
+ if (s!=AVAHI_ENTRY_GROUP_ESTABLISHED && s!=AVAHI_ENTRY_GROUP_COLLISION) return;
+ PublishEvent* pev=new PublishEvent(s==AVAHI_ENTRY_GROUP_ESTABLISHED);
+ QApplication::postEvent(obj, pev);
}
-#endif
const KURL PublicService::toInvitation(const QString& host)
{
@@ -194,14 +245,13 @@ const KURL PublicService::toInvitation(const QString& host)
void PublicService::customEvent(QCustomEvent* event)
{
- if (event->type()==QEvent::User+SD_ERROR) {
- stop();
- emit published(false);
- }
if (event->type()==QEvent::User+SD_PUBLISH) {
+ if (!static_cast<PublishEvent*>(event)->m_ok) {
+ setServiceName(QString::fromUtf8(avahi_alternative_service_name(m_serviceName.utf8())));
+ return;
+ }
d->m_published=true;
emit published(true);
- m_serviceName = static_cast<PublishEvent*>(event)->m_name;
}
}