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 <qeventloop.h>
00024
#include <qapplication.h>
00025
#ifdef HAVE_SYS_TYPES_H
00026
#include <sys/types.h>
00027
#endif
00028
#include <netinet/in.h>
00029
#include "remoteservice.h"
00030
#include "responder.h"
00031
#include "sdevent.h"
00032
#include <kdebug.h>
00033
00034
namespace DNSSD
00035 {
00036
#ifdef HAVE_DNSSD
00037
void resolve_callback ( DNSServiceRef,
00038 DNSServiceFlags,
00039 uint32_t,
00040 DNSServiceErrorType errorCode,
00041
const char*,
00042
const char *hosttarget,
00043 uint16_t port,
00044 uint16_t txtLen,
00045
const char *txtRecord,
00046
void *context
00047 );
00048
00049
#endif
00050
class RemoteServicePrivate :
public Responder
00051 {
00052
public:
00053 RemoteServicePrivate() : Responder(), m_resolved(false)
00054 {};
00055
bool m_resolved;
00056 };
00057
00058 RemoteService::RemoteService(
const QString& label)
00059 {
00060 decode(label);
00061 d =
new RemoteServicePrivate();
00062 }
00063 RemoteService::RemoteService(
const QString& name,
const QString& type,
const QString& domain)
00064 :
ServiceBase(name, type, domain)
00065 {
00066 d =
new RemoteServicePrivate();
00067 }
00068
00069 RemoteService::~RemoteService()
00070 {
00071
delete d;
00072 }
00073
00074 bool RemoteService::resolve()
00075 {
00076
resolveAsync();
00077
while (d->isRunning() && !d->m_resolved) d->process();
00078 d->stop();
00079
return d->m_resolved;
00080 }
00081
00082 void RemoteService::resolveAsync()
00083 {
00084
if (d->isRunning())
return;
00085 d->m_resolved =
false;
00086 kdDebug() <<
this <<
":Starting resolve of : " << m_serviceName <<
" " << m_type <<
" " << m_domain <<
"\n";
00087
#ifdef HAVE_DNSSD
00088
DNSServiceRef ref;
00089
if (DNSServiceResolve(&ref,0,0,m_serviceName.
utf8(), m_type.
ascii(),
00090 domainToDNS(m_domain),resolve_callback,reinterpret_cast<void*>(
this))
00091 == kDNSServiceErr_NoError) d->setRef(ref);
00092
#endif
00093
if (!d->isRunning()) emit
resolved(
false);
00094 }
00095
00096 bool RemoteService::isResolved()
const
00097
{
00098
return d->m_resolved;
00099 }
00100
00101
void RemoteService::customEvent(
QCustomEvent* event)
00102 {
00103
if (event->type() == QEvent::User+SD_ERROR) {
00104 d->stop();
00105 d->m_resolved=
false;
00106 emit resolved(
false);
00107 }
00108
if (event->type() == QEvent::User+SD_RESOLVE) {
00109 ResolveEvent* rev = static_cast<ResolveEvent*>(event);
00110 m_hostName = rev->m_hostname;
00111 m_port = rev->m_port;
00112 m_textData = rev->m_txtdata;
00113 d->m_resolved =
true;
00114 emit resolved(
true);
00115 }
00116 }
00117
00118
void RemoteService::virtual_hook(
int,
void*)
00119 {
00120
00121 }
00122
00123
QDataStream & operator<< (
QDataStream & s,
const RemoteService & a)
00124 {
00125 s << (static_cast<ServiceBase>(a));
00126 Q_INT8 resolved = a.d->m_resolved ? 1:0;
00127 s << resolved;
00128
return s;
00129 }
00130
00131
QDataStream & operator>> (
QDataStream & s, RemoteService & a)
00132 {
00133
00134 a.d->stop();
00135 Q_INT8 resolved;
00136 operator>>(s,(static_cast<ServiceBase&>(a)));
00137 s >> resolved;
00138 a.d->m_resolved = (resolved == 1);
00139
return s;
00140 }
00141
00142
00143
#ifdef HAVE_DNSSD
00144
void resolve_callback ( DNSServiceRef,
00145 DNSServiceFlags,
00146 uint32_t,
00147 DNSServiceErrorType errorCode,
00148
const char*,
00149
const char *hosttarget,
00150 uint16_t port,
00151 uint16_t txtLen,
00152
const char *txtRecord,
00153
void *context
00154 )
00155 {
00156
QObject *obj = reinterpret_cast<QObject*>(context);
00157
if (errorCode != kDNSServiceErr_NoError) {
00158 ErrorEvent err;
00159
QApplication::sendEvent(obj, &err);
00160
return;
00161 }
00162
char key[256];
00163
const char *value;
00164
int index=0;
00165
unsigned char valueLen;
00166 kdDebug() <<
"Resolve callback\n";
00167
QMap<QString,QString> map;
00168
while (TXTRecordGetItemAtIndex(txtLen,txtRecord,index++,256,key,&valueLen,
00169 reinterpret_cast<const void **>(&value)) == kDNSServiceErr_NoError)
00170
if (value) map[
QString::fromUtf8(key)]=
QString::fromUtf8(value,valueLen);
00171
else map[
QString::fromUtf8(key)]=QString::null;
00172 ResolveEvent rev(DNSToDomain(hosttarget),ntohs(port),map);
00173
QApplication::sendEvent(obj, &rev);
00174 }
00175
#endif
00176
00177
00178 }
00179
00180
#include "remoteservice.moc"