From bb1347f2c08b5daa9515934d5211f647d8fe4b1d Mon Sep 17 00:00:00 2001 From: ejurgensen Date: Sat, 1 Dec 2018 10:03:22 +0100 Subject: [PATCH] Revert "[raop] Listen for _airplay._tcp and make it a condition for device removal (issue #496)" This reverts commit 1e051407d55c28580c3e42b54fc6973f4b0f41cc. --- src/outputs/raop.c | 156 ++++----------------------------------------- 1 file changed, 14 insertions(+), 142 deletions(-) diff --git a/src/outputs/raop.c b/src/outputs/raop.c index 0eca4a5c..21dc01c7 100644 --- a/src/outputs/raop.c +++ b/src/outputs/raop.c @@ -159,11 +159,8 @@ struct raop_extra { enum raop_devtype devtype; - // "ek" param in the mdns announcement bool encrypt; - // "md" param in the mdns announcement bool wants_metadata; - // Part of the "et" param in the mdns announcement bool supports_auth_setup; }; @@ -239,15 +236,6 @@ struct raop_metadata struct raop_metadata *next; }; -struct raop_airplay_announcement -{ - uint64_t id; - char *name; - int family; - - struct raop_airplay_announcement *next; -}; - struct raop_service { int fd; @@ -351,9 +339,6 @@ static struct timeval keep_alive_tv = { 30, 0 }; /* Sessions */ static struct raop_session *sessions; -/* _airplay._tcp announcements */ -static struct raop_airplay_announcement *raop_airplay_announcements; - /* ALAC bits writer - big endian * p outgoing buffer pointer @@ -4572,7 +4557,6 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha { struct output_device *rd; struct raop_extra *re; - struct raop_airplay_announcement *an; cfg_t *airplay; const char *p; char *at_name; @@ -4608,6 +4592,12 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha { DPRINTF(E_LOG, L_RAOP, "Excluding AirPlay device '%s' as set in config\n", at_name); + return; + } + if (airplay && cfg_getbool(airplay, "permanent") && (port < 0)) + { + DPRINTF(E_INFO, L_RAOP, "AirPlay device '%s' disappeared, but set as permanent in config\n", at_name); + return; } @@ -4622,21 +4612,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha if (port < 0) { - // Device stopped advertising, but let's see if we really should remove it - if (airplay && cfg_getbool(airplay, "permanent")) - { - DPRINTF(E_INFO, L_RAOP, "AirPlay device '%s' disappeared, but set as permanent in config\n", at_name); - goto free_rd; - } - for (an = raop_airplay_announcements; an; an = an->next) - { - if (!(id == an->id && family == an->family)) - continue; - - DPRINTF(E_DBG, L_RAOP, "Removal of AirPlay device '%s' deferred for _airplay._tcp announcement\n", at_name); - goto free_rd; - } - + /* Device stopped advertising */ switch (family) { case AF_INET: @@ -4655,7 +4631,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha return; } - // Protocol + /* Protocol */ p = keyval_get(txt, "tp"); if (!p) { @@ -4678,7 +4654,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha goto free_rd; } - // Password protection + /* Password protection */ password = NULL; p = keyval_get(txt, "pw"); if (!p) @@ -4710,7 +4686,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha rd->password = password; - // Device verification + /* Device verification */ p = keyval_get(txt, "sf"); if (p && (safe_hextou64(p, &sf) == 0)) { @@ -4720,7 +4696,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha // Note: device_add() in player.c will get the auth key from the db if available } - // Device type + /* Device type */ re->devtype = RAOP_DEV_OTHER; p = keyval_get(txt, "am"); @@ -4737,14 +4713,14 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha else if (*p == '\0') DPRINTF(E_LOG, L_RAOP, "AirPlay device '%s': am has no value\n", at_name); - // Encrypt stream + /* Encrypt stream */ p = keyval_get(txt, "ek"); if (p && (*p == '1')) re->encrypt = 1; else re->encrypt = 0; - // Metadata support + /* Metadata support */ p = keyval_get(txt, "md"); if (p && (*p != '\0')) re->wants_metadata = 1; @@ -4800,103 +4776,6 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha outputs_device_free(rd); } -// Here is the deal with browsing for _airplay._tcp (even though we mainly use -// _raop._tcp): Some devices (Apple HomePod) stop announcing _raop._tcp records -// despite being online. They will, however, keep announcing _airplay._tcp, so -// we make it a condition that _airplay._tcp also times out before removing a -// device. -static void -raop_device_airplay_cb(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt) -{ - struct raop_airplay_announcement *an; - struct raop_airplay_announcement *prev; - const char *p; - char deviceid[13]; - char raopname[128]; - int i; - uint64_t id; - int ret; - - DPRINTF(E_DBG, L_RAOP, "_airplay._tcp event from '%s' (address '%s', port %d, family %d)\n", name, address, port, family); - -#ifdef DEBUG - for (an = raop_airplay_announcements; an; an = an->next) - { - snprintf(raopname, sizeof(raopname), "%" PRIX64 "@%s", an->id, an->name); - DPRINTF(E_DBG, L_RAOP, "Dump of _airplay._tcp announcements in list: '%s' (family %d)\n", raopname, an->family); - } -#endif - - // Device is gone (note, depending on order it might already have been removed) - if (port < 0) - { - prev = NULL; - for (an = raop_airplay_announcements; an; an = an->next) - { - if (strcmp(name, an->name) == 0 && family == an->family) - break; - - prev = an; - } - - if (!an) - return; - - // Remove from list so raop_device_cb will not find it - if (!prev) - raop_airplay_announcements = an->next; - else - prev->next = an->next; - - snprintf(raopname, sizeof(raopname), "%" PRIX64 "@%s", an->id, an->name); - raop_device_cb(raopname, type, domain, hostname, family, address, port, txt); - - free(an->name); - free(an); - return; - } - - // Find device's ID - p = keyval_get(txt, "deviceid"); - if (!p) - { - DPRINTF(E_WARN, L_RAOP, "_airplay._tcp event from '%s' without deviceid in txt field\n", name); - return; - } - - // Converts p="AB:CD:EF:01:02:03" -> deviceid="ABCDEF0123456" - for (i = 0; (*p != '\0') && (i < sizeof(deviceid)); p++) - { - if (*p == ':') - continue; - - deviceid[i] = *p; - i++; - } - deviceid[sizeof(deviceid) - 1] = '\0'; - - ret = safe_hextou64(deviceid, &id); - if (ret < 0) - { - DPRINTF(E_LOG, L_RAOP, "Could not read AirPlay device ID ('%s') from '%s'\n", deviceid, name); - return; - } - - // If we already have the announcement registered we are done - for (an = raop_airplay_announcements; an; an = an->next) - { - if (id == an->id && family == an->family) - return; - } - - an = calloc(1, sizeof(struct raop_airplay_announcement)); - an->id = id; - an->name = strdup(name); - an->family = family; - an->next = raop_airplay_announcements; - raop_airplay_announcements = an; -} - static int raop_device_start_generic(struct output_device *rd, output_status_cb cb, uint64_t rtptime, bool only_probe) { @@ -5155,18 +5034,11 @@ raop_init(void) ret = mdns_browse("_raop._tcp", family, raop_device_cb, MDNS_CONNECTION_TEST); if (ret < 0) { - DPRINTF(E_LOG, L_RAOP, "Could not add mDNS browser for AirPlay devices (_raop._tcp)\n"); + DPRINTF(E_LOG, L_RAOP, "Could not add mDNS browser for AirPlay devices\n"); goto out_stop_control; } - ret = mdns_browse("_airplay._tcp", family, raop_device_airplay_cb, 0); - if (ret < 0) - { - DPRINTF(E_LOG, L_RAOP, "Could not add mDNS browser for AirPlay devices (_airplay._tcp)\n"); - - goto out_stop_control; - } return 0;