mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-05-06 06:46:29 -04:00
bluez5: require RegisterApplication() support
The `{Un}Register{Endpoint,Player}()` functions of the `org.bluez.Media1`
interface were deprecated with the introduction of the `{Un}RegisterApplication()`
functions[0][1]. Fallback to the deprecated interfaces has been present for a
long time in pipewire, but those parts in their current form are prone to
use-after-free issues (#5096). Instead of fixing them, remove them as they
have been deprecated for a long time. The first version of bluez that supports
the new interfaces is 5.51, released on 2019-09-19 [2].
[0]: https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=65bd68b907a95b4748df6929383a833ecfb4b660
[1]: https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?id=01f8fc2997524d85817adb8176e542bac9d0cdfa
[2]: https://git.kernel.org/pub/scm/bluetooth/bluez.git/commit/?h=5.51&id=6de4bdb957cdc85d89851420ab06ca8e226f8d4e
This commit is contained in:
parent
31f0300c48
commit
eec372ba9d
2 changed files with 5 additions and 143 deletions
|
|
@ -2818,12 +2818,9 @@ bool spa_bt_device_supports_media_codec(struct spa_bt_device *device, const stru
|
||||||
if (!codec_target_profile)
|
if (!codec_target_profile)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (!device->adapter->a2dp_application_registered && is_a2dp) {
|
if (is_a2dp && !device->adapter->a2dp_application_registered)
|
||||||
/* Codec switching not supported: only plain SBC allowed */
|
return false;
|
||||||
return (codec->codec_id == A2DP_CODEC_SBC && spa_streq(codec->name, "sbc") &&
|
if (is_bap && !device->adapter->bap_application_registered)
|
||||||
device->adapter->legacy_endpoints_registered);
|
|
||||||
}
|
|
||||||
if (!device->adapter->bap_application_registered && codec->kind == MEDIA_CODEC_BAP)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* Check codec quirks */
|
/* Check codec quirks */
|
||||||
|
|
@ -5504,28 +5501,6 @@ static DBusHandlerResult endpoint_handler(DBusConnection *c, DBusMessage *m, voi
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bluez_register_endpoint_legacy_reply(DBusPendingCall *pending, void *user_data)
|
|
||||||
{
|
|
||||||
struct spa_bt_adapter *adapter = user_data;
|
|
||||||
struct spa_bt_monitor *monitor = adapter->monitor;
|
|
||||||
|
|
||||||
spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
|
|
||||||
if (r == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (dbus_message_is_error(r, DBUS_ERROR_UNKNOWN_METHOD)) {
|
|
||||||
spa_log_warn(monitor->log, "BlueZ D-Bus ObjectManager not available");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
|
|
||||||
spa_log_error(monitor->log, "RegisterEndpoint() failed: %s",
|
|
||||||
dbus_message_get_error_name(r));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
adapter->legacy_endpoints_registered = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void append_basic_variant_dict_entry(DBusMessageIter *dict, const char* key, int variant_type_int, const char* variant_type_str, void* variant) {
|
static void append_basic_variant_dict_entry(DBusMessageIter *dict, const char* key, int variant_type_int, const char* variant_type_str, void* variant) {
|
||||||
DBusMessageIter dict_entry_it, variant_it;
|
DBusMessageIter dict_entry_it, variant_it;
|
||||||
dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_it);
|
dbus_message_iter_open_container(dict, DBUS_TYPE_DICT_ENTRY, NULL, &dict_entry_it);
|
||||||
|
|
@ -5550,112 +5525,6 @@ static void append_basic_array_variant_dict_entry(DBusMessageIter *dict, const c
|
||||||
dbus_message_iter_close_container(dict, &dict_entry_it);
|
dbus_message_iter_close_container(dict, &dict_entry_it);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int bluez_register_endpoint_legacy(struct spa_bt_adapter *adapter,
|
|
||||||
enum spa_bt_media_direction direction,
|
|
||||||
const char *uuid, const struct media_codec *codec)
|
|
||||||
{
|
|
||||||
struct spa_bt_monitor *monitor = adapter->monitor;
|
|
||||||
const char *path = adapter->path;
|
|
||||||
spa_autofree char *object_path = NULL;
|
|
||||||
spa_autoptr(DBusMessage) m = NULL;
|
|
||||||
DBusMessageIter object_it, dict_it;
|
|
||||||
uint8_t caps[A2DP_MAX_CAPS_SIZE];
|
|
||||||
int ret, caps_size;
|
|
||||||
uint16_t codec_id = codec->codec_id;
|
|
||||||
bool sink = (direction == SPA_BT_MEDIA_SINK);
|
|
||||||
|
|
||||||
spa_assert(codec->fill_caps);
|
|
||||||
|
|
||||||
ret = media_codec_to_endpoint(codec, direction, &object_path);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = caps_size = codec->fill_caps(codec, sink ? MEDIA_CODEC_FLAG_SINK : 0, &monitor->global_settings, caps);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
m = dbus_message_new_method_call(BLUEZ_SERVICE,
|
|
||||||
path,
|
|
||||||
BLUEZ_MEDIA_INTERFACE,
|
|
||||||
"RegisterEndpoint");
|
|
||||||
if (m == NULL)
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
dbus_message_iter_init_append(m, &object_it);
|
|
||||||
dbus_message_iter_append_basic(&object_it, DBUS_TYPE_OBJECT_PATH, &object_path);
|
|
||||||
|
|
||||||
dbus_message_iter_open_container(&object_it, DBUS_TYPE_ARRAY, "{sv}", &dict_it);
|
|
||||||
|
|
||||||
append_basic_variant_dict_entry(&dict_it,"UUID", DBUS_TYPE_STRING, "s", &uuid);
|
|
||||||
append_basic_variant_dict_entry(&dict_it, "Codec", DBUS_TYPE_BYTE, "y", &codec_id);
|
|
||||||
append_basic_array_variant_dict_entry(&dict_it, "Capabilities", "ay", "y", DBUS_TYPE_BYTE, caps, caps_size);
|
|
||||||
|
|
||||||
dbus_message_iter_close_container(&object_it, &dict_it);
|
|
||||||
|
|
||||||
if (!send_with_reply(monitor->conn, m, bluez_register_endpoint_legacy_reply, adapter))
|
|
||||||
return -EIO;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int adapter_register_endpoints_legacy(struct spa_bt_adapter *a)
|
|
||||||
{
|
|
||||||
struct spa_bt_monitor *monitor = a->monitor;
|
|
||||||
const struct media_codec * const * const media_codecs = monitor->media_codecs;
|
|
||||||
int i;
|
|
||||||
int err = 0;
|
|
||||||
bool registered = false;
|
|
||||||
|
|
||||||
if (a->legacy_endpoints_registered)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* The legacy bluez5 api doesn't support codec switching
|
|
||||||
* It doesn't make sense to register codecs other than SBC
|
|
||||||
* as bluez5 will probably use SBC anyway and we have no control over it
|
|
||||||
* let's incentivize users to upgrade their bluez5 daemon
|
|
||||||
* if they want proper media codec support
|
|
||||||
* */
|
|
||||||
spa_log_warn(monitor->log,
|
|
||||||
"Using legacy bluez5 API for A2DP - only SBC will be supported. "
|
|
||||||
"Please upgrade bluez5.");
|
|
||||||
|
|
||||||
for (i = 0; media_codecs[i]; i++) {
|
|
||||||
const struct media_codec *codec = media_codecs[i];
|
|
||||||
|
|
||||||
if (codec->id != SPA_BLUETOOTH_AUDIO_CODEC_SBC)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (endpoint_should_be_registered(monitor, codec, SPA_BT_MEDIA_SOURCE)) {
|
|
||||||
if ((err = bluez_register_endpoint_legacy(a, SPA_BT_MEDIA_SOURCE,
|
|
||||||
SPA_BT_UUID_A2DP_SOURCE,
|
|
||||||
codec)))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (endpoint_should_be_registered(monitor, codec, SPA_BT_MEDIA_SINK)) {
|
|
||||||
if ((err = bluez_register_endpoint_legacy(a, SPA_BT_MEDIA_SINK,
|
|
||||||
SPA_BT_UUID_A2DP_SINK,
|
|
||||||
codec)))
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
registered = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!registered) {
|
|
||||||
/* Should never happen as SBC support is always enabled */
|
|
||||||
spa_log_error(monitor->log, "Broken PipeWire build - unable to locate SBC codec");
|
|
||||||
err = -ENOSYS;
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
if (err) {
|
|
||||||
spa_log_error(monitor->log, "Failed to register bluez5 endpoints");
|
|
||||||
}
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void append_supported_features(DBusMessageIter *dict, struct bap_features *features)
|
static void append_supported_features(DBusMessageIter *dict, struct bap_features *features)
|
||||||
{
|
{
|
||||||
const char *key = "SupportedFeatures";
|
const char *key = "SupportedFeatures";
|
||||||
|
|
@ -5911,7 +5780,6 @@ static void bluez_register_application_a2dp_reply(DBusPendingCall *pending, void
|
||||||
{
|
{
|
||||||
struct spa_bt_adapter *adapter = user_data;
|
struct spa_bt_adapter *adapter = user_data;
|
||||||
struct spa_bt_monitor *monitor = adapter->monitor;
|
struct spa_bt_monitor *monitor = adapter->monitor;
|
||||||
bool fallback = true;
|
|
||||||
|
|
||||||
spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
|
spa_autoptr(DBusMessage) r = steal_reply_and_unref(&pending);
|
||||||
if (r == NULL)
|
if (r == NULL)
|
||||||
|
|
@ -5919,21 +5787,16 @@ static void bluez_register_application_a2dp_reply(DBusPendingCall *pending, void
|
||||||
|
|
||||||
if (dbus_message_is_error(r, BLUEZ_ERROR_NOT_SUPPORTED)) {
|
if (dbus_message_is_error(r, BLUEZ_ERROR_NOT_SUPPORTED)) {
|
||||||
spa_log_warn(monitor->log, "Registering media applications for adapter %s is disabled in bluez5", adapter->path);
|
spa_log_warn(monitor->log, "Registering media applications for adapter %s is disabled in bluez5", adapter->path);
|
||||||
goto finish;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
|
if (dbus_message_get_type(r) == DBUS_MESSAGE_TYPE_ERROR) {
|
||||||
spa_log_error(monitor->log, "RegisterApplication() failed: %s",
|
spa_log_error(monitor->log, "RegisterApplication() failed: %s",
|
||||||
dbus_message_get_error_name(r));
|
dbus_message_get_error_name(r));
|
||||||
goto finish;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fallback = false;
|
|
||||||
adapter->a2dp_application_registered = true;
|
adapter->a2dp_application_registered = true;
|
||||||
|
|
||||||
finish:
|
|
||||||
if (fallback)
|
|
||||||
adapter_register_endpoints_legacy(adapter);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void bluez_register_application_bap_reply(DBusPendingCall *pending, void *user_data)
|
static void bluez_register_application_bap_reply(DBusPendingCall *pending, void *user_data)
|
||||||
|
|
|
||||||
|
|
@ -368,7 +368,6 @@ struct spa_bt_adapter {
|
||||||
int powered;
|
int powered;
|
||||||
unsigned int has_msbc:1;
|
unsigned int has_msbc:1;
|
||||||
unsigned int msbc_probed:1;
|
unsigned int msbc_probed:1;
|
||||||
unsigned int legacy_endpoints_registered:1;
|
|
||||||
unsigned int a2dp_application_registered:1;
|
unsigned int a2dp_application_registered:1;
|
||||||
unsigned int bap_application_registered:1;
|
unsigned int bap_application_registered:1;
|
||||||
unsigned int player_registered:1;
|
unsigned int player_registered:1;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue