summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor V. Kovalenko <igor.v.kovalenko@gmail.com>2021-02-22 23:14:37 +0300
committerPulseAudio Marge Bot <pulseaudio-maintainers@lists.freedesktop.org>2021-04-05 15:43:32 +0000
commitddad63a23cff6f3f0cb394230b103aaaadbc056e (patch)
treefdba620d4ae3dfe406345e2771f7c01134ffd116
parentf0d32e9454b850ace231361763d648d6312f5ac3 (diff)
bluetooth: show negotiated HFP codec
While codec switching for HFP is not implemented, show current codec via messaging api. Part-of: <https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/507>
-rw-r--r--src/modules/bluetooth/a2dp-codec-util.c9
-rw-r--r--src/modules/bluetooth/a2dp-codec-util.h6
-rw-r--r--src/modules/bluetooth/module-bluez5-device.c56
3 files changed, 53 insertions, 18 deletions
diff --git a/src/modules/bluetooth/a2dp-codec-util.c b/src/modules/bluetooth/a2dp-codec-util.c
index 355e19ca7..ca8df468e 100644
--- a/src/modules/bluetooth/a2dp-codec-util.c
+++ b/src/modules/bluetooth/a2dp-codec-util.c
@@ -80,6 +80,15 @@ const pa_a2dp_codec *pa_bluetooth_a2dp_codec_iter(unsigned int i) {
return pa_a2dp_codecs[i];
}
+unsigned int pa_bluetooth_hf_codec_count(void) {
+ return PA_ELEMENTSOF(pa_hf_codecs);
+}
+
+const pa_a2dp_codec *pa_bluetooth_hf_codec_iter(unsigned int i) {
+ pa_assert(i < pa_bluetooth_hf_codec_count());
+ return pa_hf_codecs[i];
+}
+
const pa_a2dp_codec *pa_bluetooth_get_hf_codec(const char *name) {
unsigned int i;
diff --git a/src/modules/bluetooth/a2dp-codec-util.h b/src/modules/bluetooth/a2dp-codec-util.h
index 6330fd8e8..57a15c744 100644
--- a/src/modules/bluetooth/a2dp-codec-util.h
+++ b/src/modules/bluetooth/a2dp-codec-util.h
@@ -37,6 +37,12 @@ bool pa_bluetooth_a2dp_codec_is_available(const pa_a2dp_codec_id *id, bool is_a2
/* Initialise GStreamer */
void pa_bluetooth_a2dp_codec_gst_init(void);
+/* Get number of supported HSP/HFP codecs */
+unsigned int pa_bluetooth_hf_codec_count(void);
+
+/* Get i-th codec. Codec with higher number has higher priority */
+const pa_a2dp_codec *pa_bluetooth_hf_codec_iter(unsigned int i);
+
/* Get HSP/HFP codec by name */
const pa_a2dp_codec *pa_bluetooth_get_hf_codec(const char *name);
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index 6e75bfcbc..4d3d0c9c2 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -2361,31 +2361,49 @@ static char *list_codecs(struct userdata *u) {
bool is_a2dp_sink;
void *state;
- is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
-
- a2dp_endpoints = is_a2dp_sink ? u->device->a2dp_sink_endpoints : u->device->a2dp_source_endpoints;
-
encoder = pa_json_encoder_new();
pa_json_encoder_begin_element_array(encoder);
- PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, a2dp_endpoints, state) {
- for (i = 0; i < pa_bluetooth_a2dp_codec_count(); i++) {
- const pa_a2dp_codec *a2dp_codec;
+ if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK || u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE) {
+ is_a2dp_sink = u->profile == PA_BLUETOOTH_PROFILE_A2DP_SINK;
+
+ a2dp_endpoints = is_a2dp_sink ? u->device->a2dp_sink_endpoints : u->device->a2dp_source_endpoints;
+
+ PA_HASHMAP_FOREACH_KV(key, a2dp_capabilities, a2dp_endpoints, state) {
+ for (i = 0; i < pa_bluetooth_a2dp_codec_count(); i++) {
+ const pa_a2dp_codec *a2dp_codec;
- a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
+ a2dp_codec = pa_bluetooth_a2dp_codec_iter(i);
- if (memcmp(key, &a2dp_codec->id, sizeof(pa_a2dp_codec_id)) == 0) {
- if (a2dp_codec->can_be_supported(is_a2dp_sink)) {
- pa_json_encoder_begin_element_object(encoder);
+ if (memcmp(key, &a2dp_codec->id, sizeof(pa_a2dp_codec_id)) == 0) {
+ if (a2dp_codec->can_be_supported(is_a2dp_sink)) {
+ pa_json_encoder_begin_element_object(encoder);
- pa_json_encoder_add_member_string(encoder, "name", a2dp_codec->name);
- pa_json_encoder_add_member_string(encoder, "description", a2dp_codec->description);
+ pa_json_encoder_add_member_string(encoder, "name", a2dp_codec->name);
+ pa_json_encoder_add_member_string(encoder, "description", a2dp_codec->description);
- pa_json_encoder_end_object(encoder);
+ pa_json_encoder_end_object(encoder);
+ }
}
}
}
+ } else {
+ /* find out active codec selection from device profile */
+ for (i = 0; i < pa_bluetooth_hf_codec_count(); i++) {
+ const pa_a2dp_codec *hf_codec;
+
+ hf_codec = pa_bluetooth_hf_codec_iter(i);
+
+ if (true) {
+ pa_json_encoder_begin_element_object(encoder);
+
+ pa_json_encoder_add_member_string(encoder, "name", hf_codec->name);
+ pa_json_encoder_add_member_string(encoder, "description", hf_codec->description);
+
+ pa_json_encoder_end_object(encoder);
+ }
+ }
}
pa_json_encoder_end_array(encoder);
@@ -2428,13 +2446,15 @@ static int bluez5_device_message_handler(const char *object_path, const char *me
if (u->profile == PA_BLUETOOTH_PROFILE_OFF) {
pa_log_info("Bluetooth profile is off. Message cannot be handled.");
return -PA_ERR_INVALID;
- } else if (u->profile != PA_BLUETOOTH_PROFILE_A2DP_SINK &&
- u->profile != PA_BLUETOOTH_PROFILE_A2DP_SOURCE) {
- pa_log_info("Listing or switching codecs only allowed for A2DP sink or source");
- return -PA_ERR_INVALID;
}
if (pa_streq(message, "switch-codec")) {
+ if (u->profile != PA_BLUETOOTH_PROFILE_A2DP_SINK &&
+ u->profile != PA_BLUETOOTH_PROFILE_A2DP_SOURCE) {
+ pa_log_info("Switching codecs only allowed for A2DP sink or source");
+ return -PA_ERR_INVALID;
+ }
+
if (!parameters) {
pa_log_info("Codec switching operation requires codec name string parameter");
return -PA_ERR_INVALID;