Avahi backends - keep resolvers around to get updates

This commit is contained in:
Jonathan Bagg
2017-08-08 21:56:15 -04:00
parent 4e2d636323
commit 639050b600
2 changed files with 50 additions and 18 deletions

View File

@ -102,7 +102,7 @@ public:
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
void* userdata) void* userdata)
{ {
QString key; QString key = name + QString::number(interface);
QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata); QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata);
switch (event) { switch (event) {
@ -111,10 +111,15 @@ public:
emit ref->pub->error(QZeroConf::browserFailed); emit ref->pub->error(QZeroConf::browserFailed);
break; break;
case AVAHI_BROWSER_NEW: case AVAHI_BROWSER_NEW:
avahi_service_resolver_new(ref->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_USE_MULTICAST, resolveCallback, ref); if (!ref->resolvers.contains(key))
ref->resolvers.insert(key, avahi_service_resolver_new(ref->client, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_USE_MULTICAST, resolveCallback, ref));
break; break;
case AVAHI_BROWSER_REMOVE: case AVAHI_BROWSER_REMOVE:
key = name + QString::number(interface); if (!ref->resolvers.contains(key))
return;
avahi_service_resolver_free(ref->resolvers[key]);
ref->resolvers.remove(key);
if (!ref->pub->services.contains(key)) if (!ref->pub->services.contains(key))
return; return;
QZeroConfService *zcs; QZeroConfService *zcs;
@ -130,7 +135,7 @@ public:
} }
static void resolveCallback( static void resolveCallback(
AvahiServiceResolver *r, AVAHI_GCC_UNUSED AvahiServiceResolver *r,
AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiIfIndex interface,
AVAHI_GCC_UNUSED AvahiProtocol protocol, AVAHI_GCC_UNUSED AvahiProtocol protocol,
AvahiResolverEvent event, AvahiResolverEvent event,
@ -145,11 +150,11 @@ public:
AVAHI_GCC_UNUSED void* userdata) AVAHI_GCC_UNUSED void* userdata)
{ {
bool newRecord = 0; bool newRecord = 0;
QZeroConfService *zcs;
QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata); QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata);
QString key = name + QString::number(interface);
if (event == AVAHI_RESOLVER_FOUND) { if (event == AVAHI_RESOLVER_FOUND) {
QString key = name + QString::number(interface);
QZeroConfService *zcs;
if (ref->pub->services.contains(key)) if (ref->pub->services.contains(key))
zcs = ref->pub->services[key]; zcs = ref->pub->services[key];
else { else {
@ -186,21 +191,31 @@ public:
else else
emit ref->pub->serviceUpdated(zcs); emit ref->pub->serviceUpdated(zcs);
} }
avahi_service_resolver_free(r); else if (ref->pub->services.contains(key)) { // delete service if exists and unable to resolve
zcs = ref->pub->services[key];
ref->pub->services.remove(key);
emit ref->pub->serviceRemoved(zcs);
delete zcs;
// don't delete the resolver here...we need to keep it around so Avahi will keep updating....might be able to resolve the service in the future
}
} }
void broswerCleanUp(void) void broswerCleanUp(void)
{ {
if (!browser) if (!browser)
return; return;
avahi_service_browser_free(browser);
browser = NULL;
QMap<QString, QZeroConfService *>::iterator i; QMap<QString, QZeroConfService *>::iterator i;
for (i = pub->services.begin(); i != pub->services.end(); i++) for (i = pub->services.begin(); i != pub->services.end(); i++)
delete *i; delete *i;
pub->services.clear(); pub->services.clear();
avahi_service_browser_free(browser); QMap<QString, AvahiServiceResolver *>::iterator r;
browser = NULL; for (r = resolvers.begin(); r != resolvers.end(); r++)
avahi_service_resolver_free(*r);
resolvers.clear();
} }
QZeroConf *pub; QZeroConf *pub;
@ -208,6 +223,7 @@ public:
AvahiClient *client; AvahiClient *client;
AvahiEntryGroup *group; AvahiEntryGroup *group;
AvahiServiceBrowser *browser; AvahiServiceBrowser *browser;
QMap <QString, AvahiServiceResolver *> resolvers;
AvahiStringList *txt; AvahiStringList *txt;
QString name, type, domain; QString name, type, domain;
quint16 port; quint16 port;

View File

@ -114,7 +114,7 @@ public:
AVAHI_GCC_UNUSED AvahiLookupResultFlags flags, AVAHI_GCC_UNUSED AvahiLookupResultFlags flags,
void* userdata) void* userdata)
{ {
QString key; QString key = name + QString::number(interface);
QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata); QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata);
switch (event) { switch (event) {
@ -123,10 +123,15 @@ public:
emit ref->pub->error(QZeroConf::browserFailed); emit ref->pub->error(QZeroConf::browserFailed);
break; break;
case AVAHI_BROWSER_NEW: case AVAHI_BROWSER_NEW:
avahi_s_service_resolver_new(ref->server, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_USE_MULTICAST, resolveCallback, ref); if (!ref->resolvers.contains(key))
ref->resolvers.insert(key, avahi_s_service_resolver_new(ref->server, interface, protocol, name, type, domain, AVAHI_PROTO_UNSPEC, AVAHI_LOOKUP_USE_MULTICAST, resolveCallback, ref));
break; break;
case AVAHI_BROWSER_REMOVE: case AVAHI_BROWSER_REMOVE:
key = name + QString::number(interface); if (!ref->resolvers.contains(key))
return;
avahi_s_service_resolver_free(ref->resolvers[key]);
ref->resolvers.remove(key);
if (!ref->pub->services.contains(key)) if (!ref->pub->services.contains(key))
return; return;
QZeroConfService *zcs; QZeroConfService *zcs;
@ -142,7 +147,7 @@ public:
} }
static void resolveCallback( static void resolveCallback(
AvahiSServiceResolver *r, AVAHI_GCC_UNUSED AvahiSServiceResolver *r,
AVAHI_GCC_UNUSED AvahiIfIndex interface, AVAHI_GCC_UNUSED AvahiIfIndex interface,
AVAHI_GCC_UNUSED AvahiProtocol protocol, AVAHI_GCC_UNUSED AvahiProtocol protocol,
AvahiResolverEvent event, AvahiResolverEvent event,
@ -157,11 +162,11 @@ public:
AVAHI_GCC_UNUSED void* userdata) AVAHI_GCC_UNUSED void* userdata)
{ {
bool newRecord = 0; bool newRecord = 0;
QZeroConfService *zcs;
QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata); QZeroConfPrivate *ref = static_cast<QZeroConfPrivate *>(userdata);
QString key = name + QString::number(interface);
if (event == AVAHI_RESOLVER_FOUND) { if (event == AVAHI_RESOLVER_FOUND) {
QString key = name + QString::number(interface);
QZeroConfService *zcs;
if (ref->pub->services.contains(key)) if (ref->pub->services.contains(key))
zcs = ref->pub->services[key]; zcs = ref->pub->services[key];
else { else {
@ -198,21 +203,31 @@ public:
else else
emit ref->pub->serviceUpdated(zcs); emit ref->pub->serviceUpdated(zcs);
} }
avahi_s_service_resolver_free(r); else if (ref->pub->services.contains(key)) { // delete service if exists and unable to resolve
zcs = ref->pub->services[key];
ref->pub->services.remove(key);
emit ref->pub->serviceRemoved(zcs);
delete zcs;
// don't delete the resolver here...we need to keep it around so Avahi will keep updating....might be able to resolve the service in the future
}
} }
void broswerCleanUp(void) void broswerCleanUp(void)
{ {
if (!browser) if (!browser)
return; return;
avahi_s_service_browser_free(browser);
browser = NULL;
QMap<QString, QZeroConfService *>::iterator i; QMap<QString, QZeroConfService *>::iterator i;
for (i = pub->services.begin(); i != pub->services.end(); i++) for (i = pub->services.begin(); i != pub->services.end(); i++)
delete *i; delete *i;
pub->services.clear(); pub->services.clear();
avahi_s_service_browser_free(browser); QMap<QString, AvahiSServiceResolver *>::iterator r;
browser = NULL; for (r = resolvers.begin(); r != resolvers.end(); r++)
avahi_s_service_resolver_free(*r);
resolvers.clear();
} }
void registerService(const char *name, const char *type, const char *domain, quint16 port) void registerService(const char *name, const char *type, const char *domain, quint16 port)
@ -246,6 +261,7 @@ public:
AvahiServerConfig config; AvahiServerConfig config;
AvahiSEntryGroup *group; AvahiSEntryGroup *group;
AvahiSServiceBrowser *browser; AvahiSServiceBrowser *browser;
QMap <QString, AvahiSServiceResolver *> resolvers;
AvahiStringList *txt; AvahiStringList *txt;
bool ready, registerWaiting; bool ready, registerWaiting;
QString name, type, domain; QString name, type, domain;