[mdns] Also handle devices being switched on/off without Avahi service removal notices

This commit is contained in:
ejurgensen 2017-05-02 23:13:53 +02:00
parent e2f65debc8
commit b9e069939e
2 changed files with 21 additions and 10 deletions

View File

@ -362,6 +362,7 @@ struct mdns_resolver
{ {
char *name; char *name;
AvahiServiceResolver *resolver; AvahiServiceResolver *resolver;
AvahiProtocol proto;
struct mdns_resolver *next; struct mdns_resolver *next;
}; };
@ -441,7 +442,7 @@ avahi_address_make(AvahiAddress *addr, AvahiProtocol proto, const void *rdata, s
// Frees all resolvers for a given service name // Frees all resolvers for a given service name
static void static void
resolvers_cleanup(const char *name) resolvers_cleanup(const char *name, AvahiProtocol proto)
{ {
struct mdns_resolver *r; struct mdns_resolver *r;
struct mdns_resolver *prev; struct mdns_resolver *prev;
@ -452,7 +453,7 @@ resolvers_cleanup(const char *name)
{ {
next = r->next; next = r->next;
if (strcmp(name, r->name) != 0) if ((strcmp(name, r->name) != 0) || (proto != r->proto))
{ {
prev = r; prev = r;
continue; continue;
@ -463,8 +464,6 @@ resolvers_cleanup(const char *name)
else else
prev->next = r->next; prev->next = r->next;
DPRINTF(E_DBG, L_MDNS, "Freeing resolver for service '%s'\n", r->name);
avahi_service_resolver_free(r->resolver); avahi_service_resolver_free(r->resolver);
free(r->name); free(r->name);
free(r); free(r);
@ -533,20 +532,30 @@ browse_resolve_callback(AvahiServiceResolver *r, AvahiIfIndex intf, AvahiProtoco
uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata) uint16_t port, AvahiStringList *txt, AvahiLookupResultFlags flags, void *userdata)
{ {
AvahiRecordBrowser *rb; AvahiRecordBrowser *rb;
struct mdns_browser *mb;
struct mdns_record_browser *rb_data; struct mdns_record_browser *rb_data;
char *key; char *key;
char *value; char *value;
uint16_t dns_type; uint16_t dns_type;
int family;
int ret; int ret;
mb = (struct mdns_browser *)userdata;
if (event != AVAHI_RESOLVER_FOUND) if (event != AVAHI_RESOLVER_FOUND)
{ {
if (event == AVAHI_RESOLVER_FAILURE) if (event == AVAHI_RESOLVER_FAILURE)
DPRINTF(E_LOG, L_MDNS, "Avahi Resolver failure: service '%s' type '%s': %s\n", name, type, MDNSERR); DPRINTF(E_LOG, L_MDNS, "Avahi Resolver failure: service '%s' type '%s' proto %d: %s\n", name, type, proto, MDNSERR);
else else
DPRINTF(E_LOG, L_MDNS, "Avahi Resolver empty callback\n"); DPRINTF(E_LOG, L_MDNS, "Avahi Resolver empty callback\n");
resolvers_cleanup(name); family = avahi_proto_to_af(proto);
if (family != AF_UNSPEC)
mb->cb(name, type, domain, NULL, family, NULL, -1, NULL);
// We don't clean up resolvers because we want a notification from them if
// the service reappears (e.g. if device was switched off and then on)
return; return;
} }
@ -556,7 +565,7 @@ browse_resolve_callback(AvahiServiceResolver *r, AvahiIfIndex intf, AvahiProtoco
rb_data->name = strdup(name); rb_data->name = strdup(name);
rb_data->domain = strdup(domain); rb_data->domain = strdup(domain);
rb_data->mb = (struct mdns_browser *)userdata; rb_data->mb = mb;
rb_data->port = port; rb_data->port = port;
while (txt) while (txt)
@ -630,6 +639,7 @@ browse_callback(AvahiServiceBrowser *b, AvahiIfIndex intf, AvahiProtocol proto,
} }
r->name = strdup(name); r->name = strdup(name);
r->proto = proto;
r->next = resolver_list; r->next = resolver_list;
resolver_list = r; resolver_list = r;
@ -638,11 +648,12 @@ browse_callback(AvahiServiceBrowser *b, AvahiIfIndex intf, AvahiProtocol proto,
case AVAHI_BROWSER_REMOVE: case AVAHI_BROWSER_REMOVE:
DPRINTF(E_DBG, L_MDNS, "Avahi Browser: REMOVE service '%s' type '%s' proto %d\n", name, type, proto); DPRINTF(E_DBG, L_MDNS, "Avahi Browser: REMOVE service '%s' type '%s' proto %d\n", name, type, proto);
resolvers_cleanup(name);
family = avahi_proto_to_af(proto); family = avahi_proto_to_af(proto);
if (family != AF_UNSPEC) if (family != AF_UNSPEC)
mb->cb(name, type, domain, NULL, family, NULL, -1, NULL); mb->cb(name, type, domain, NULL, family, NULL, -1, NULL);
resolvers_cleanup(name, proto);
break; break;
case AVAHI_BROWSER_ALL_FOR_NOW: case AVAHI_BROWSER_ALL_FOR_NOW:

View File

@ -1239,7 +1239,7 @@ device_remove(struct output_device *remove)
if (ret < 0) if (ret < 0)
DPRINTF(E_LOG, L_PLAYER, "Could not save state for %s device '%s'\n", remove->type_name, remove->name); DPRINTF(E_LOG, L_PLAYER, "Could not save state for %s device '%s'\n", remove->type_name, remove->name);
DPRINTF(E_DBG, L_PLAYER, "Removing %s device '%s'; stopped advertising\n", remove->type_name, remove->name); DPRINTF(E_INFO, L_PLAYER, "Removing %s device '%s'; stopped advertising\n", remove->type_name, remove->name);
/* Make sure device isn't selected anymore */ /* Make sure device isn't selected anymore */
if (remove->selected) if (remove->selected)