00001 #include <QSocketNotifier>
00002 #include <QtEndian>
00003
00004 #include <stdlib.h>
00005
00006 #include "mythlogging.h"
00007 #include "bonjourregister.h"
00008
00009 #define LOC QString("Bonjour: ")
00010
00011 BonjourRegister::BonjourRegister(QObject *parent)
00012 : QObject(parent), m_dnssref(0), m_socket(NULL)
00013 {
00014 setenv("AVAHI_COMPAT_NOWARN", "1", 1);
00015 }
00016
00017 BonjourRegister::~BonjourRegister()
00018 {
00019 if (m_socket)
00020 m_socket->setEnabled(false);
00021
00022 if (m_dnssref)
00023 {
00024 LOG(VB_GENERAL, LOG_INFO, LOC +
00025 QString("De-registering service '%1' on '%2'")
00026 .arg(m_type.data()).arg(m_name.data()));
00027 DNSServiceRefDeallocate(m_dnssref);
00028 }
00029 m_dnssref = 0;
00030
00031 m_socket->deleteLater();
00032 m_socket = NULL;
00033 }
00034
00035 bool BonjourRegister::Register(uint16_t port, const QByteArray &type,
00036 const QByteArray &name, const QByteArray &txt)
00037 {
00038 if (m_dnssref)
00039 {
00040 LOG(VB_GENERAL, LOG_WARNING, LOC + "Service already registered.");
00041 return true;
00042 }
00043
00044 uint16_t qport = qToBigEndian(port);
00045 DNSServiceErrorType res =
00046 DNSServiceRegister(&m_dnssref, 0, 0, (const char*)name.data(),
00047 (const char*)type.data(),
00048 NULL, 0, qport, txt.size(), (void*)txt.data(),
00049 BonjourCallback, this);
00050
00051 if (kDNSServiceErr_NoError != res)
00052 {
00053 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Error: %1").arg(res));
00054 }
00055 else
00056 {
00057 int fd = DNSServiceRefSockFD(m_dnssref);
00058 if (fd != -1)
00059 {
00060 m_socket = new QSocketNotifier(fd, QSocketNotifier::Read, this);
00061 m_socket->setEnabled(true);
00062 connect(m_socket, SIGNAL(activated(int)),
00063 this, SLOT(socketReadyRead()));
00064 return true;
00065 }
00066 }
00067
00068 LOG(VB_GENERAL, LOG_ERR, LOC + "Failed to register service.");
00069 return false;
00070 }
00071
00072
00073 void BonjourRegister::socketReadyRead()
00074 {
00075 DNSServiceErrorType res = DNSServiceProcessResult(m_dnssref);
00076 if (kDNSServiceErr_NoError != res)
00077 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Read Error: %1").arg(res));
00078 }
00079
00080
00081 void BonjourRegister::BonjourCallback(DNSServiceRef ref, DNSServiceFlags flags,
00082 DNSServiceErrorType errorcode,
00083 const char *name, const char *type,
00084 const char *domain, void *object)
00085 {
00086 (void)ref;
00087 (void)flags;
00088
00089 BonjourRegister *bonjour = static_cast<BonjourRegister *>(object);
00090 if (kDNSServiceErr_NoError != errorcode)
00091 {
00092 LOG(VB_GENERAL, LOG_ERR, LOC + QString("Callback Error: %1")
00093 .arg(errorcode));
00094 }
00095 else if (bonjour)
00096 {
00097 LOG(VB_GENERAL, LOG_INFO, LOC +
00098 QString("Service registration complete: name '%1' type '%2' domain: '%3'")
00099 .arg(QString::fromUtf8(name)).arg(QString::fromUtf8(type))
00100 .arg(QString::fromUtf8(domain)));
00101 bonjour->m_name = name;
00102 bonjour->m_type = type;
00103 }
00104 else
00105 {
00106 LOG(VB_GENERAL, LOG_ERR, LOC +
00107 QString("BonjourCallback for unknown object."));
00108 }
00109 }
00110