Honor the "ek" (encryption) flag for RAOP_DEV_OTHER + slight rewrite of raop_device_cb

This commit is contained in:
ejurgensen 2014-05-18 17:19:50 +02:00
parent 6289bb0fcb
commit 8468f55910
3 changed files with 71 additions and 60 deletions

View File

@ -127,8 +127,9 @@ struct player_command
/* Keep in sync with enum raop_devtype */ /* Keep in sync with enum raop_devtype */
static const char *raop_devtype[] = static const char *raop_devtype[] =
{ {
"AirPort Express 802.11g", "AirPort Express 1 - 802.11g",
"AirPort Express 802.11n", "AirPort Express 2 - 802.11n",
"AirPort Express 3 - 802.11n",
"AppleTV", "AppleTV",
"Other", "Other",
}; };
@ -4210,6 +4211,28 @@ player_device_remove(struct raop_device *rd)
/* RAOP devices discovery - mDNS callback */ /* RAOP devices discovery - mDNS callback */
/* Thread: main (mdns) */ /* Thread: main (mdns) */
/* Examples of txt content:
* Apple TV 2:
["sf=0x4" "am=AppleTV2,1" "vs=130.14" "vn=65537" "tp=UDP" "ss=16" "sr=4 4100" "sv=false" "pw=false" "md=0,1,2" "et=0,3,5" "da=true" "cn=0,1,2,3" "ch=2"]
["sf=0x4" "am=AppleTV2,1" "vs=105.5" "md=0,1,2" "tp=TCP,UDP" "vn=65537" "pw=false" "ss=16" "sr=44100" "da=true" "sv=false" "et=0,3" "cn=0,1" "ch=2" "txtvers=1"]
* Apple TV 3:
["vv=2" "vs=200.54" "vn=65537" "tp=UDP" "sf=0x44" "pk=8...f" "am=AppleTV3,1" "md=0,1,2" "ft=0x5A7FFFF7,0xE" "et=0,3,5" "da=true" "cn=0,1,2,3"]
* Sony STR-DN1040:
["fv=s9327.1090.0" "am=STR-DN1040" "vs=141.9" "vn=65537" "tp=UDP" "ss=16" "sr=44100" "sv=false" "pw=false" "md=0,2" "ft=0x44F0A00" "et=0,4" "da=true" "cn=0,1" "ch=2" "txtvers=1"]
* AirFoil:
["rastx=iafs" "sm=false" "raver=3.5.3.0" "ek=1" "md=0,1,2" "ramach=Win32NT.6" "et=0,1" "cn=0,1" "sr=44100" "ss=16" "raAudioFormats=ALAC" "raflakyzeroconf=true" "pw=false" "rast=afs" "vn=3" "sv=false" "txtvers=1" "ch=2" "tp=UDP"]
* Xbmc 13:
["am=Xbmc,1" "md=0,1,2" "vs=130.14" "da=true" "vn=3" "pw=false" "sr=44100" "ss=16" "sm=false" "tp=UDP" "sv=false" "et=0,1" "ek=1" "ch=2" "cn=0,1" "txtvers=1"]
* Shairport (abrasive/1.0):
["pw=false" "txtvers=1" "vn=3" "sr=44100" "ss=16" "ch=2" "cn=0,1" "et=0,1" "ek=1" "sm=false" "tp=UDP"]
* JB2:
["fv=95.8947" "am=JB2 Gen" "vs=103.2" "tp=UDP" "vn=65537" "pw=false" "s s=16" "sr=44100" "da=true" "sv=false" "et=0,4" "cn=0,1" "ch=2" "txtvers=1"]
* Airport Express 802.11g (Gen 1):
["tp=TCP,UDP" "sm=false" "sv=false" "ek=1" "et=0,1" "cn=0,1" "ch=2" "ss=16" "sr=44100" "pw=false" "vn=3" "txtvers=1"]
* Airport Express 802.11n:
802.11n Gen 2 model (firmware 7.6.4): "am=Airport4,107", "et=0,1"
802.11n Gen 3 model (firmware 7.6.4): "am=Airport10,115", "et=0,4"
*/
static void static void
raop_device_cb(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt) raop_device_cb(const char *name, const char *type, const char *domain, const char *hostname, int family, const char *address, int port, struct keyval *txt)
{ {
@ -4219,9 +4242,6 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
char *at_name; char *at_name;
char *password; char *password;
uint64_t id; uint64_t id;
char wants_metadata;
char has_password;
enum raop_devtype devtype;
int ret; int ret;
ret = safe_hextou64(name, &id); ret = safe_hextou64(name, &id);
@ -4275,6 +4295,7 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
return; return;
} }
/* Protocol */
p = keyval_get(txt, "tp"); p = keyval_get(txt, "tp");
if (!p) if (!p)
{ {
@ -4297,13 +4318,14 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
goto free_rd; goto free_rd;
} }
/* Password protection */
password = NULL; password = NULL;
p = keyval_get(txt, "pw"); p = keyval_get(txt, "pw");
if (!p) if (!p)
{ {
DPRINTF(E_INFO, L_PLAYER, "AirPlay %s: no pw field in TXT record, assuming no password protection\n", name); DPRINTF(E_INFO, L_PLAYER, "AirPlay %s: no pw field in TXT record, assuming no password protection\n", name);
has_password = 0; rd->has_password = 0;
} }
else if (*p == '\0') else if (*p == '\0')
{ {
@ -4313,10 +4335,10 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
} }
else else
{ {
has_password = (strcmp(p, "false") != 0); rd->has_password = (strcmp(p, "false") != 0);
} }
if (has_password) if (rd->has_password)
{ {
DPRINTF(E_LOG, L_PLAYER, "AirPlay device %s is password-protected\n", name); DPRINTF(E_LOG, L_PLAYER, "AirPlay device %s is password-protected\n", name);
@ -4328,52 +4350,39 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
DPRINTF(E_LOG, L_PLAYER, "No password given in config for AirPlay device %s\n", name); DPRINTF(E_LOG, L_PLAYER, "No password given in config for AirPlay device %s\n", name);
} }
devtype = RAOP_DEV_APEX_80211N; rd->password = password;
/* Device type */
rd->devtype = RAOP_DEV_OTHER;
p = keyval_get(txt, "am"); p = keyval_get(txt, "am");
if (!p) if (!p)
{ rd->devtype = RAOP_DEV_APEX1_80211G; // First generation AirPort Express
DPRINTF(E_INFO, L_PLAYER, "AirPlay %s: no am field in TXT record, assuming old Airport Express\n", name); else if (strncmp(p, "AirPort4", strlen("AirPort4")) == 0)
rd->devtype = RAOP_DEV_APEX2_80211N; // Second generation
else if (strncmp(p, "AirPort", strlen("AirPort")) == 0)
rd->devtype = RAOP_DEV_APEX3_80211N; // Third generation and newer
else if (strncmp(p, "AppleTV", strlen("AppleTV")) == 0)
rd->devtype = RAOP_DEV_APPLETV;
else if (*p == '\0')
DPRINTF(E_LOG, L_PLAYER, "AirPlay %s: am has no value\n", name);
/* Old AirPort Express */ /* Encrypt stream */
devtype = RAOP_DEV_APEX_80211G; p = keyval_get(txt, "ek");
if (p && (*p == '1'))
rd->encrypt = 1;
else
rd->encrypt = 0;
goto no_am; /* Metadata support */
}
if (*p == '\0')
{
DPRINTF(E_LOG, L_PLAYER, "AirPlay %s: am has no value\n", name);
goto no_am;
}
if (strncmp(p, "AppleTV", strlen("AppleTV")) == 0)
devtype = RAOP_DEV_APPLETV;
else if (strncmp(p, "AirPort4", strlen("AirPort4")) != 0)
devtype = OTHER;
no_am:
wants_metadata = 0;
p = keyval_get(txt, "md"); p = keyval_get(txt, "md");
if (!p) if (p && (*p != '\0'))
{ rd->wants_metadata = 1;
DPRINTF(E_INFO, L_PLAYER, "AirPlay %s: no md field in TXT record.\n", name); else
rd->wants_metadata = 0;
goto no_md; DPRINTF(E_INFO, L_PLAYER, "AirPlay device %s: password: %u, encrypt: %u, metadata: %u, type %s\n",
} name, rd->has_password, rd->encrypt, rd->wants_metadata, raop_devtype[rd->devtype]);
if (*p == '\0')
{
DPRINTF(E_LOG, L_PLAYER, "AirPlay %s: md has no value\n", name);
goto no_md;
}
wants_metadata = 1;
no_md:
DPRINTF(E_DBG, L_PLAYER, "AirPlay device %s: password: %s, type %s\n", name, (password) ? "yes" : "no", raop_devtype[devtype]);
rd->advertised = 1; rd->advertised = 1;
@ -4390,12 +4399,6 @@ raop_device_cb(const char *name, const char *type, const char *domain, const cha
break; break;
} }
rd->devtype = devtype;
rd->wants_metadata = wants_metadata;
rd->has_password = has_password;
rd->password = password;
player_device_add(rd); player_device_add(rd);
return; return;

View File

@ -1855,23 +1855,28 @@ raop_session_make(struct raop_device *rd, int family, raop_status_cb cb)
switch (rd->devtype) switch (rd->devtype)
{ {
case RAOP_DEV_APEX_80211G: case RAOP_DEV_APEX1_80211G:
rs->encrypt = 1; rs->encrypt = 1;
rs->auth_quirk_itunes = 1; rs->auth_quirk_itunes = 1;
break; break;
case RAOP_DEV_APEX_80211N: case RAOP_DEV_APEX2_80211N:
rs->encrypt = 1; rs->encrypt = 1;
rs->auth_quirk_itunes = 0; rs->auth_quirk_itunes = 0;
break; break;
case RAOP_DEV_APEX3_80211N:
rs->encrypt = 0;
rs->auth_quirk_itunes = 0;
break;
case RAOP_DEV_APPLETV: case RAOP_DEV_APPLETV:
rs->encrypt = 0; rs->encrypt = 0;
rs->auth_quirk_itunes = 0; rs->auth_quirk_itunes = 0;
break; break;
case OTHER: case RAOP_DEV_OTHER:
rs->encrypt = 0; rs->encrypt = rd->encrypt;
rs->auth_quirk_itunes = 0; rs->auth_quirk_itunes = 0;
break; break;
} }

View File

@ -16,11 +16,13 @@ union sockaddr_all
struct sockaddr_storage ss; struct sockaddr_storage ss;
}; };
/* Keep in sync with raop_devtype[] in player.c */
enum raop_devtype { enum raop_devtype {
RAOP_DEV_APEX_80211G, RAOP_DEV_APEX1_80211G,
RAOP_DEV_APEX_80211N, RAOP_DEV_APEX2_80211N,
RAOP_DEV_APEX3_80211N,
RAOP_DEV_APPLETV, RAOP_DEV_APPLETV,
OTHER, RAOP_DEV_OTHER,
}; };
struct raop_session; struct raop_session;
@ -40,6 +42,7 @@ struct raop_device
unsigned selected:1; unsigned selected:1;
unsigned advertised:1; unsigned advertised:1;
unsigned encrypt:1;
unsigned wants_metadata:1; unsigned wants_metadata:1;
unsigned has_password:1; unsigned has_password:1;
const char *password; const char *password;