33 #include "private/ArnDiscover_p.hpp" 38 #include <QNetworkInterface> 46 ArnDiscoverInfoPrivate::ArnDiscoverInfoPrivate()
55 ArnDiscoverInfoPrivate::~ArnDiscoverInfoPrivate()
61 : d_ptr( new ArnDiscoverInfoPrivate)
73 : d_ptr( new ArnDiscoverInfoPrivate( *other.d_ptr))
80 *d_ptr = *other.d_ptr;
97 return (d->_state < d->_stopState) && !
isError();
121 return d->_stopState;
137 return d->_properties.values(
"group");
145 return d->_serviceName;
185 return d->_properties;
200 default:
return "Unknown";
209 return d->_state <
State::HostInfo ? QString() : QString::number( d->_hostPort);
217 return d->_state <
State::HostIp ? QString() : d->_hostIp.toString();
231 return d->_resolvCode;
245 ArnDiscoverResolverPrivate::ArnDiscoverResolverPrivate()
247 _defaultService =
"Arn Default Service";
251 ArnDiscoverResolverPrivate::~ArnDiscoverResolverPrivate()
272 return ArnDiscoverBrowserB::resolve( serviceName.isEmpty() ? d->_defaultService : serviceName, forceUpdate);
280 return d->_defaultService;
295 ArnDiscoverBrowserBPrivate::ArnDiscoverBrowserBPrivate()
302 ArnDiscoverBrowserBPrivate::~ArnDiscoverBrowserBPrivate()
304 delete _serviceBrowser;
308 void ArnDiscoverBrowserB::init()
312 connect( d->_serviceBrowser, SIGNAL(browseError(
int)),
313 this, SLOT(onBrowseError(
int)));
314 connect( d->_serviceBrowser, SIGNAL(
serviceAdded(
int,QString,QString)),
315 this, SLOT(onServiceAdded(
int,QString,QString)));
316 connect( d->_serviceBrowser, SIGNAL(
serviceRemoved(
int,QString,QString)),
317 this, SLOT(onServiceRemoved(
int,QString,QString)));
320 foreach (QNetworkInterface interface, QNetworkInterface::allInterfaces()) {
321 QNetworkInterface::InterfaceFlags flags = interface.flags();
322 if (!flags.testFlag( QNetworkInterface::IsUp)
323 || flags.testFlag( QNetworkInterface::IsPointToPoint)
324 || flags.testFlag( QNetworkInterface::IsLoopBack))
327 foreach (QNetworkAddressEntry entry, interface.addressEntries()) {
328 QAbstractSocket::NetworkLayerProtocol prot = entry.ip().protocol();
329 if ((prot != QAbstractSocket::IPv4Protocol) && (prot != QAbstractSocket::IPv6Protocol))
332 int prefixLen = entry.prefixLength();
336 if (
Arn::warningMDNS) qWarning() <<
"Bad netmask: nif=" << interface.humanReadableName()
337 <<
", asume prefixLen=" << prefixLen;
339 ArnDiscoverBrowserBPrivate::SubNet subNet( entry.ip(), prefixLen);
340 d->_localHostNetList += subNet;
348 , d_ptr( new ArnDiscoverBrowserBPrivate)
372 return d->_activeServInfos.size();
382 if ((index < 0) || (index >= d->_activeServInfos.size()))
return nullInfo;
384 return d->_activeServInfos.at( index);
392 int index = d->_activeServIds.indexOf(
id);
407 if ((index < 0) || (index >= d->_activeServIds.size()))
return -1;
409 return d->_activeServIds.at( index);
417 return d->_activeServIds.indexOf(
id);
426 if (info.d_ptr->_serviceName == name)
427 return info.d_ptr->_id;
433 bool ArnDiscoverBrowserB::isBrowsing()
const 437 return d->_serviceBrowser->isBrowsing();
445 switch (typeFilter) {
450 default: d->_filter =
"";
455 void ArnDiscoverBrowserB::setFilter(
const QString& group)
467 return d->_defaultStopState;
483 if ((index < 0) || (index >= d->_activeServInfos.size()))
return false;
486 if (state <= info.
state())
return false;
489 info.d_ptr->_stopState = state;
492 info.d_ptr->_stopState = state;
496 Q_ASSERT_X(
false,
"ArnDiscoverBrowser::goTowardState()",
"State passed stopState");
504 void ArnDiscoverBrowserB::browse(
bool enable)
508 if (!enable)
return stopBrowse();
509 if (isBrowsing())
return;
511 d->_activeServIds.clear();
512 d->_activeServInfos.clear();
514 d->_serviceBrowser->setSubType( d->_filter);
515 d->_serviceBrowser->browse( enable);
519 void ArnDiscoverBrowserB::stopBrowse()
523 d->_serviceBrowser->stopBrowse();
527 int ArnDiscoverBrowserB::resolve(
const QString& serviceName,
bool forceUpdate)
534 if ((
id >= 0) && forceUpdate) {
536 removeServiceInfo( index);
544 index = newServiceInfo(
id, serviceName, QString());
545 Q_ASSERT(index >= 0);
547 info = &d->_activeServInfos[ index];
552 info = &d->_activeServInfos[ index];
556 Q_ASSERT(info && (index >= 0));
567 void ArnDiscoverBrowserB::onBrowseError(
int code)
573 void ArnDiscoverBrowserB::onServiceAdded(
int id,
const QString& name,
const QString& domain)
577 if (
Arn::debugDiscover) qDebug() <<
"Browse Service added: name=" << name <<
" domain=" << domain
578 <<
" escFullDomain=" << d->_serviceBrowser->escapedFullDomain();
580 int index = newServiceInfo(
id, name, domain);
581 Q_ASSERT(index >= 0);
584 doNextState( d->_activeServInfos[ index]);
588 void ArnDiscoverBrowserB::onServiceRemoved(
int id,
const QString& name,
const QString& domain)
592 if (
Arn::debugDiscover) qDebug() <<
"Browse Service removed: name=" << name <<
" domain=" << domain;
593 int index = d->_activeServIds.indexOf(
id);
594 removeServiceInfo( index);
600 void ArnDiscoverBrowserB::onResolveError(
int id,
int code)
609 int index = d->_activeServIds.indexOf(
id);
613 info.d_ptr->_resolvCode = code;
624 void ArnDiscoverBrowserB::onResolved(
int id,
const QByteArray& escFullDomain)
626 Q_UNUSED(escFullDomain)
634 <<
" escFullDomain=" << ds->escapedFullDomain();
635 int index = d->_activeServIds.indexOf(
id);
640 if (xsmTxt.
key( xsmTxt.
size() - 1) ==
"protovers")
642 QByteArray servProp = xsmTxt.
value(
"server");
648 info.d_ptr->_hostName = ds->
host();
649 info.d_ptr->_hostPort = ds->
port();
650 info.d_ptr->_properties = xsmTxt;
661 void ArnDiscoverBrowserB::onLookupError(
int id,
int code)
670 int index = d->_activeServIds.indexOf(
id);
674 info.d_ptr->_resolvCode = code;
685 void ArnDiscoverBrowserB::onLookuped(
int id)
692 QString hostName = ds->
host();
694 int index = d->_activeServIds.indexOf(
id);
698 info.d_ptr->_hostIpLookup = ds->
hostAddr();
699 info.d_ptr->_hostIp = info.d_ptr->_hostIpLookup;
701 doHostIpLogic( info);
715 QList<QHostAddress> remHostIpList;
716 remHostIpList += info.d_ptr->_hostIpLookup;
719 for (uint i = 0;
true; ++i) {
721 if (hostIpTxt.isNull())
break;
722 QHostAddress hostIp( hostIpTxt);
723 if (hostIp.isNull())
continue;
725 remHostIpList += hostIp;
728 foreach (
const QHostAddress& remHostIp, remHostIpList) {
729 foreach (
const ArnDiscoverBrowserBPrivate::SubNet& subNet, d->_localHostNetList) {
730 if (remHostIp.isInSubnet( subNet)) {
731 info.d_ptr->_hostIp = remHostIp;
738 int ArnDiscoverBrowserB::newServiceInfo(
int id,
const QString& name,
const QString& domain)
743 info.d_ptr->_id = id;
745 info.d_ptr->_serviceName = name;
746 info.d_ptr->_domain = domain;
747 info.d_ptr->_stopState = d->_defaultStopState;
750 for (index = 0; index < d->_activeServInfos.size(); ++index) {
751 const QString& indexName = d->_activeServInfos.at( index).
serviceName();
752 if (name == indexName)
return -1;
753 if (name < indexName)
break;
755 d->_activeServIds.insert( index,
id);
756 d->_activeServInfos.insert( index, info);
762 void ArnDiscoverBrowserB::removeServiceInfo(
int index)
766 if ((index < 0) || (index >= d->_activeServIds.size()))
return;
768 d->_activeServIds.removeAt( index);
769 d->_activeServInfos.removeAt( index);
777 switch (info.
state()) {
785 ds->
setId( info.d_ptr->_id);
786 connect( ds, SIGNAL(resolveError(
int,
int)),
this, SLOT(onResolveError(
int,
int)));
787 connect( ds, SIGNAL(resolved(
int,QByteArray)),
this, SLOT(onResolved(
int,QByteArray)));
798 ds->
setId( info.d_ptr->_id);
799 connect( ds, SIGNAL(lookupError(
int,
int)),
this, SLOT(onLookupError(
int,
int)));
800 connect( ds, SIGNAL(lookuped(
int)),
this, SLOT(onLookuped(
int)));
813 ArnDiscoverAdvertisePrivate::ArnDiscoverAdvertisePrivate()
815 _hasSetupAdvertise =
false;
820 ArnDiscoverAdvertisePrivate::~ArnDiscoverAdvertisePrivate()
826 void ArnDiscoverAdvertise::init()
833 , d_ptr( new ArnDiscoverAdvertisePrivate)
855 int port,
const QString& hostName)
859 if (
Arn::debugDiscover) qDebug() <<
"Discover advertise setup: serviceName=" << serviceName
860 <<
" port=" << port <<
" hostName=" << hostName;
861 d->_discoverType = discoverType;
862 d->_service = serviceName;
865 xsm.
add(
"protovers",
"1.1");
868 d->_arnZCReg->setSubTypes( d->_groups);
870 for (
int i = 0; i < d->_groups.size(); ++i) {
871 xsm.
add(
"group", uint(i), d->_groups.at(i));
873 for (
int i = 0; i < d->_hostIpList.size(); ++i) {
874 xsm.
add(
"hostIp", uint(i), d->_hostIpList.at(i));
876 xsm += d->_customProperties;
878 d->_arnZCReg->setTxtRecordMap( xsm);
879 d->_arnZCReg->setHost( hostName);
882 connect( d->_arnZCReg, SIGNAL(registered(QString)),
this, SLOT(serviceRegistered(QString)));
883 connect( d->_arnZCReg, SIGNAL(registrationError(
int)),
this, SLOT(serviceRegistrationError(
int)));
885 QTimer::singleShot(0,
this, SLOT(postSetupThis()));
889 void ArnDiscoverAdvertise::postSetupThis()
893 d->_hasSetupAdvertise =
true;
895 if (!d->_service.isEmpty())
900 void ArnDiscoverAdvertise::serviceRegistered(
const QString& serviceName)
902 if (
Arn::debugDiscover) qDebug() <<
"DiscoverAdvertice Service registered: serviceName=" << serviceName;
908 void ArnDiscoverAdvertise::serviceRegistrationError(
int code)
920 return d->_customProperties;
936 d->_customProperties.add( key, val);
940 bool ArnDiscoverAdvertise::hasSetupAdvertise()
const 944 return d->_hasSetupAdvertise;
948 void ArnDiscoverAdvertise::setHostIpList(
const QStringList& hostIpList)
952 d->_hostIpList = hostIpList;
968 return d->_hasSetupAdvertise ? d->_arnZCReg->currentServiceName() : d->_service;
976 return State::fromInt( d->_arnZCReg->state());
987 if (!d->_hasSetupAdvertise)
return;
990 if (
Arn::debugDiscover) qDebug() <<
"DiscoverAdvertise Service will change: serviceName=" << d->_service;
992 d->_arnZCReg->releaseService();
993 d->_arnZCReg->setServiceName( d->_service);
994 d->_arnZCReg->registerService();
1018 d->_groups += group;
void setGroups(const QStringList &groups)
Set service discover groups used for filter browsing.
QStringList groups() const
Return service discover groups used for filter browsing.
bool goTowardState(int index, ArnDiscoverInfo::State state)
Command a service to go towards a stop state.
Registering a ZeroConfig service.
static QByteArray info()
Give information about this library.
ArnDiscoverInfo::State defaultStopState() const
Return the default stop state for this service discover browser.
void setId(int id)
Sets the id number for this this lookup.
QString hostName() const
Return the host name for this service.
ArnDiscoverResolver(QObject *parent=arnNullptr)
static int getNextId()
Return the next id number for zero config objects.
State of Arn discover browse data. Can be tested by relative order.
QStringList groups() const
Return the groups for this service.
quint16 port() const
Returns the port number for connecting to the service.
QString hostIpString() const
Return the printable host ip-address for this service.
void advertiseService(ArnDiscover::Type discoverType, const QString &serviceName, int port=-1, const QString &hostName=QString())
Start advertising the service.
QString serviceName() const
Returns the service name used for this resolv.
State state() const
Return the state for this service.
void serviceRemoved(int index)
Indicate service has been removed.
State stopState() const
Return the stop state for this service.
void serviceChangeError(int code)
Indicate unsuccessfull advertise of service.
Container class with string representation for serialized data.
int resolvCode() const
Return the latest resolv error code for this service.
Advertise an Arn service.
Browsing for ZeroConfig services.
Ok, defined as kDNSServiceErr_NoError in dns_sd.h.
const ArnDiscoverInfo & infoByIndex(int index)
Return the discover service info by its index.
ArnDiscoverInfo & operator=(const ArnDiscoverInfo &other)
void addGroup(const QString &group)
Add a service discover group.
const quint16 defaultTcpPort
QString host() const
Returns the host name for this resolv.
Got service name and domain (from browsing)
void serviceAdded(int index, const QString &name)
Indicate service has been added (discovered)
int indexToId(int index)
Return the discover service id by its index.
int resolve(const QString &serviceName, bool forceUpdate=true)
Resolve a specific service name.
Got error during resolving HostName, HostPort, type and properties.
QString service() const
Returns the requested service name for this Advertise.
void releaseLookup()
Release the lookup.
ArnDiscoverBrowserB(QObject *parent=arnNullptr)
QHostAddress hostIp() const
Return the host ip-address for this service.
QByteArray value(int i, const char *def=arnNullptr) const
bool inProgress() const
Is discover in progress for this service.
Types of Arn discover advertise.
QString hostWithInfo() const
Get the the HostWithInfo string.
Arn::XStringMap customProperties() const
Return service custom properties.
QString currentService() const
Returns the current service name for this Advertise.
QString hostPortString() const
Return the printable host port for this service.
QString serviceName() const
Return the service name for this service.
int IdToIndex(int id)
Return the discover service index by its id.
void resolve(bool forceMulticast=false)
Resolve the service.
void lookup(bool forceMulticast=false)
Lookup the host address.
int serviceNameToId(const QString &name)
Return the discover service id by its name.
void addCustomProperty(const QString &key, const QString &val)
Add service custom property.
States of DiscoverAdvertise / These values must be synced with: ArnZeroConf::State.
QHostAddress hostAddr() const
Returns the host address for this Lookup.
Arn::XStringMap properties() const
Return the properties for this service.
Got error during DNS lookup HostIp.
void setDefaultService(const QString &defaultService)
Set the default service name.
void setCustomProperties(const Arn::XStringMap &customProperties)
Set service custom properties.
QString valueString(int i, const QString &def=QString()) const
ArnDiscoverBrowser(QObject *parent=arnNullptr)
void setDefaultStopState(ArnDiscoverInfo::State defaultStopState)
Set the default stop state for this service discover browser.
void releaseResolve()
Release the resolving.
Also got HostName, HostPort, type and properties (from resolving)
void setId(int id)
Sets the id number for this this resolv.
QByteArray key(int i, const char *def=arnNullptr) const
Resolv a ZeroConfig service.
Browse() and resolve() together, may never be used to the same instance.
QString typeString() const
Return the printable type for this service.
void serviceChanged(const QString &serviceName)
Indicate successfull advertise of service.
Also got HostIp (from DNS lookup)
bool isError() const
Is in an error state for this service.
Class for holding current discover info of one service.
QString defaultService() const
Return the default service name.
XStringMap & add(const char *key, const QByteArray &val)
void infoUpdated(int index, ArnDiscoverInfo::State state)
Indicate service has been updated.
State state() const
Returns the state for this Advertise.
const ArnDiscoverInfo & infoByName(const QString &serviceName)
Return the discover service info by its name.
quint16 hostPort() const
Return the port for this service.
bool getTxtRecordMap(Arn::XStringMap &xsm)
Load a XStringMap with parameters from the Txt Record.
QString makeHostWithInfo(const QString &host, const QString &info)
Make a combined host and info string, i.e. HostWithInfo
int serviceCount() const
Return the number of active discover services.
QString domain() const
Return the domain for this service.
ArnDiscover::Type type() const
Return the discover type for this service.
QString host() const
Returns the host name for this Lookup.
const ArnDiscoverInfo & infoById(int id)
Return the discover service info by its id.
ArnDiscoverAdvertise(QObject *parent=arnNullptr)
virtual void setService(const QString &service)
Set the service name.