Skip to content

Commit

Permalink
Add a simple Bonjour/Avahi service registration class.
Browse files Browse the repository at this point in the history
This should work out of the box on OS X but requires the Avahi Bonjour
compatability layer on *nix (libdns_sd).

Fairly straightforward service registration and removal that will be
used by a couple of upcoming features (and could easily be used as an
extra layer of 'advertising' by both mythfrontend and mythbackend).
  • Loading branch information
Mark Kendall committed Jan 22, 2012
1 parent 1222fa2 commit b1f1fc8
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 1 deletion.
10 changes: 10 additions & 0 deletions mythtv/configure
Expand Up @@ -138,6 +138,7 @@ Advanced options (experts only):
--libxml2-path=HDRLOC location of directory containing
'libxml/parser.h', not the
directory with parser.h [$libxml2_path_default]
--disable-libdns-sd disable DNS Service Discovery (Bonjour/Zeroconf/Avahi)
--with-bindings=LIST install the bindings specified in the
comma-separated list
Expand Down Expand Up @@ -1354,6 +1355,7 @@ MYTHTV_CONFIG_LIST='
asi
joystick_menu
libcec
libdns_sd
libfftw3
libmpeg2external
libxml2
Expand Down Expand Up @@ -1998,6 +2000,7 @@ enable asi
enable lamemp3
enable libass
enable libcec
enable libdns_sd
enable libxml2
enable libudf
enable lirc
Expand Down Expand Up @@ -4138,6 +4141,8 @@ int main(void) {
EOF
fi

enabled libdns_sd && check_lib dns_sd.h DNSServiceRegister -ldns_sd || disable libdns_sd

if enabled libxml2 ; then
if pkg-config --exists libxml-2.0 ; then
libxml2_path=`pkg-config --cflags-only-I libxml-2.0|sed -n "s/-I\([^ ]*\) *$/\1/p"`
Expand Down Expand Up @@ -4569,6 +4574,7 @@ echo "multi threaded libavcodec ${threads-no}"
if enabled frontend; then
echo "libxml2 support ${libxml2-no} [$libxml2_path]"
fi
echo "libdns_sd (Bonjour) ${libdns_sd-no}"
echo "Frontend ${frontend-no}"
echo "Backend ${backend-no}"
echo "OpenGL ES 2.0 ${opengles-no}"
Expand Down Expand Up @@ -4879,6 +4885,10 @@ if enabled libxml2; then
fi
fi

if enabled libdns_sd; then
append CONFIG_DEFINES "using_libdns_sd"
fi

if enabled libudf; then
append CCONFIG "using_libudf"
fi
Expand Down
102 changes: 102 additions & 0 deletions mythtv/libs/libmythbase/bonjourregister.cpp
@@ -0,0 +1,102 @@
#include <QSocketNotifier>
#include <QtEndian>
#include "mythlogging.h"
#include "bonjourregister.h"

#define LOC QString("Bonjour: ")

BonjourRegister::BonjourRegister(QObject *parent)
: QObject(parent), m_dnssref(0), m_socket(NULL)
{
}

BonjourRegister::~BonjourRegister()
{
if (m_socket)
m_socket->setEnabled(false);

if (m_dnssref)
{
LOG(VB_GENERAL, LOG_INFO, LOC + "De-registering service.");
DNSServiceRefDeallocate(m_dnssref);
}
m_dnssref = 0;

m_socket->deleteLater();
m_socket = NULL;
}

bool BonjourRegister::Register(uint16_t port, const QByteArray &type,
const QByteArray &name, const QByteArray &txt)
{
if (m_dnssref)
{
LOG(VB_GENERAL, LOG_WARNING, LOC + "Service already registered.");
return true;
}

uint16_t qport = qToBigEndian(port);
DNSServiceErrorType res =
DNSServiceRegister(&m_dnssref, 0, 0, (const char*)name.data(),
(const char*)type.data(),
NULL, 0, qport, txt.size(), (void*)txt.data(),
BonjourCallback, this);

if (kDNSServiceErr_NoError != res)
{
LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error: %1").arg(res));
}
else
{
int fd = DNSServiceRefSockFD(m_dnssref);
if (fd != -1)
{
m_socket = new QSocketNotifier(fd, QSocketNotifier::Read, this);
m_socket->setEnabled(true);
connect(m_socket, SIGNAL(activated(int)),
this, SLOT(socketReadyRead()));
return true;
}
}

LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to register service.");
return false;
}


void BonjourRegister::socketReadyRead()
{
DNSServiceErrorType res = DNSServiceProcessResult(m_dnssref);
if (kDNSServiceErr_NoError != res)
LOG(VB_GENERAL, LOG_ERR, LOC + QString("Read Error: %1").arg(res));
}


void BonjourRegister::BonjourCallback(DNSServiceRef ref, DNSServiceFlags flags,
DNSServiceErrorType errorcode,
const char *name, const char *type,
const char *domain, void *object)
{
(void)ref;
(void)flags;

BonjourRegister *bonjour = static_cast<BonjourRegister *>(object);
if (kDNSServiceErr_NoError != errorcode)
{
LOG(VB_GENERAL, LOG_ERR, LOC + QString("Callback Error: %1")
.arg(errorcode));
}
else if (bonjour)
{
LOG(VB_GENERAL, LOG_INFO, LOC +
QString("Service registration complete: name '%1' type '%2' domain: '%3'")
.arg(QString::fromUtf8(name)).arg(QString::fromUtf8(type))
.arg(QString::fromUtf8(domain)));
}
else
{
LOG(VB_GENERAL, LOG_ERR, LOC +
QString("BonjourCallback for unknown object."));
}
}

32 changes: 32 additions & 0 deletions mythtv/libs/libmythbase/bonjourregister.h
@@ -0,0 +1,32 @@
#ifndef BONJOURREGISTER_H
#define BONJOURREGISTER_H

#include <QObject>
#include <dns_sd.h>
#include "mythbaseexp.h"

class QSocketNotifier;

class MBASE_PUBLIC BonjourRegister : public QObject
{
Q_OBJECT
public:
BonjourRegister(QObject *parent = 0);
~BonjourRegister();

bool Register(uint16_t port, const QByteArray &type, const QByteArray &name,
const QByteArray &txt);

private slots:
void socketReadyRead();

private:
static void DNSSD_API BonjourCallback(DNSServiceRef ref,
DNSServiceFlags flags,
DNSServiceErrorType errorcode,
const char *name, const char *type,
const char *domain, void *object);
DNSServiceRef m_dnssref;
QSocketNotifier *m_socket;
};
#endif
9 changes: 8 additions & 1 deletion mythtv/libs/libmythbase/libmythbase.pro
Expand Up @@ -63,7 +63,7 @@ inc.files += mythcoreutil.h mythlocale.h mythdownloadmanager.h
inc.files += mythtranslation.h iso639.h iso3166.h mythmedia.h util.h
inc.files += mythcdrom.h autodeletedeque.h dbutil.h mythhttppool.h mythdeque.h
inc.files += referencecounter.h mythcommandlineparser.h mthread.h mthreadpool.h
inc.files += filesysteminfo.h hardwareprofile.h
inc.files += filesysteminfo.h hardwareprofile.h bonjourregister.h

# Allow both #include <blah.h> and #include <libmythbase/blah.h>
inc2.path = $${PREFIX}/include/mythtv/libmythbase
Expand Down Expand Up @@ -100,6 +100,13 @@ use_hidesyms {
QMAKE_CXXFLAGS += -fvisibility=hidden
}

using_libdns_sd {
DEFINES += USING_LIBDNS_SD
HEADERS += bonjourregister.h
SOURCES += bonjourregister.cpp
LIBS += -ldns_sd
}

using_libudf {
DEFINES += USING_LIBUDF
LIBS += -ludf
Expand Down

0 comments on commit b1f1fc8

Please sign in to comment.