From 30df4e70d09cfe0a331ad0c6d3a4338e8369edc6 Mon Sep 17 00:00:00 2001 From: Christian Glombek Date: Thu, 10 Apr 2025 23:13:46 +0200 Subject: [PATCH] raop: Add `fp_sap25` encryption type Add support for FairPlay SAP v2.5 (encryption type 5) type devices such as Apple Home Pod Minis. Apparently only these devices require the `POST /feedback` heartbeat, so fix that. --- src/modules/module-raop-discover.c | 8 +++++--- src/modules/module-raop-sink.c | 11 ++++++++--- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/modules/module-raop-discover.c b/src/modules/module-raop-discover.c index c794bc076..9a1079a4e 100644 --- a/src/modules/module-raop-discover.c +++ b/src/modules/module-raop-discover.c @@ -71,7 +71,7 @@ * #raop.domain = "" * #raop.device = "" * #raop.transport = "udp" | "tcp" - * #raop.encryption.type = "RSA" | "auth_setup" | "none" + * #raop.encryption.type = "none" | "RSA" | "auth_setup" | "fp_sap25" * #raop.audio.codec = "PCM" | "ALAC" | "AAC" | "AAC-ELD" * #audio.channels = 2 * #audio.format = "S16" | "S24" | "S32" @@ -244,10 +244,12 @@ static void pw_properties_from_avahi_string(const char *key, const char *value, * 3 = FairPlay, * 4 = MFiSAP (/auth-setup), * 5 = FairPlay SAPv2.5 */ - if (str_in_list(value, ",", "1")) - value = "RSA"; + if (str_in_list(value, ",", "5")) + value = "fp_sap25"; else if (str_in_list(value, ",", "4")) value = "auth_setup"; + else if (str_in_list(value, ",", "1")) + value = "RSA"; else value = "none"; pw_properties_set(props, "raop.encryption.type", value); diff --git a/src/modules/module-raop-sink.c b/src/modules/module-raop-sink.c index 8eef429f0..076c388d7 100644 --- a/src/modules/module-raop-sink.c +++ b/src/modules/module-raop-sink.c @@ -197,6 +197,7 @@ enum { CRYPTO_NONE, CRYPTO_RSA, CRYPTO_AUTH_SETUP, + CRYPTO_FP_SAP25, }; enum { CODEC_PCM, @@ -892,9 +893,9 @@ static int rtsp_record_reply(void *data, int status, const struct spa_dict *head interval.tv_nsec = 0; // feedback timer is only needed for auth_setup encryption - if (impl->encryption == CRYPTO_AUTH_SETUP && !impl->feedback_timer) { - - impl->feedback_timer = pw_loop_add_timer(impl->loop, rtsp_do_post_feedback, impl); + if (impl->encryption == CRYPTO_FP_SAP25) { + if (!impl->feedback_timer) + impl->feedback_timer = pw_loop_add_timer(impl->loop, rtsp_do_post_feedback, impl); pw_loop_update_timer(impl->loop, impl->feedback_timer, &timeout, &interval, false); } @@ -1239,6 +1240,7 @@ static int rtsp_do_announce(struct impl *impl) switch (impl->encryption) { case CRYPTO_NONE: + case CRYPTO_FP_SAP25: sdp = spa_aprintf("v=0\r\n" "o=iTunes %s 0 IN IP%d %s\r\n" "s=iTunes\r\n" @@ -1252,6 +1254,7 @@ static int rtsp_do_announce(struct impl *impl) if (!sdp) return -errno; break; + case CRYPTO_AUTH_SETUP: sdp = spa_aprintf("v=0\r\n" "o=iTunes %s 0 IN IP%d %s\r\n" @@ -1877,6 +1880,8 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args) impl->encryption = CRYPTO_RSA; else if (spa_streq(str, "auth_setup")) impl->encryption = CRYPTO_AUTH_SETUP; + else if (spa_streq(str, "fp_sap25")) + impl->encryption = CRYPTO_FP_SAP25; else { pw_log_error( "can't handle encryption type %s", str); res = -EINVAL;