mirror of
https://gitlab.freedesktop.org/pulseaudio/pulseaudio.git
synced 2026-04-25 06:47:32 -04:00
raop: Restore legacy Airplay support
This commit is contained in:
parent
938fb64115
commit
6ecdfdef4a
2 changed files with 201 additions and 203 deletions
|
|
@ -126,10 +126,6 @@ struct pa_raop_client {
|
|||
pa_raop_client_state_cb_t state_callback;
|
||||
void *state_userdata;
|
||||
|
||||
// Airplay 2 devices require additionnal authentication
|
||||
// It actually is useful to authenticate Airplay server, not the device (see pa_rtsp_auth_setup for more
|
||||
// details)
|
||||
bool require_post_auth;
|
||||
pa_volume_t initial_volume;
|
||||
};
|
||||
|
||||
|
|
@ -867,37 +863,14 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_
|
|||
pa_assert(rtsp == c->rtsp);
|
||||
|
||||
switch (state) {
|
||||
case STATE_CONNECT:
|
||||
case STATE_AUTH_SETUP: {
|
||||
if (c->require_post_auth && state == STATE_CONNECT) {
|
||||
struct {
|
||||
uint32_t ci1;
|
||||
uint32_t ci2;
|
||||
} rci;
|
||||
pa_log_debug("RAOP: CONNECTED");
|
||||
|
||||
pa_random(&rci, sizeof(rci));
|
||||
c->sci = pa_sprintf_malloc("%08x%08x", rci.ci1, rci.ci2);
|
||||
pa_rtsp_add_header(c->rtsp, "Client-Instance", c->sci);
|
||||
|
||||
if (pa_rtsp_auth_setup(
|
||||
c->rtsp,
|
||||
"\x01\x4e\xea\xd0\x4e\xa9\x2e\x47\x69\xd2\xe1\xfb\xd0\x96\x81\xd5\x94\xa8\xef\x18\x45\x4a\x24\xae\xaf\xb3\x14\x97\x0d\xa0\xb5\xa3\x49"
|
||||
) < 0) {
|
||||
pa_log_error("RAOP: The device supports POST method but we were unable to POST auth-setup");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
if (!c->require_post_auth || (c->require_post_auth && state == STATE_AUTH_SETUP)) {
|
||||
{
|
||||
case STATE_CONNECT: {
|
||||
char *key, *iv, *sdp = NULL;
|
||||
int frames = 0;
|
||||
const char *ip;
|
||||
char *url;
|
||||
int ipv;
|
||||
|
||||
pa_log_debug("RAOP: AUTH SETUP");
|
||||
pa_log_debug("RAOP: CONNECT");
|
||||
|
||||
ip = pa_rtsp_localip(c->rtsp);
|
||||
if (pa_is_ip6_address(ip)) {
|
||||
|
|
@ -967,15 +940,11 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_
|
|||
|
||||
pa_rtsp_announce(c->rtsp, sdp);
|
||||
|
||||
connect_finish:
|
||||
connect_finish:
|
||||
pa_xfree(sdp);
|
||||
pa_xfree(url);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case STATE_OPTIONS: {
|
||||
pa_log_debug("RAOP: OPTIONS (stream cb)");
|
||||
|
|
@ -983,28 +952,32 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_
|
|||
break;
|
||||
}
|
||||
|
||||
case STATE_ANNOUNCE: {
|
||||
uint16_t cport = DEFAULT_UDP_CONTROL_PORT;
|
||||
uint16_t tport = DEFAULT_UDP_TIMING_PORT;
|
||||
case STATE_ANNOUNCE:
|
||||
case STATE_AUTH_SETUP: {
|
||||
char *trs = NULL;
|
||||
|
||||
pa_log_debug("RAOP: ANNOUNCE");
|
||||
uint16_t cport = DEFAULT_UDP_CONTROL_PORT;
|
||||
uint16_t tport = DEFAULT_UDP_TIMING_PORT;
|
||||
|
||||
pa_log_debug("RAOP: ANNOUNCE or AUTH-SETUP");
|
||||
|
||||
if (c->protocol == PA_RAOP_PROTOCOL_TCP) {
|
||||
trs = pa_sprintf_malloc(
|
||||
"RTP/AVP/TCP;unicast;interleaved=0-1;mode=record");
|
||||
} else if (c->protocol == PA_RAOP_PROTOCOL_UDP) {
|
||||
if (state == STATE_ANNOUNCE) {
|
||||
c->udp_cfd = open_bind_udp_socket(c, &cport);
|
||||
c->udp_tfd = open_bind_udp_socket(c, &tport);
|
||||
if (c->udp_cfd < 0 || c->udp_tfd < 0)
|
||||
goto annonce_error;
|
||||
|
||||
}
|
||||
trs = pa_sprintf_malloc(
|
||||
"RTP/AVP/UDP;unicast;interleaved=0-1;mode=record;"
|
||||
"control_port=%d;timing_port=%d",
|
||||
cport, tport);
|
||||
}
|
||||
|
||||
if (state == STATE_ANNOUNCE)
|
||||
if (c->state_callback)
|
||||
c->state_callback(PA_RAOP_CONNECTED, c->state_userdata);
|
||||
|
||||
|
|
@ -1031,9 +1004,33 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_
|
|||
}
|
||||
|
||||
case STATE_SETUP: {
|
||||
if (status == STATUS_FORBIDDEN) {
|
||||
struct {
|
||||
uint32_t ci1;
|
||||
uint32_t ci2;
|
||||
} rci;
|
||||
pa_log_debug("RAOP: SETUP - FORBIDDEN");
|
||||
|
||||
pa_random(&rci, sizeof(rci));
|
||||
c->sci = pa_sprintf_malloc("%08x%08x", rci.ci1, rci.ci2);
|
||||
pa_rtsp_add_header(c->rtsp, "Client-Instance", c->sci);
|
||||
|
||||
// Airplay 2 devices require additionnal authentication step
|
||||
// It is actually useful to authenticate AirTunes server, not the device (see pa_rtsp_auth_setup for more details)
|
||||
if (pa_rtsp_auth_setup(
|
||||
c->rtsp,
|
||||
"\x01\x4e\xea\xd0\x4e\xa9\x2e\x47\x69\xd2\xe1\xfb\xd0\x96\x81\xd5\x94\xa8\xef\x18\x45\x4a\x24\xae\xaf\xb3\x14\x97\x0d\xa0\xb5\xa3\x49"
|
||||
) < 0) {
|
||||
pa_log_error("RAOP: Unable to POST auth-setup");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (status == STATUS_OK) {
|
||||
pa_socket_client *sc = NULL;
|
||||
uint32_t sport = DEFAULT_UDP_AUDIO_PORT;
|
||||
uint32_t cport =0, tport = 0;
|
||||
uint32_t cport = 0, tport = 0;
|
||||
char *ajs, *token, *pc, *trs;
|
||||
const char *token_state = NULL;
|
||||
char delimiters[] = ";";
|
||||
|
|
@ -1146,6 +1143,8 @@ static void rtsp_stream_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_
|
|||
c->rtsp = NULL;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case STATE_RECORD: {
|
||||
int32_t latency = 0;
|
||||
|
|
@ -1361,7 +1360,6 @@ static void rtsp_auth_cb(pa_rtsp_client *rtsp, pa_rtsp_state_t state, pa_rtsp_st
|
|||
if (STATUS_OK == status) {
|
||||
publ = pa_xstrdup(pa_headerlist_gets(headers, "Public"));
|
||||
c->sci = pa_xstrdup(pa_rtsp_get_header(c->rtsp, "Client-Instance"));
|
||||
c->require_post_auth = true;
|
||||
|
||||
if (c->password)
|
||||
pa_xfree(c->password);
|
||||
|
|
|
|||
|
|
@ -129,7 +129,7 @@ static void headers_read(pa_rtsp_client *c) {
|
|||
pa_assert(c->callback);
|
||||
|
||||
/* Deal with a SETUP response */
|
||||
if (STATE_SETUP == c->state) {
|
||||
if (STATE_SETUP == c->state && c->status == STATUS_OK) {
|
||||
const char* token_state = NULL;
|
||||
const char* pc = NULL;
|
||||
c->session = pa_xstrdup(pa_headerlist_gets(c->response_headers, "Session"));
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue