00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "config.h"
00022
00023
#include "publicservice.h"
00024
#ifdef HAVE_SYS_TYPES_H
00025
#include <sys/types.h>
00026
#endif
00027
#include <netinet/in.h>
00028
#include <qapplication.h>
00029
#include "sdevent.h"
00030
#include "responder.h"
00031
#include "settings.h"
00032
00033
namespace DNSSD
00034 {
00035
#ifdef HAVE_DNSSD
00036
void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode,
const char *name,
00037
const char*,
const char*,
void *context);
00038
#endif
00039
class PublicServicePrivate :
public Responder
00040 {
00041
public:
00042 PublicServicePrivate() : m_published(false)
00043 {}
00044
bool m_published;
00045 };
00046
00047 PublicService::PublicService(
const QString& name,
const QString& type,
unsigned int port,
00048
const QString& domain)
00049 :
QObject(),
ServiceBase(name, type,
QString::null, domain, port)
00050 {
00051 d =
new PublicServicePrivate;
00052
if (domain.isNull())
00053
if (Configuration::publishType()==Configuration::EnumPublishType::LAN) m_domain=
"local.";
00054
else m_domain=Configuration::publishDomain();
00055 }
00056
00057
00058 PublicService::~PublicService()
00059 {
00060
stop();
00061
delete d;
00062 }
00063
00064 void PublicService::setServiceName(
const QString& serviceName)
00065 {
00066 m_serviceName = serviceName;
00067
if (d->isRunning()) {
00068
stop();
00069
publishAsync();
00070 }
00071 }
00072
00073 void PublicService::setDomain(
const QString& domain)
00074 {
00075 m_domain = domain;
00076
if (d->isRunning()) {
00077
stop();
00078
publishAsync();
00079 }
00080 }
00081
00082
00083 void PublicService::setType(
const QString& type)
00084 {
00085 m_type = type;
00086
if (d->isRunning()) {
00087
stop();
00088
publishAsync();
00089 }
00090 }
00091
00092 void PublicService::setPort(
unsigned short port)
00093 {
00094 m_port = port;
00095
if (d->isRunning()) {
00096
stop();
00097
publishAsync();
00098 }
00099 }
00100
00101 bool PublicService::isPublished()
const
00102
{
00103
return d->m_published;
00104 }
00105
00106 void PublicService::setTextData(
const QMap<QString,QString>& textData)
00107 {
00108 m_textData = textData;
00109
if (d->isRunning()) {
00110
stop();
00111
publishAsync();
00112 }
00113 }
00114
00115 bool PublicService::publish()
00116 {
00117
publishAsync();
00118
while (d->isRunning() && !d->m_published) d->process();
00119
return d->m_published;
00120 }
00121
00122 void PublicService::stop()
00123 {
00124 d->stop();
00125 d->m_published =
false;
00126 }
00127
00128 void PublicService::publishAsync()
00129 {
00130
if (d->isRunning())
stop();
00131
#ifdef HAVE_DNSSD
00132
TXTRecordRef txt;
00133 TXTRecordCreate(&txt,0,0);
00134
QMap<QString,QString>::ConstIterator itEnd = m_textData.end();
00135
for (
QMap<QString,QString>::ConstIterator it = m_textData.begin(); it!=itEnd ; ++it) {
00136
QCString value = it.data().utf8();
00137
if (TXTRecordSetValue(&txt,it.key().utf8(),value.length(),value)!=kDNSServiceErr_NoError) {
00138 TXTRecordDeallocate(&txt);
00139 emit
published(
false);
00140
return;
00141 }
00142 }
00143 DNSServiceRef ref;
00144
if (DNSServiceRegister(&ref,0,0,m_serviceName.utf8(),m_type.ascii(),domainToDNS(m_domain),NULL,
00145 htons(m_port),TXTRecordGetLength(&txt),TXTRecordGetBytesPtr(&txt),publish_callback,
00146 reinterpret_cast<void*>(
this)) == kDNSServiceErr_NoError) d->setRef(ref);
00147 TXTRecordDeallocate(&txt);
00148
#endif
00149
if (!d->isRunning()) emit
published(
false);
00150 }
00151
00152
#ifdef HAVE_DNSSD
00153
void publish_callback (DNSServiceRef, DNSServiceFlags, DNSServiceErrorType errorCode,
const char *name,
00154
const char*,
const char*,
void *context)
00155 {
00156
QObject *obj = reinterpret_cast<QObject*>(context);
00157
if (errorCode != kDNSServiceErr_NoError) {
00158 ErrorEvent err;
00159 QApplication::sendEvent(obj, &err);
00160 }
else {
00161 PublishEvent pev(QString::fromUtf8(name));
00162 QApplication::sendEvent(obj, &pev);
00163 }
00164 }
00165
#endif
00166
00167
00168
void PublicService::customEvent(
QCustomEvent* event)
00169 {
00170
if (event->type()==QEvent::User+SD_ERROR) {
00171
stop();
00172 emit
published(
false);
00173 }
00174
if (event->type()==QEvent::User+SD_PUBLISH) {
00175 d->m_published=
true;
00176 emit
published(
true);
00177 m_serviceName = static_cast<PublishEvent*>(event)->m_name;
00178 }
00179 }
00180
00181
void PublicService::virtual_hook(
int,
void*)
00182 {
00183 }
00184
00185 }
00186
00187
#include "publicservice.moc"