mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-26 07:05:57 -05:00
Honor the "ek" (encryption) flag for RAOP_DEV_OTHER + slight rewrite of raop_device_cb
This commit is contained in:
parent
6289bb0fcb
commit
8468f55910
109
src/player.c
109
src/player.c
@ -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;
|
||||||
|
13
src/raop.c
13
src/raop.c
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user