module-raop-sink: Start with GET /info

This commit is contained in:
Christian Glombek 2023-09-23 20:32:09 +02:00
parent 4823e573dc
commit f9e541eee2
3 changed files with 85 additions and 5 deletions

View file

@ -16,6 +16,7 @@
#include <math.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <plist/plist.h>
#include <openssl/err.h>
#if OPENSSL_API_LEVEL >= 30000
@ -29,6 +30,7 @@
#include "config.h"
#include <spa/utils/cleanup.h>
#include <spa/utils/result.h>
#include <spa/utils/string.h>
#include <spa/utils/json.h>
@ -121,6 +123,10 @@
PW_LOG_TOPIC_STATIC(mod_topic, "mod." NAME);
#define PW_LOG_TOPIC_DEFAULT mod_topic
SPA_DEFINE_AUTO_CLEANUP(plist, plist_t, {
spa_clear_ptr(*thing, plist_free);
})
#define FRAMES_PER_TCP_PACKET 4096
#define FRAMES_PER_UDP_PACKET 352
@ -193,6 +199,39 @@ enum {
CODEC_AAC_ELD,
};
// https://openairplay.github.io/airplay-spec/status_flags.html
enum {
AP_STATUS_FLAG_PIN_REQUIRED = (1 << 3),
AP_STATUS_FLAG_PASSWORD_REQUIRED = (1 << 7),
AP_STATUS_FLAG_ONE_TIME_PAIRING_REQUIRED = (1 << 9),
};
// https://emanuelecozzi.net/docs/airplay2/features/
enum {
AP_FEATURE_FLAG_VIDEO_V1 = 1llu,
AP_FEATURE_FLAG_PHOTO = (1llu << 1),
AP_FEATURE_FLAG_SLIDESHOW = (1llu << 5),
AP_FEATURE_FLAG_SCREEN = (1llu << 7),
AP_FEATURE_FLAG_AUDIO = (1llu << 9),
AP_FEATURE_FLAG_AUTHENTICATION_4 = (1llu << 14),
AP_FEATURE_FLAG_FORMAT_PCM = (1llu << 18), // CODEC_PCM
AP_FEATURE_FLAG_FORMAT_ALAC = (1llu << 19), // CODEC_ALAC
AP_FEATURE_FLAG_FORMAT_AAC = (1llu << 20), // CODEC_AAC
AP_FEATURE_FLAG_FORMAT_AAC_ELD = (1llu << 21), // CODEC_AAC_ELD
AP_FEATURE_FLAG_AUTHENTICATION_1 = (1llu << 23), // CRYPTO_RSA
AP_FEATURE_FLAG_AUTHENTICATION_8 = (1llu << 26), // CRYPTO_AUTH_SETUP
AP_FEATURE_FLAG_PAIR_LEGACY = (1llu << 27), // CRYPTO_AUTH_SETUP
AP_FEATURE_FLAG_RAOP = (1llu << 30), // CRYPTO_AUTH_SETUP
AP_FEATURE_FLAG_PAIR_COREUTILS = (1llu << 38), // CRYPTO_PAIR_SETUP
AP_FEATURE_FLAG_BUFFERED_AUDIO = (1llu << 40),
AP_FEATURE_FLAG_PTP = (1llu << 41),
AP_FEATURE_FLAG_PAIR_SYSTEM = (1llu << 43), // CRYPTO_PAIR_SETUP
AP_FEATURE_FLAG_PAIR_HOMEKIT = (1llu << 46), // CRYPTO_PAIR_SETUP
AP_FEATURE_FLAG_PAIR_TRANSIENT = (1llu << 48), // CRYPTO_PAIR_SETUP
AP_FEATURE_FLAG_VIDEO_V2 = (1llu << 49),
AP_FEATURE_FLAG_PAIR_SETUP = (1llu << 51), // CRYPTO_PAIR_SETUP
};
struct impl {
struct pw_context *context;
@ -1539,6 +1578,46 @@ static int rtsp_options_reply(void *data, int status, const struct spa_dict *hea
return res;
}
static int rtsp_do_options(void *data)
{
struct impl *impl = data;
return pw_rtsp_client_send(impl->rtsp, "OPTIONS", &impl->headers->dict,
NULL, NULL, rtsp_options_reply, impl);
}
static int rtsp_get_info_reply(void *data, int status, const struct spa_dict *headers, const struct pw_array *content)
{
struct impl *impl = data;
uint64_t features = 0, status_flags = 0;
spa_auto(plist) info_plist = NULL;
plist_t features_plist = NULL, status_flags_plist = NULL;
pw_log_info("info status: %d", status);
plist_from_bin(content->data, content->size, &info_plist);
status_flags_plist = plist_dict_get_item(info_plist, "statusFlags");
plist_get_uint_val(status_flags_plist, &status_flags);
if (status_flags != 0)
pw_log_info("received statusFlags value: 0x%" PRIx64 "\n", status_flags);
features_plist = plist_dict_get_item(info_plist, "features");
plist_get_uint_val(features_plist, &features);
if (features != 0)
pw_log_info("received features value: 0x%" PRIx64 "\n", features);
return rtsp_do_options(impl);
}
static int rtsp_do_get_info(void *data)
{
struct impl *impl = data;
return pw_rtsp_client_url_send(impl->rtsp, "/info", "GET", &impl->headers->dict,
NULL, NULL, 0, rtsp_get_info_reply, impl);
}
static void rtsp_connected(void *data)
{
struct impl *impl = data;
@ -1562,8 +1641,7 @@ static void rtsp_connected(void *data)
pw_properties_set(impl->headers, "User-Agent", DEFAULT_USER_NAME "/" PACKAGE_VERSION);
pw_rtsp_client_send(impl->rtsp, "OPTIONS", &impl->headers->dict,
NULL, NULL, rtsp_options_reply, impl);
rtsp_do_get_info(data);
}
static void connection_cleanup(struct impl *impl)