From ed44fa1856729483077dd02d417dbfebea0417f7 Mon Sep 17 00:00:00 2001 From: Sanchayan Maity Date: Thu, 7 Jan 2021 17:52:22 +0530 Subject: [PATCH] bluetooth: Register an endpoint according to encode or decode support As we now support codecs other than SBC, we might have codec which does not have an encode or a decode capability. Specifically, in the case of LDAC there isn't a known decoder implementation available. For such a case, we should not register the corresponding endpoint. In case of LDAC, as decoding cannot be supported, we should not register a sink endpoint or vice versa in the other scenario. To do this, we check if encode_buffer or decode_buffer entry for a codec has been set in pa_a2dp_codec and accordingly prevent or allow it's registration. Part-of: --- src/modules/bluetooth/a2dp-codec-util.c | 14 ++++++ src/modules/bluetooth/a2dp-codec-util.h | 3 ++ src/modules/bluetooth/bluez5-util.c | 57 ++++++++++++++++--------- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/src/modules/bluetooth/a2dp-codec-util.c b/src/modules/bluetooth/a2dp-codec-util.c index 71482cdbf..d3d763bcb 100644 --- a/src/modules/bluetooth/a2dp-codec-util.c +++ b/src/modules/bluetooth/a2dp-codec-util.c @@ -88,3 +88,17 @@ void pa_bluetooth_a2dp_codec_gst_init(void) { pa_log_info("GStreamer initialisation done"); #endif } + +bool pa_bluetooth_a2dp_codec_is_codec_available(const pa_a2dp_codec_id *id, bool is_a2dp_sink) { + unsigned int i; + unsigned int count = pa_bluetooth_a2dp_codec_count(); + + for (i = 0; i < count; i++) { + if (memcmp(id, &pa_a2dp_codecs[i]->id, sizeof(pa_a2dp_codec_id)) == 0) { + return (is_a2dp_sink && pa_a2dp_codecs[i]->encode_buffer != NULL) + || (!is_a2dp_sink && pa_a2dp_codecs[i]->decode_buffer != NULL); + } + } + + return false; +} diff --git a/src/modules/bluetooth/a2dp-codec-util.h b/src/modules/bluetooth/a2dp-codec-util.h index 22fa8f65f..3c6b8008e 100644 --- a/src/modules/bluetooth/a2dp-codec-util.h +++ b/src/modules/bluetooth/a2dp-codec-util.h @@ -31,6 +31,9 @@ const pa_a2dp_codec *pa_bluetooth_a2dp_codec_iter(unsigned int i); /* Get codec by name */ const pa_a2dp_codec *pa_bluetooth_get_a2dp_codec(const char *name); +/* Check if the given codec can be supported in A2DP_SINK or A2DP_SOURCE */ +bool pa_bluetooth_a2dp_codec_is_codec_available(const pa_a2dp_codec_id *id, bool is_a2dp_sink); + /* Initialise GStreamer */ void pa_bluetooth_a2dp_codec_gst_init(void); diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c index 4d0180a2e..5017e4526 100644 --- a/src/modules/bluetooth/bluez5-util.c +++ b/src/modules/bluetooth/bluez5-util.c @@ -1335,6 +1335,11 @@ static void parse_remote_endpoint_properties(pa_bluetooth_discovery *y, const ch a2dp_codec_id->vendor_codec_id = 0; } + if (!pa_bluetooth_a2dp_codec_is_codec_available(a2dp_codec_id, pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SINK))) { + pa_xfree(a2dp_codec_id); + return; + } + a2dp_codec_capabilities = pa_xmalloc0(sizeof(*a2dp_codec_capabilities) + capabilities_size); a2dp_codec_capabilities->size = capabilities_size; memcpy(a2dp_codec_capabilities->buffer, capabilities, capabilities_size); @@ -2108,15 +2113,19 @@ static DBusHandlerResult object_manager_handler(DBusConnection *c, DBusMessage * capabilities_size = a2dp_codec->fill_capabilities(capabilities); pa_assert(capabilities_size != 0); - endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name); - append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SINK, codec_id, - capabilities, capabilities_size); - pa_xfree(endpoint); + if (a2dp_codec->decode_buffer != NULL) { + endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name); + append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SINK, codec_id, + capabilities, capabilities_size); + pa_xfree(endpoint); + } - endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name); - append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SOURCE, codec_id, - capabilities, capabilities_size); - pa_xfree(endpoint); + if (a2dp_codec->encode_buffer != NULL) { + endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name); + append_a2dp_object(&array, endpoint, PA_BLUETOOTH_UUID_A2DP_SOURCE, codec_id, + capabilities, capabilities_size); + pa_xfree(endpoint); + } } dbus_message_iter_close_container(&iter, &array); @@ -2214,13 +2223,17 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backe if (!a2dp_codec->can_be_supported()) continue; - endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name); - endpoint_init(y, endpoint); - pa_xfree(endpoint); + if (a2dp_codec->decode_buffer != NULL) { + endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name); + endpoint_init(y, endpoint); + pa_xfree(endpoint); + } - endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name); - endpoint_init(y, endpoint); - pa_xfree(endpoint); + if (a2dp_codec->encode_buffer != NULL) { + endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name); + endpoint_init(y, endpoint); + pa_xfree(endpoint); + } } get_managed_objects(y); @@ -2304,13 +2317,17 @@ void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y) { if (!a2dp_codec->can_be_supported()) continue; - endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name); - endpoint_done(y, endpoint); - pa_xfree(endpoint); + if (a2dp_codec->decode_buffer != NULL) { + endpoint = pa_sprintf_malloc("%s/%s", A2DP_SINK_ENDPOINT, a2dp_codec->name); + endpoint_done(y, endpoint); + pa_xfree(endpoint); + } - endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name); - endpoint_done(y, endpoint); - pa_xfree(endpoint); + if (a2dp_codec->encode_buffer != NULL) { + endpoint = pa_sprintf_malloc("%s/%s", A2DP_SOURCE_ENDPOINT, a2dp_codec->name); + endpoint_done(y, endpoint); + pa_xfree(endpoint); + } } pa_dbus_connection_unref(y->connection);