drop unused patches

This commit is contained in:
Rex Dieter 2018-06-22 15:57:15 -05:00
parent 94bc24c033
commit 02110efee6
7 changed files with 0 additions and 1705 deletions

View File

@ -1,621 +0,0 @@
From patchwork Sun Oct 8 16:48:24 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v2,1/3] alsa-mixer: add hw_device_index to pa_alsa_mapping
From: Tanu Kaskinen <tanuk@iki.fi>
X-Patchwork-Id: 181163
Message-Id: <20171008164826.7588-2-tanuk@iki.fi>
To: pulseaudio-discuss@lists.freedesktop.org
Date: Sun, 8 Oct 2017 19:48:24 +0300
We have so far assumed that HDMI always uses device indexes 3, 7, 8, 9,
10, 11, 12 and 13. These values are hardcoded in the path configuration.
The Intel HDMI LPE driver, however, uses different device numbering
scheme. Since the indexes aren't always the same, we need to query the
hw device index from ALSA.
Later patches will use the queried index for HDMI jack detection and ELD
information reading.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488
---
src/modules/alsa/alsa-mixer.c | 26 ++++++++++++++++++++++++++
src/modules/alsa/alsa-mixer.h | 4 ++++
2 files changed, 30 insertions(+)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 7de1c7deb..02ab4a611 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -3505,6 +3505,7 @@ pa_alsa_mapping *pa_alsa_mapping_get(pa_alsa_profile_set *ps, const char *name)
pa_sample_spec_init(&m->sample_spec);
pa_channel_map_init(&m->channel_map);
m->proplist = pa_proplist_new();
+ m->hw_device_index = -1;
pa_hashmap_put(ps->mappings, m->name, m);
@@ -4532,6 +4533,25 @@ static int add_profiles_to_probe(
return i;
}
+static void mapping_query_hw_device(pa_alsa_mapping *mapping, snd_pcm_t *pcm) {
+ int r;
+ snd_pcm_info_t* pcm_info;
+ snd_pcm_info_alloca(&pcm_info);
+
+ r = snd_pcm_info(pcm, pcm_info);
+ if (r < 0) {
+ pa_log("Mapping %s: snd_pcm_info() failed %s: ", mapping->name, pa_alsa_strerror(r));
+ return;
+ }
+
+ /* XXX: It's not clear what snd_pcm_info_get_device() does if the device is
+ * not backed by a hw device or if it's backed by multiple hw devices. We
+ * only use hw_device_index for HDMI devices, however, and for those the
+ * return value is expected to be always valid, so this shouldn't be a
+ * significant problem. */
+ mapping->hw_device_index = snd_pcm_info_get_device(pcm_info);
+}
+
void pa_alsa_profile_set_probe(
pa_alsa_profile_set *ps,
const char *dev_id,
@@ -4622,6 +4642,9 @@ void pa_alsa_profile_set_probe(
}
break;
}
+
+ if (m->hw_device_index < 0)
+ mapping_query_hw_device(m, m->output_pcm);
}
if (p->input_mappings && p->supported)
@@ -4643,6 +4666,9 @@ void pa_alsa_profile_set_probe(
}
break;
}
+
+ if (m->hw_device_index < 0)
+ mapping_query_hw_device(m, m->input_pcm);
}
last = p;
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 4ebf1922b..cb482906b 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -275,6 +275,10 @@ struct pa_alsa_mapping {
bool exact_channels:1;
bool fallback:1;
+ /* The "y" in "hw:x,y". This is set to -1 before the device index has been
+ * queried, or if the query failed. */
+ int hw_device_index;
+
/* Temporarily used during probing */
snd_pcm_t *input_pcm;
snd_pcm_t *output_pcm;
From patchwork Sun Oct 8 16:48:25 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v2,2/3] alsa-mixer: autodetect the HDMI jack PCM device
From: Tanu Kaskinen <tanuk@iki.fi>
X-Patchwork-Id: 181164
Message-Id: <20171008164826.7588-3-tanuk@iki.fi>
To: pulseaudio-discuss@lists.freedesktop.org
Date: Sun, 8 Oct 2017 19:48:25 +0300
This removes the need to hardcode the PCM device index in the HDMI jack
names. The hardcoded values don't work with the Intel HDMI LPE driver.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488
---
src/modules/alsa/alsa-mixer.c | 53 ++++++++++++++++++++--
src/modules/alsa/alsa-mixer.h | 4 +-
src/modules/alsa/alsa-sink.c | 2 +-
src/modules/alsa/alsa-source.c | 2 +-
.../alsa/mixer/paths/analog-output.conf.common | 4 ++
src/modules/alsa/mixer/paths/hdmi-output-0.conf | 3 +-
src/modules/alsa/mixer/paths/hdmi-output-1.conf | 3 +-
src/modules/alsa/mixer/paths/hdmi-output-2.conf | 3 +-
src/modules/alsa/mixer/paths/hdmi-output-3.conf | 3 +-
src/modules/alsa/mixer/paths/hdmi-output-4.conf | 3 +-
src/modules/alsa/mixer/paths/hdmi-output-5.conf | 3 +-
src/modules/alsa/mixer/paths/hdmi-output-6.conf | 3 +-
src/modules/alsa/mixer/paths/hdmi-output-7.conf | 3 +-
13 files changed, 73 insertions(+), 16 deletions(-)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index 02ab4a611..eaee7ea0a 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -1812,12 +1812,31 @@ static int element_probe(pa_alsa_element *e, snd_mixer_t *m) {
return 0;
}
-static int jack_probe(pa_alsa_jack *j, snd_mixer_t *m) {
+static int jack_probe(pa_alsa_jack *j, pa_alsa_mapping *mapping, snd_mixer_t *m) {
bool has_control;
pa_assert(j);
pa_assert(j->path);
+ if (j->append_pcm_to_name) {
+ char *new_name;
+
+ if (!mapping) {
+ /* This could also be an assertion, because this should never
+ * happen. At the time of writing, mapping can only be NULL when
+ * module-alsa-sink/source synthesizes a path, and those
+ * synthesized paths never have any jacks, so jack_probe() should
+ * never be called with a NULL mapping. */
+ pa_log("Jack %s: append_pcm_to_name is set, but mapping is NULL. Can't use this jack.", j->name);
+ return -1;
+ }
+
+ new_name = pa_sprintf_malloc("%s,pcm=%i Jack", j->name, mapping->hw_device_index);
+ pa_xfree(j->alsa_name);
+ j->alsa_name = new_name;
+ j->append_pcm_to_name = false;
+ }
+
has_control = pa_alsa_mixer_find(m, j->alsa_name, 0) != NULL;
pa_alsa_jack_set_has_control(j, has_control);
@@ -2326,6 +2345,30 @@ static int jack_parse_state(pa_config_parser_state *state) {
return 0;
}
+static int jack_parse_append_pcm_to_name(pa_config_parser_state *state) {
+ pa_alsa_path *path;
+ pa_alsa_jack *jack;
+ int b;
+
+ pa_assert(state);
+
+ path = state->userdata;
+ if (!(jack = jack_get(path, state->section))) {
+ pa_log("[%s:%u] Option 'append_pcm_to_name' not expected in section '%s'",
+ state->filename, state->lineno, state->section);
+ return -1;
+ }
+
+ b = pa_parse_boolean(state->rvalue);
+ if (b < 0) {
+ pa_log("[%s:%u] Invalid value for 'append_pcm_to_name': %s", state->filename, state->lineno, state->rvalue);
+ return -1;
+ }
+
+ jack->append_pcm_to_name = b;
+ return 0;
+}
+
static int element_set_option(pa_alsa_element *e, snd_mixer_t *m, int alsa_idx) {
snd_mixer_selem_id_t *sid;
snd_mixer_elem_t *me;
@@ -2534,6 +2577,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
/* [Jack ...] */
{ "state.plugged", jack_parse_state, NULL, NULL },
{ "state.unplugged", jack_parse_state, NULL, NULL },
+ { "append-pcm-to-name", jack_parse_append_pcm_to_name, NULL, NULL },
/* [Element ...] */
{ "switch", element_parse_switch, NULL, NULL },
@@ -2746,7 +2790,7 @@ static void path_create_settings(pa_alsa_path *p) {
element_create_settings(p->elements, NULL);
}
-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB) {
+int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB) {
pa_alsa_element *e;
pa_alsa_jack *j;
double min_dB[PA_CHANNEL_POSITION_MAX], max_dB[PA_CHANNEL_POSITION_MAX];
@@ -2766,7 +2810,7 @@ int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB) {
pa_log_debug("Probing path '%s'", p->name);
PA_LLIST_FOREACH(j, p->jacks) {
- if (jack_probe(j, m) < 0) {
+ if (jack_probe(j, mapping, m) < 0) {
p->supported = false;
pa_log_debug("Probe of jack '%s' failed.", j->alsa_name);
return -1;
@@ -3968,9 +4012,8 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
}
PA_HASHMAP_FOREACH(p, ps->paths, state) {
- if (pa_alsa_path_probe(p, mixer_handle, m->profile_set->ignore_dB) < 0) {
+ if (pa_alsa_path_probe(p, m, mixer_handle, m->profile_set->ignore_dB) < 0)
pa_hashmap_remove(ps->paths, p);
- }
}
path_set_condense(ps, mixer_handle);
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index cb482906b..7ae40511c 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -171,6 +171,8 @@ struct pa_alsa_jack {
pa_dynarray *ucm_devices; /* pa_alsa_ucm_device */
pa_dynarray *ucm_hw_mute_devices; /* pa_alsa_ucm_device */
+
+ bool append_pcm_to_name;
};
pa_alsa_jack *pa_alsa_jack_new(pa_alsa_path *path, const char *name);
@@ -234,7 +236,7 @@ void pa_alsa_element_dump(pa_alsa_element *e);
pa_alsa_path *pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa_direction_t direction);
pa_alsa_path *pa_alsa_path_synthesize(const char *element, pa_alsa_direction_t direction);
-int pa_alsa_path_probe(pa_alsa_path *p, snd_mixer_t *m, bool ignore_dB);
+int pa_alsa_path_probe(pa_alsa_path *p, pa_alsa_mapping *mapping, snd_mixer_t *m, bool ignore_dB);
void pa_alsa_path_dump(pa_alsa_path *p);
int pa_alsa_path_get_volume(pa_alsa_path *p, snd_mixer_t *m, const pa_channel_map *cm, pa_cvolume *v);
int pa_alsa_path_get_mute(pa_alsa_path *path, snd_mixer_t *m, bool *muted);
diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 827a65081..99ca5061b 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -1912,7 +1912,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_OUTPUT)))
goto fail;
- if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0)
+ if (pa_alsa_path_probe(u->mixer_path, NULL, u->mixer_handle, ignore_dB) < 0)
goto fail;
pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
diff --git a/src/modules/alsa/alsa-source.c b/src/modules/alsa/alsa-source.c
index 6bec188ea..84abbf1d9 100644
--- a/src/modules/alsa/alsa-source.c
+++ b/src/modules/alsa/alsa-source.c
@@ -1615,7 +1615,7 @@ static void find_mixer(struct userdata *u, pa_alsa_mapping *mapping, const char
if (!(u->mixer_path = pa_alsa_path_synthesize(element, PA_ALSA_DIRECTION_INPUT)))
goto fail;
- if (pa_alsa_path_probe(u->mixer_path, u->mixer_handle, ignore_dB) < 0)
+ if (pa_alsa_path_probe(u->mixer_path, NULL, u->mixer_handle, ignore_dB) < 0)
goto fail;
pa_log_debug("Probed mixer path %s:", u->mixer_path->name);
diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common
index 17b45278a..baf37660e 100644
--- a/src/modules/alsa/mixer/paths/analog-output.conf.common
+++ b/src/modules/alsa/mixer/paths/analog-output.conf.common
@@ -122,6 +122,10 @@
; # the required-any are present.
; state.plugged = yes | no | unknown # Normally a plugged jack would mean the port becomes available, and an unplugged means it's
; state.unplugged = yes | no | unknown # unavailable, but the port status can be overridden by specifying state.plugged and/or state.unplugged.
+; append-pcm-to-name = no | yes # Add ",pcm=N" to the jack name? N is the hw PCM device index. HDMI jacks have
+; # the PCM device index in their name, but different drivers use different
+; # numbering schemes, so we can't hardcode the full jack name in our configuration
+; # files.
[Element PCM]
switch = mute
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-0.conf b/src/modules/alsa/mixer/paths/hdmi-output-0.conf
index 331014709..a87205cea 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-0.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-0.conf
@@ -6,5 +6,6 @@ eld-device = 3
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=3]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-1.conf b/src/modules/alsa/mixer/paths/hdmi-output-1.conf
index d81ee789c..b513ffd70 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-1.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-1.conf
@@ -6,5 +6,6 @@ eld-device = 7
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=7]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-2.conf b/src/modules/alsa/mixer/paths/hdmi-output-2.conf
index 349812fc2..a2386650e 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-2.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-2.conf
@@ -6,5 +6,6 @@ eld-device = 8
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=8]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-3.conf b/src/modules/alsa/mixer/paths/hdmi-output-3.conf
index 81463c946..edceb36e1 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-3.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-3.conf
@@ -6,5 +6,6 @@ eld-device = 9
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=9]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-4.conf b/src/modules/alsa/mixer/paths/hdmi-output-4.conf
index d61ec7547..0d1401eef 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-4.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-4.conf
@@ -6,5 +6,6 @@ eld-device = 10
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=10]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-5.conf b/src/modules/alsa/mixer/paths/hdmi-output-5.conf
index 02c15e893..883cccc20 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-5.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-5.conf
@@ -6,5 +6,6 @@ eld-device = 11
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=11]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-6.conf b/src/modules/alsa/mixer/paths/hdmi-output-6.conf
index 188a1adb3..d8ac2f55c 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-6.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-6.conf
@@ -6,5 +6,6 @@ eld-device = 12
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=12]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-7.conf b/src/modules/alsa/mixer/paths/hdmi-output-7.conf
index 80f4e3722..dd090855f 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-7.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-7.conf
@@ -6,5 +6,6 @@ eld-device = 13
[Properties]
device.icon_name = video-display
-[Jack HDMI/DP,pcm=13]
+[Jack HDMI/DP]
+append-pcm-to-name = yes
required = ignore
From patchwork Sun Oct 8 16:48:26 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [v2,3/3] alsa-mixer: autodetect the ELD device
From: Tanu Kaskinen <tanuk@iki.fi>
X-Patchwork-Id: 181165
Message-Id: <20171008164826.7588-4-tanuk@iki.fi>
To: pulseaudio-discuss@lists.freedesktop.org
Date: Sun, 8 Oct 2017 19:48:26 +0300
This removes the need to hardcode the ELD device index in the path
configuration. The hardcoded values don't work with the Intel HDMI LPE
driver.
BugLink: https://bugs.freedesktop.org/show_bug.cgi?id=100488
---
src/modules/alsa/alsa-mixer.c | 28 ++++++++++++++++++++--
src/modules/alsa/alsa-mixer.h | 1 +
.../alsa/mixer/paths/analog-output.conf.common | 8 +++++--
src/modules/alsa/mixer/paths/hdmi-output-0.conf | 2 +-
src/modules/alsa/mixer/paths/hdmi-output-1.conf | 2 +-
src/modules/alsa/mixer/paths/hdmi-output-2.conf | 2 +-
src/modules/alsa/mixer/paths/hdmi-output-3.conf | 2 +-
src/modules/alsa/mixer/paths/hdmi-output-4.conf | 2 +-
src/modules/alsa/mixer/paths/hdmi-output-5.conf | 2 +-
src/modules/alsa/mixer/paths/hdmi-output-6.conf | 2 +-
src/modules/alsa/mixer/paths/hdmi-output-7.conf | 2 +-
11 files changed, 41 insertions(+), 12 deletions(-)
diff --git a/src/modules/alsa/alsa-mixer.c b/src/modules/alsa/alsa-mixer.c
index eaee7ea0a..a524d6d64 100644
--- a/src/modules/alsa/alsa-mixer.c
+++ b/src/modules/alsa/alsa-mixer.c
@@ -2051,6 +2051,28 @@ static int element_parse_enumeration(pa_config_parser_state *state) {
return 0;
}
+static int parse_eld_device(pa_config_parser_state *state) {
+ pa_alsa_path *path;
+ uint32_t eld_device;
+
+ path = state->userdata;
+
+ if (pa_atou(state->rvalue, &eld_device) >= 0) {
+ path->autodetect_eld_device = false;
+ path->eld_device = eld_device;
+ return 0;
+ }
+
+ if (pa_streq(state->rvalue, "auto")) {
+ path->autodetect_eld_device = true;
+ path->eld_device = -1;
+ return 0;
+ }
+
+ pa_log("[%s:%u] Invalid value for option 'eld-device': %s", state->filename, state->lineno, state->rvalue);
+ return -1;
+}
+
static int option_parse_priority(pa_config_parser_state *state) {
pa_alsa_path *p;
pa_alsa_option *o;
@@ -2568,7 +2590,7 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
{ "description-key", pa_config_parse_string, NULL, "General" },
{ "description", pa_config_parse_string, NULL, "General" },
{ "mute-during-activation", pa_config_parse_bool, NULL, "General" },
- { "eld-device", pa_config_parse_int, NULL, "General" },
+ { "eld-device", parse_eld_device, NULL, "General" },
/* [Option ...] */
{ "priority", option_parse_priority, NULL, NULL },
@@ -2608,7 +2630,6 @@ pa_alsa_path* pa_alsa_path_new(const char *paths_dir, const char *fname, pa_alsa
items[1].data = &p->description_key;
items[2].data = &p->description;
items[3].data = &mute_during_activation;
- items[4].data = &p->eld_device;
if (!paths_dir)
paths_dir = get_default_paths_dir();
@@ -4012,6 +4033,9 @@ static void mapping_paths_probe(pa_alsa_mapping *m, pa_alsa_profile *profile,
}
PA_HASHMAP_FOREACH(p, ps->paths, state) {
+ if (p->autodetect_eld_device)
+ p->eld_device = m->hw_device_index;
+
if (pa_alsa_path_probe(p, m, mixer_handle, m->profile_set->ignore_dB) < 0)
pa_hashmap_remove(ps->paths, p);
}
diff --git a/src/modules/alsa/alsa-mixer.h b/src/modules/alsa/alsa-mixer.h
index 7ae40511c..15615a615 100644
--- a/src/modules/alsa/alsa-mixer.h
+++ b/src/modules/alsa/alsa-mixer.h
@@ -193,6 +193,7 @@ struct pa_alsa_path {
char *description_key;
char *description;
unsigned priority;
+ bool autodetect_eld_device;
int eld_device;
pa_proplist *proplist;
diff --git a/src/modules/alsa/mixer/paths/analog-output.conf.common b/src/modules/alsa/mixer/paths/analog-output.conf.common
index baf37660e..e52830d99 100644
--- a/src/modules/alsa/mixer/paths/analog-output.conf.common
+++ b/src/modules/alsa/mixer/paths/analog-output.conf.common
@@ -64,8 +64,12 @@
; mute-during-activation = yes | no # If this path supports hardware mute, should the hw mute be used while activating this
; # path? In some cases this can reduce extra noises during port switching, while in other
; # cases this can increase such noises. Default: no.
-; eld-device = ... # If this is an HDMI port, here's where to specify the device number for the ELD mixer
-; # control. The default is to not make use of ELD information.
+; eld-device = ... # If this is an HDMI port, set to "auto" so that PulseAudio will try to read
+; # the monitor ELD information from the ALSA mixer. By default the ELD information
+; # is not read, because it's only applicable with HDMI. Earlier the "auto" option
+; # didn't exist, and the hw device index had to be manually configured. For
+; # backwards compatibility, it's still possible to manually configure the device
+; # index using this option.
;
; [Properties] # Property list for this path. The list is merged into the port property list.
; <key> = <value> # Each property is defined on its own line.
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-0.conf b/src/modules/alsa/mixer/paths/hdmi-output-0.conf
index a87205cea..95b1342e9 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-0.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-0.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort
priority = 59
-eld-device = 3
+eld-device = auto
[Properties]
device.icon_name = video-display
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-1.conf b/src/modules/alsa/mixer/paths/hdmi-output-1.conf
index b513ffd70..37b945204 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-1.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-1.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort 2
priority = 58
-eld-device = 7
+eld-device = auto
[Properties]
device.icon_name = video-display
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-2.conf b/src/modules/alsa/mixer/paths/hdmi-output-2.conf
index a2386650e..19c38f2e8 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-2.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-2.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort 3
priority = 57
-eld-device = 8
+eld-device = auto
[Properties]
device.icon_name = video-display
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-3.conf b/src/modules/alsa/mixer/paths/hdmi-output-3.conf
index edceb36e1..8551570ac 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-3.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-3.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort 4
priority = 56
-eld-device = 9
+eld-device = auto
[Properties]
device.icon_name = video-display
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-4.conf b/src/modules/alsa/mixer/paths/hdmi-output-4.conf
index 0d1401eef..e36128921 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-4.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-4.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort 5
priority = 55
-eld-device = 10
+eld-device = auto
[Properties]
device.icon_name = video-display
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-5.conf b/src/modules/alsa/mixer/paths/hdmi-output-5.conf
index 883cccc20..82dc3be79 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-5.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-5.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort 6
priority = 54
-eld-device = 11
+eld-device = auto
[Properties]
device.icon_name = video-display
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-6.conf b/src/modules/alsa/mixer/paths/hdmi-output-6.conf
index d8ac2f55c..92e8fd1e2 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-6.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-6.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort 7
priority = 53
-eld-device = 12
+eld-device = auto
[Properties]
device.icon_name = video-display
diff --git a/src/modules/alsa/mixer/paths/hdmi-output-7.conf b/src/modules/alsa/mixer/paths/hdmi-output-7.conf
index dd090855f..abe2b60e6 100644
--- a/src/modules/alsa/mixer/paths/hdmi-output-7.conf
+++ b/src/modules/alsa/mixer/paths/hdmi-output-7.conf
@@ -1,7 +1,7 @@
[General]
description = HDMI / DisplayPort 8
priority = 52
-eld-device = 13
+eld-device = auto
[Properties]
device.icon_name = video-display

View File

@ -1,62 +0,0 @@
From patchwork Wed Nov 8 12:20:22 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [1/2] card-restore: log the correct profile name
From: Tanu Kaskinen <tanuk@iki.fi>
X-Patchwork-Id: 187101
Message-Id: <20171108122023.8147-2-tanuk@iki.fi>
To: pulseaudio-discuss@lists.freedesktop.org
Date: Wed, 8 Nov 2017 14:20:22 +0200
---
src/modules/module-card-restore.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index 3c0307bee..2d3a91c01 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -561,7 +561,7 @@ static pa_hook_result_t card_choose_initial_profile_callback(pa_core *core, pa_c
profile = pa_hashmap_get(card->profiles, e->profile);
if (profile) {
- pa_log_info("Restoring profile '%s' for card %s.", card->active_profile->name, card->name);
+ pa_log_info("Restoring profile '%s' for card %s.", profile->name, card->name);
pa_card_set_profile(card, profile, true);
} else {
pa_log_debug("Tried to restore profile %s for card %s, but the card doesn't have such profile.",
From patchwork Wed Nov 8 12:20:23 2017
Content-Type: text/plain; charset="utf-8"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Subject: [2/2] card-restore: don't restore unavailable profiles
From: Tanu Kaskinen <tanuk@iki.fi>
X-Patchwork-Id: 187102
Message-Id: <20171108122023.8147-3-tanuk@iki.fi>
To: pulseaudio-discuss@lists.freedesktop.org
Date: Wed, 8 Nov 2017 14:20:23 +0200
---
src/modules/module-card-restore.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/src/modules/module-card-restore.c b/src/modules/module-card-restore.c
index 2d3a91c01..b7189ad53 100644
--- a/src/modules/module-card-restore.c
+++ b/src/modules/module-card-restore.c
@@ -561,8 +561,12 @@ static pa_hook_result_t card_choose_initial_profile_callback(pa_core *core, pa_c
profile = pa_hashmap_get(card->profiles, e->profile);
if (profile) {
- pa_log_info("Restoring profile '%s' for card %s.", profile->name, card->name);
- pa_card_set_profile(card, profile, true);
+ if (profile->available != PA_AVAILABLE_NO) {
+ pa_log_info("Restoring profile '%s' for card %s.", profile->name, card->name);
+ pa_card_set_profile(card, profile, true);
+ } else
+ pa_log_debug("Not restoring profile %s for card %s, because the profile is currently unavailable.",
+ profile->name, card->name);
} else {
pa_log_debug("Tried to restore profile %s for card %s, but the card doesn't have such profile.",
e->profile, card->name);

View File

@ -73,11 +73,6 @@ Patch206: pulseaudio-11.1-autospawn_disable.patch
## upstream patches
## upstreamable patches
# patchset from https://bugs.freedesktop.org/show_bug.cgi?id=93898
Patch101: v5-1-4-bluetooth-use-consistent-profile-names.patch
Patch102: v5-2-4-bluetooth-separate-HSP-and-HFP.patch
Patch103: v5-3-4-bluetooth-add-correct-HFP-rfcomm-negotiation.patch
Patch104: v5-4-4-bluetooth-make-native-the-default-backend.patch
BuildRequires: automake libtool
BuildRequires: gcc-c++
@ -279,15 +274,6 @@ This package contains GDM integration hooks for the PulseAudio sound server.
## upstream patches
## upstreamable patches
# experimental, rawhide only
#if 0%{?fedora} > 28
## no longer applies cleanly, rebase or drop -- rex
%if 0
%patch101 -p1
%patch102 -p1
%patch103 -p1
%patch104 -p1
%endif
%patch201 -p1 -b .autostart
%patch202 -p1 -b .disable_flat_volumes

View File

@ -1,380 +0,0 @@
diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index 0f0104d8..f2009bfd 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -449,7 +449,7 @@ static void set_speaker_gain(pa_bluetooth_transport *t, uint16_t gain) {
/* If we are in the AG role, we send a command to the head set to change
* the speaker gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the microphone gain has changed */
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT) {
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS) {
len = sprintf(buf, "\r\n+VGS=%d\r\n", gain);
pa_log_debug("RFCOMM >> +VGS=%d", gain);
} else {
@@ -476,7 +476,7 @@ static void set_microphone_gain(pa_bluetooth_transport *t, uint16_t gain) {
/* If we are in the AG role, we send a command to the head set to change
* the microphone gain. In the HS role, source and sink are swapped, so
* in this case we notify the AG that the speaker gain has changed */
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT) {
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS) {
len = sprintf(buf, "\r\n+VGM=%d\r\n", gain);
pa_log_debug("RFCOMM >> +VGM=%d", gain);
} else {
@@ -509,9 +509,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m,
handler = dbus_message_get_path(m);
if (pa_streq(handler, HSP_AG_PROFILE)) {
- p = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+ p = PA_BLUETOOTH_PROFILE_HSP_HS;
} else if (pa_streq(handler, HSP_HS_PROFILE)) {
- p = PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY;
+ p = PA_BLUETOOTH_PROFILE_HFP_AG;
} else {
pa_log_error("Invalid handler");
goto fail;
@@ -626,11 +626,11 @@ static void profile_init(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile
pa_assert(b);
switch (profile) {
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
object_name = HSP_AG_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_AG;
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
object_name = HSP_HS_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_HS;
break;
@@ -647,10 +647,10 @@ static void profile_done(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile
pa_assert(b);
switch (profile) {
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_AG_PROFILE);
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_HS_PROFILE);
break;
default:
@@ -665,9 +665,9 @@ void pa_bluetooth_native_backend_enable_hs_role(pa_bluetooth_backend *native_bac
return;
if (enable_hs_role)
- profile_init(native_backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ profile_init(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
else
- profile_done(native_backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ profile_done(native_backend, PA_BLUETOOTH_PROFILE_HFP_AG);
native_backend->enable_hs_role = enable_hs_role;
}
@@ -693,8 +693,8 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
backend->enable_hs_role = enable_hs_role;
if (enable_hs_role)
- profile_init(backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
- profile_init(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+ profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
return backend;
}
@@ -705,8 +705,8 @@ void pa_bluetooth_native_backend_free(pa_bluetooth_backend *backend) {
pa_dbus_free_pending_list(&backend->pending);
if (backend->enable_hs_role)
- profile_done(backend, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
- profile_done(backend, PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT);
+ profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
+ profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
pa_dbus_connection_unref(backend->connection);
diff --git a/src/modules/bluetooth/backend-ofono.c b/src/modules/bluetooth/backend-ofono.c
index 2c51497f..85b9c477 100644
--- a/src/modules/bluetooth/backend-ofono.c
+++ b/src/modules/bluetooth/backend-ofono.c
@@ -223,7 +223,7 @@ static void hf_audio_agent_card_found(pa_bluetooth_backend *backend, const char
const char *key, *value;
struct hf_audio_card *card;
pa_bluetooth_device *d;
- pa_bluetooth_profile_t p = PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY;
+ pa_bluetooth_profile_t p = PA_BLUETOOTH_PROFILE_HFP_AG;
pa_assert(backend);
pa_assert(path);
@@ -257,7 +257,7 @@ static void hf_audio_agent_card_found(pa_bluetooth_backend *backend, const char
card->local_address = pa_xstrdup(value);
} else if (pa_streq(key, "Type")) {
if (pa_streq(value, "gateway"))
- p = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+ p = PA_BLUETOOTH_PROFILE_HSP_HS;
}
pa_log_debug("%s: %s", key, value);
diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
index c9283232..4470f2ef 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -174,11 +174,11 @@ static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_pr
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK);
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE);
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
case PA_BLUETOOTH_PROFILE_OFF:
@@ -1018,7 +1018,7 @@ void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is
pa_bluetooth_device *d;
PA_HASHMAP_FOREACH(d, y->devices, state) {
- if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)) {
+ if (device_supports_profile(d, PA_BLUETOOTH_PROFILE_HFP_AG)) {
DBusMessage *m;
pa_assert_se(m = dbus_message_new_method_call(BLUEZ_SERVICE, d->path, "org.bluez.Device1", "Disconnect"));
@@ -1304,9 +1304,9 @@ const char *pa_bluetooth_profile_to_string(pa_bluetooth_profile_t profile) {
return "a2dp_sink";
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
return "a2dp_source";
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
return "headset_head_unit";
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
return "headset_audio_gateway";
case PA_BLUETOOTH_PROFILE_OFF:
return "off";
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index a3e7bf3d..84c0c3f1 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -46,8 +46,8 @@ typedef enum pa_bluetooth_hook {
typedef enum profile {
PA_BLUETOOTH_PROFILE_A2DP_SINK,
PA_BLUETOOTH_PROFILE_A2DP_SOURCE,
- PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT,
- PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY,
+ PA_BLUETOOTH_PROFILE_HSP_HS,
+ PA_BLUETOOTH_PROFILE_HFP_AG,
PA_BLUETOOTH_PROFILE_OFF
} pa_bluetooth_profile_t;
#define PA_BLUETOOTH_PROFILE_COUNT PA_BLUETOOTH_PROFILE_OFF
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index 530207a2..d076fbad 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -257,8 +257,8 @@ static int sco_process_render(struct userdata *u) {
pa_memchunk memchunk;
pa_assert(u);
- pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
- u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->sink);
pa_sink_render_full(u->sink, u->write_block_size, &memchunk);
@@ -317,8 +317,8 @@ static int sco_process_push(struct userdata *u) {
pa_usec_t tstamp = 0;
pa_assert(u);
- pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT ||
- u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY);
+ pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->source);
pa_assert(u->read_smoother);
@@ -784,7 +784,7 @@ static void transport_release(struct userdata *u) {
/* Run from I/O thread */
static void transport_config_mtu(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->read_block_size = u->read_link_mtu;
u->write_block_size = u->write_link_mtu;
@@ -981,7 +981,7 @@ static void source_set_volume_cb(pa_source *s) {
pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
/* Set soft volume when in headset role */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
pa_cvolume_set(&s->soft_volume, u->sample_spec.channels, volume);
/* If we are in the AG role, we send a command to the head set to change
@@ -1004,7 +1004,7 @@ static int add_source(struct userdata *u) {
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_INPUT);
@@ -1012,10 +1012,10 @@ static int add_source(struct userdata *u) {
if (!u->transport_acquired)
switch (u->profile) {
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
data.suspend_cause = PA_SUSPEND_USER;
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1039,7 +1039,7 @@ static int add_source(struct userdata *u) {
u->source->parent.process_msg = source_process_msg;
u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
u->source->n_volume_steps = 16;
}
@@ -1151,7 +1151,7 @@ static void sink_set_volume_cb(pa_sink *s) {
pa_cvolume_set(&s->real_volume, u->sample_spec.channels, volume);
/* Set soft volume when in headset role */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
pa_cvolume_set(&s->soft_volume, u->sample_spec.channels, volume);
/* If we are in the AG role, we send a command to the head set to change
@@ -1174,17 +1174,17 @@ static int add_sink(struct userdata *u) {
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_OUTPUT);
if (!u->transport_acquired)
switch (u->profile) {
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
data.suspend_cause = PA_SUSPEND_USER;
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1210,7 +1210,7 @@ static int add_sink(struct userdata *u) {
u->sink->parent.process_msg = sink_process_msg;
u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
u->sink->n_volume_steps = 16;
}
@@ -1219,7 +1219,7 @@ static int add_sink(struct userdata *u) {
/* Run from main thread */
static void transport_config(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->sample_spec.format = PA_SAMPLE_S16LE;
u->sample_spec.channels = 1;
u->sample_spec.rate = 8000;
@@ -1349,7 +1349,7 @@ static int setup_transport(struct userdata *u) {
u->transport = t;
- if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
transport_acquire(u, true); /* In case of error, the sink/sources will be created suspended */
else {
int transport_error;
@@ -1369,8 +1369,8 @@ static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
static const pa_direction_t profile_direction[] = {
[PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
- [PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
- [PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_HSP_HS] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_HFP_AG] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_OFF] = 0
};
@@ -1620,7 +1620,7 @@ static int start_thread(struct userdata *u) {
/* If we are in the headset role, the sink should not become default
* unless there is no other sound device available. */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG)
u->sink->priority = 1500;
pa_sink_put(u->sink);
@@ -1636,7 +1636,7 @@ static int start_thread(struct userdata *u) {
/* If we are in the headset role or the device is an a2dp source,
* the source should not become default unless there is no other
* sound device available. */
- if (u->profile == PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY || u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HFP_AG || u->profile == PA_BLUETOOTH_PROFILE_A2DP_SOURCE)
u->source->priority = 1500;
pa_source_put(u->source);
@@ -1873,7 +1873,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, pa_bluetooth_pro
p = PA_CARD_PROFILE_DATA(cp);
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT:
+ case PA_BLUETOOTH_PROFILE_HSP_HS:
cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30;
cp->n_sinks = 1;
@@ -1886,7 +1886,7 @@ static pa_card_profile *create_card_profile(struct userdata *u, pa_bluetooth_pro
p = PA_CARD_PROFILE_DATA(cp);
break;
- case PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY:
+ case PA_BLUETOOTH_PROFILE_HFP_AG:
cp = pa_card_profile_new(name, _("Headset Audio Gateway (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 10;
cp->n_sinks = 1;
@@ -1961,9 +1961,9 @@ static int uuid_to_profile(const char *uuid, pa_bluetooth_profile_t *_r) {
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
*_r = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
else if (pa_bluetooth_uuid_is_hsp_hs(uuid) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF))
- *_r = PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT;
+ *_r = PA_BLUETOOTH_PROFILE_HSP_HS;
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_AG) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_AG))
- *_r = PA_BLUETOOTH_PROFILE_HEADSET_AUDIO_GATEWAY;
+ *_r = PA_BLUETOOTH_PROFILE_HFP_AG;
else
return -PA_ERR_INVALID;
@@ -2174,7 +2174,7 @@ static pa_hook_result_t transport_speaker_gain_changed_cb(pa_bluetooth_discovery
volume++;
pa_cvolume_set(&v, u->sample_spec.channels, volume);
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_sink_volume_changed(u->sink, &v);
else
pa_sink_set_volume(u->sink, &v, true, true);
@@ -2202,7 +2202,7 @@ static pa_hook_result_t transport_microphone_gain_changed_cb(pa_bluetooth_discov
pa_cvolume_set(&v, u->sample_spec.channels, volume);
- if (t->profile == PA_BLUETOOTH_PROFILE_HEADSET_HEAD_UNIT)
+ if (t->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
pa_source_volume_changed(u->source, &v);
else
pa_source_set_volume(u->source, &v, true, true);

View File

@ -1,397 +0,0 @@
diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index f2009bfd..9ec9244b 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -62,6 +62,7 @@ struct transport_data {
#define BLUEZ_PROFILE_INTERFACE BLUEZ_SERVICE ".Profile1"
#define HSP_AG_PROFILE "/Profile/HSPAGProfile"
+#define HFP_AG_PROFILE "/Profile/HFPAGProfile"
#define HSP_HS_PROFILE "/Profile/HSPHSProfile"
/* RFCOMM channel for HSP headset role
@@ -512,6 +513,8 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m,
p = PA_BLUETOOTH_PROFILE_HSP_HS;
} else if (pa_streq(handler, HSP_HS_PROFILE)) {
p = PA_BLUETOOTH_PROFILE_HFP_AG;
+ } else if (pa_streq(handler, HFP_AG_PROFILE)) {
+ p = PA_BLUETOOTH_PROFILE_HFP_HF;
} else {
pa_log_error("Invalid handler");
goto fail;
@@ -589,7 +592,8 @@ static DBusHandlerResult profile_handler(DBusConnection *c, DBusMessage *m, void
pa_log_debug("dbus: path=%s, interface=%s, member=%s", path, interface, member);
- if (!pa_streq(path, HSP_AG_PROFILE) && !pa_streq(path, HSP_HS_PROFILE))
+ if (!pa_streq(path, HSP_AG_PROFILE) && !pa_streq(path, HSP_HS_PROFILE)
+ && !pa_streq(path, HFP_AG_PROFILE))
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
if (dbus_message_is_method_call(m, "org.freedesktop.DBus.Introspectable", "Introspect")) {
@@ -634,6 +638,10 @@ static void profile_init(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile
object_name = HSP_HS_PROFILE;
uuid = PA_BLUETOOTH_UUID_HSP_HS;
break;
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ object_name = HFP_AG_PROFILE;
+ uuid = PA_BLUETOOTH_UUID_HFP_AG;
+ break;
default:
pa_assert_not_reached();
break;
@@ -653,6 +661,9 @@ static void profile_done(pa_bluetooth_backend *b, pa_bluetooth_profile_t profile
case PA_BLUETOOTH_PROFILE_HFP_AG:
dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HSP_HS_PROFILE);
break;
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ dbus_connection_unregister_object_path(pa_dbus_connection_get(b->connection), HFP_AG_PROFILE);
+ break;
default:
pa_assert_not_reached();
break;
@@ -695,6 +706,8 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
if (enable_hs_role)
profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
+ if (pa_bluetooth_discovery_get_enable_native_hfp_hf(y))
+ profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
return backend;
}
@@ -707,6 +720,8 @@ void pa_bluetooth_native_backend_free(pa_bluetooth_backend *backend) {
if (backend->enable_hs_role)
profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_AG);
profile_done(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
+ if (pa_bluetooth_discovery_get_enable_native_hfp_hf(backend->discovery))
+ profile_done(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
pa_dbus_connection_unref(backend->connection);
diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
index 4470f2ef..80a025d5 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -92,6 +92,7 @@ struct pa_bluetooth_discovery {
int headset_backend;
pa_bluetooth_backend *ofono_backend, *native_backend;
PA_LLIST_HEAD(pa_dbus_pending, pending);
+ bool enable_native_hfp_hf;
};
static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_discovery *y, DBusMessage *m,
@@ -169,15 +170,29 @@ static const char *transport_state_to_string(pa_bluetooth_transport_state_t stat
}
static bool device_supports_profile(pa_bluetooth_device *device, pa_bluetooth_profile_t profile) {
+ bool show_hfp, show_hsp, enable_native_hfp_hf;
+
+ enable_native_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(device->discovery);
+
+ if (enable_native_hfp_hf) {
+ show_hfp = pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
+ show_hsp = !show_hfp;
+ } else {
+ show_hfp = false;
+ show_hsp = true;
+ }
+
switch (profile) {
case PA_BLUETOOTH_PROFILE_A2DP_SINK:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SINK);
case PA_BLUETOOTH_PROFILE_A2DP_SOURCE:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_A2DP_SOURCE);
case PA_BLUETOOTH_PROFILE_HSP_HS:
- return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
- || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT)
- || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
+ return show_hsp && (
+ !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS)
+ || !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_HS_ALT));
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ return show_hfp && !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_HF);
case PA_BLUETOOTH_PROFILE_HFP_AG:
return !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HSP_AG)
|| !!pa_hashmap_get(device->uuids, PA_BLUETOOTH_UUID_HFP_AG);
@@ -536,6 +550,14 @@ pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_path(pa_bluetooth_disc
return NULL;
}
+bool pa_bluetooth_discovery_get_enable_native_hfp_hf(pa_bluetooth_discovery *y)
+{
+ pa_assert(y);
+ pa_assert(PA_REFCNT_VALUE(y) > 0);
+
+ return y->enable_native_hfp_hf;
+}
+
pa_bluetooth_device* pa_bluetooth_discovery_get_device_by_address(pa_bluetooth_discovery *y, const char *remote, const char *local) {
pa_bluetooth_device *d;
void *state = NULL;
@@ -1306,6 +1328,8 @@ const char *pa_bluetooth_profile_to_string(pa_bluetooth_profile_t profile) {
return "a2dp_source";
case PA_BLUETOOTH_PROFILE_HSP_HS:
return "headset_head_unit";
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ return "headset_handsfree";
case PA_BLUETOOTH_PROFILE_HFP_AG:
return "headset_audio_gateway";
case PA_BLUETOOTH_PROFILE_OFF:
@@ -1727,7 +1751,7 @@ static void endpoint_done(pa_bluetooth_discovery *y, pa_bluetooth_profile_t prof
}
}
-pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backend) {
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backend, bool enable_native_hfp_hf) {
pa_bluetooth_discovery *y;
DBusError err;
DBusConnection *conn;
@@ -1737,6 +1761,7 @@ pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *c, int headset_backe
PA_REFCNT_INIT(y);
y->core = c;
y->headset_backend = headset_backend;
+ y->enable_native_hfp_hf = enable_native_hfp_hf;
y->adapters = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
(pa_free_cb_t) adapter_free);
y->devices = pa_hashmap_new_full(pa_idxset_string_hash_func, pa_idxset_string_compare_func, NULL,
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index 84c0c3f1..b077ca2c 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -47,6 +47,7 @@ typedef enum profile {
PA_BLUETOOTH_PROFILE_A2DP_SINK,
PA_BLUETOOTH_PROFILE_A2DP_SOURCE,
PA_BLUETOOTH_PROFILE_HSP_HS,
+ PA_BLUETOOTH_PROFILE_HFP_HF,
PA_BLUETOOTH_PROFILE_HFP_AG,
PA_BLUETOOTH_PROFILE_OFF
} pa_bluetooth_profile_t;
@@ -161,8 +162,9 @@ const char *pa_bluetooth_profile_to_string(pa_bluetooth_profile_t profile);
#define HEADSET_BACKEND_NATIVE 1
#define HEADSET_BACKEND_AUTO 2
-pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core, int headset_backend);
+pa_bluetooth_discovery* pa_bluetooth_discovery_get(pa_core *core, int headset_backend, bool default_profile_hfp);
pa_bluetooth_discovery* pa_bluetooth_discovery_ref(pa_bluetooth_discovery *y);
void pa_bluetooth_discovery_unref(pa_bluetooth_discovery *y);
void pa_bluetooth_discovery_set_ofono_running(pa_bluetooth_discovery *y, bool is_running);
+bool pa_bluetooth_discovery_get_enable_native_hfp_hf(pa_bluetooth_discovery *y);
#endif
diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c
index 316b9a82..b17c5d39 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -365,7 +365,8 @@ static pa_hook_result_t profile_available_hook_callback(pa_core *c, pa_card_prof
/* Do not automatically switch profiles for headsets, just in case */
/* TODO: remove a2dp and hsp when we remove BlueZ 4 support */
if (pa_streq(profile->name, "hsp") || pa_streq(profile->name, "a2dp") || pa_streq(profile->name, "a2dp_sink") ||
- pa_streq(profile->name, "headset_head_unit"))
+ pa_streq(profile->name, "headset_head_unit") ||
+ pa_streq(profile->name, "headset_handsfree"))
return PA_HOOK_OK;
is_active_profile = card->active_profile == profile;
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index d076fbad..d37ce9ce 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -258,6 +258,7 @@ static int sco_process_render(struct userdata *u) {
pa_assert(u);
pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_HF ||
u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->sink);
@@ -318,6 +319,7 @@ static int sco_process_push(struct userdata *u) {
pa_assert(u);
pa_assert(u->profile == PA_BLUETOOTH_PROFILE_HSP_HS ||
+ u->profile == PA_BLUETOOTH_PROFILE_HFP_HF||
u->profile == PA_BLUETOOTH_PROFILE_HFP_AG);
pa_assert(u->source);
pa_assert(u->read_smoother);
@@ -784,7 +786,9 @@ static void transport_release(struct userdata *u) {
/* Run from I/O thread */
static void transport_config_mtu(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->read_block_size = u->read_link_mtu;
u->write_block_size = u->write_link_mtu;
@@ -1004,7 +1008,8 @@ static int add_source(struct userdata *u) {
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_source_new_data_set_sample_spec(&data, &u->sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_INPUT);
@@ -1016,6 +1021,7 @@ static int add_source(struct userdata *u) {
data.suspend_cause = PA_SUSPEND_USER;
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1039,7 +1045,9 @@ static int add_source(struct userdata *u) {
u->source->parent.process_msg = source_process_msg;
u->source->set_state_in_io_thread = source_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
pa_source_set_set_volume_callback(u->source, source_set_volume_cb);
u->source->n_volume_steps = 16;
}
@@ -1174,7 +1182,8 @@ static int add_sink(struct userdata *u) {
data.namereg_fail = false;
pa_proplist_sets(data.proplist, "bluetooth.protocol", pa_bluetooth_profile_to_string(u->profile));
pa_sink_new_data_set_sample_spec(&data, &u->sample_spec);
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS)
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF)
pa_proplist_sets(data.proplist, PA_PROP_DEVICE_INTENDED_ROLES, "phone");
connect_ports(u, &data, PA_DIRECTION_OUTPUT);
@@ -1185,6 +1194,7 @@ static int add_sink(struct userdata *u) {
data.suspend_cause = PA_SUSPEND_USER;
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
/* u->stream_fd contains the error returned by the last transport_acquire()
* EAGAIN means we are waiting for a NewConnection signal */
if (u->stream_fd == -EAGAIN)
@@ -1210,7 +1220,9 @@ static int add_sink(struct userdata *u) {
u->sink->parent.process_msg = sink_process_msg;
u->sink->set_state_in_io_thread = sink_set_state_in_io_thread_cb;
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF) {
pa_sink_set_set_volume_callback(u->sink, sink_set_volume_cb);
u->sink->n_volume_steps = 16;
}
@@ -1219,7 +1231,9 @@ static int add_sink(struct userdata *u) {
/* Run from main thread */
static void transport_config(struct userdata *u) {
- if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
+ if (u->profile == PA_BLUETOOTH_PROFILE_HSP_HS
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_HF
+ || u->profile == PA_BLUETOOTH_PROFILE_HFP_AG) {
u->sample_spec.format = PA_SAMPLE_S16LE;
u->sample_spec.channels = 1;
u->sample_spec.rate = 8000;
@@ -1370,6 +1384,7 @@ static pa_direction_t get_profile_direction(pa_bluetooth_profile_t p) {
[PA_BLUETOOTH_PROFILE_A2DP_SINK] = PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_A2DP_SOURCE] = PA_DIRECTION_INPUT,
[PA_BLUETOOTH_PROFILE_HSP_HS] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
+ [PA_BLUETOOTH_PROFILE_HFP_HF] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_HFP_AG] = PA_DIRECTION_INPUT | PA_DIRECTION_OUTPUT,
[PA_BLUETOOTH_PROFILE_OFF] = 0
};
@@ -1874,7 +1889,20 @@ static pa_card_profile *create_card_profile(struct userdata *u, pa_bluetooth_pro
break;
case PA_BLUETOOTH_PROFILE_HSP_HS:
- cp = pa_card_profile_new(name, _("Headset Head Unit (HSP/HFP)"), sizeof(pa_bluetooth_profile_t));
+ cp = pa_card_profile_new(name, _("Headset Head Unit (HSP)"), sizeof(pa_bluetooth_profile_t));
+ cp->priority = 30;
+ cp->n_sinks = 1;
+ cp->n_sources = 1;
+ cp->max_sink_channels = 1;
+ cp->max_source_channels = 1;
+ pa_hashmap_put(input_port->profiles, cp->name, cp);
+ pa_hashmap_put(output_port->profiles, cp->name, cp);
+
+ p = PA_CARD_PROFILE_DATA(cp);
+ break;
+
+ case PA_BLUETOOTH_PROFILE_HFP_HF:
+ cp = pa_card_profile_new(name, _("Headset Handsfree (HFP)"), sizeof(pa_bluetooth_profile_t));
cp->priority = 30;
cp->n_sinks = 1;
cp->n_sources = 1;
@@ -1960,8 +1988,10 @@ static int uuid_to_profile(const char *uuid, pa_bluetooth_profile_t *_r) {
*_r = PA_BLUETOOTH_PROFILE_A2DP_SINK;
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_A2DP_SOURCE))
*_r = PA_BLUETOOTH_PROFILE_A2DP_SOURCE;
- else if (pa_bluetooth_uuid_is_hsp_hs(uuid) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF))
+ else if (pa_bluetooth_uuid_is_hsp_hs(uuid))
*_r = PA_BLUETOOTH_PROFILE_HSP_HS;
+ else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF))
+ *_r = PA_BLUETOOTH_PROFILE_HFP_HF;
else if (pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_AG) || pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_AG))
*_r = PA_BLUETOOTH_PROFILE_HFP_AG;
else
@@ -1980,6 +2010,7 @@ static int add_card(struct userdata *u) {
pa_bluetooth_profile_t *p;
const char *uuid;
void *state;
+ bool enable_native_hfp_hf, has_both;
pa_assert(u);
pa_assert(u->device);
@@ -2010,9 +2041,22 @@ static int add_card(struct userdata *u) {
create_card_ports(u, data.ports);
+ enable_native_hfp_hf = pa_bluetooth_discovery_get_enable_native_hfp_hf(u->discovery);
+
+ has_both = enable_native_hfp_hf && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HFP_HF) && pa_hashmap_get(d->uuids, PA_BLUETOOTH_UUID_HSP_HS);
PA_HASHMAP_FOREACH(uuid, d->uuids, state) {
pa_bluetooth_profile_t profile;
+ if (!enable_native_hfp_hf && pa_streq(uuid, PA_BLUETOOTH_UUID_HFP_HF)) {
+ pa_log_info("device supports HFP but disabling profile as requested");
+ continue;
+ }
+
+ if (has_both && pa_streq(uuid, PA_BLUETOOTH_UUID_HSP_HS)) {
+ pa_log_info("device support HSP and HFP, selecting HFP only");
+ continue;
+ }
+
if (uuid_to_profile(uuid, &profile) < 0)
continue;
diff --git a/src/modules/bluetooth/module-bluez5-discover.c b/src/modules/bluetooth/module-bluez5-discover.c
index c535ead4..bfb361ae 100644
--- a/src/modules/bluetooth/module-bluez5-discover.c
+++ b/src/modules/bluetooth/module-bluez5-discover.c
@@ -104,6 +104,7 @@ int pa__init(pa_module *m) {
const char *headset_str;
int headset_backend;
bool autodetect_mtu;
+ bool enable_native_hfp_hf = true;
pa_assert(m);
@@ -127,6 +128,9 @@ int pa__init(pa_module *m) {
autodetect_mtu = false;
if (pa_modargs_get_value_boolean(ma, "autodetect_mtu", &autodetect_mtu) < 0) {
pa_log("Invalid boolean value for autodetect_mtu parameter");
+ }
+ if (pa_modargs_get_value_boolean(ma, "enable_native_hfp_hf", &enable_native_hfp_hf) < 0) {
+ pa_log("enable_native_hfp_hf must be true or false");
goto fail;
}
@@ -136,7 +140,7 @@ int pa__init(pa_module *m) {
u->autodetect_mtu = autodetect_mtu;
u->loaded_device_paths = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
- if (!(u->discovery = pa_bluetooth_discovery_get(u->core, headset_backend)))
+ if (!(u->discovery = pa_bluetooth_discovery_get(u->core, headset_backend, enable_native_hfp_hf)))
goto fail;
u->device_connection_changed_slot =

View File

@ -1,199 +0,0 @@
diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index 9ec9244b..99efa066 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -53,6 +53,43 @@ struct transport_data {
pa_mainloop_api *mainloop;
};
+struct hfp_config {
+ uint32_t capabilities;
+ int state;
+};
+
+/*
+ * the separate hansfree headset (HF) and Audio Gateway (AG) features
+ */
+enum hfp_hf_features {
+ HFP_HF_EC_NR = 0,
+ HFP_HF_CALL_WAITING = 1,
+ HFP_HF_CLI = 2,
+ HFP_HF_VR = 3,
+ HFP_HF_RVOL = 4,
+ HFP_HF_ESTATUS = 5,
+ HFP_HF_ECALL = 6,
+ HFP_HF_CODECS = 7,
+};
+
+enum hfp_ag_features {
+ HFP_AG_THREE_WAY = 0,
+ HFP_AG_EC_NR = 1,
+ HFP_AG_VR = 2,
+ HFP_AG_RING = 3,
+ HFP_AG_NUM_TAG = 4,
+ HFP_AG_REJECT = 5,
+ HFP_AG_ESTATUS = 6,
+ HFP_AG_ECALL = 7,
+ HFP_AG_EERR = 8,
+ HFP_AG_CODECS = 9,
+};
+
+/* gateway features we support, which is as little as we can get away with */
+static uint32_t hfp_features =
+ /* HFP 1.6 requires this */
+ (1 << HFP_AG_ESTATUS );
+
#define BLUEZ_SERVICE "org.bluez"
#define BLUEZ_MEDIA_TRANSPORT_INTERFACE BLUEZ_SERVICE ".MediaTransport1"
@@ -109,6 +146,27 @@ static pa_dbus_pending* send_and_add_to_pending(pa_bluetooth_backend *backend, D
return p;
}
+static void rfcomm_write(int fd, const char *str)
+{
+ size_t len;
+ char buf[512];
+
+ pa_log_debug("RFCOMM >> %s", str);
+ sprintf(buf, "\r\n%s\r\n", str);
+ len = write(fd, buf, strlen(buf));
+
+ if (len != strlen(buf))
+ pa_log_error("RFCOMM write error: %s", pa_cstrerror(errno));
+}
+
+static void hfp_send_features(int fd)
+{
+ char buf[512];
+
+ sprintf(buf, "+BRSF: %d", hfp_features);
+ rfcomm_write(fd, buf);
+}
+
static int sco_do_connect(pa_bluetooth_transport *t) {
pa_bluetooth_device *d = t->device;
struct sockaddr_sco addr;
@@ -352,6 +410,61 @@ static void register_profile(pa_bluetooth_backend *b, const char *profile, const
send_and_add_to_pending(b, m, register_profile_reply, pa_xstrdup(profile));
}
+static void transport_put(pa_bluetooth_transport *t)
+{
+ pa_bluetooth_transport_put(t);
+
+ pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+}
+
+static bool hfp_rfcomm_handle(int fd, pa_bluetooth_transport *t, const char *buf)
+{
+ struct hfp_config *c = t->config;
+ int val;
+
+ /* stateful negotiation */
+ if (c->state == 0 && sscanf(buf, "AT+BRSF=%d", &val) == 1) {
+ c->capabilities = val;
+ pa_log_info("HFP capabilities returns 0x%x", val);
+ hfp_send_features(fd);
+ c->state = 1;
+ return true;
+ } else if (c->state == 1 && pa_startswith(buf, "AT+CIND=?")) {
+ /* we declare minimal no indicators */
+ rfcomm_write(fd, "+CIND: "
+ /* many indicators can be supported, only call and
+ * callheld are mandatory, so that's all we repy */
+ "(\"call\",(0-1)),"
+ "(\"callheld\",(0-2))");
+ c->state = 2;
+ return true;
+ } else if (c->state == 2 && pa_startswith(buf, "AT+CIND?")) {
+ rfcomm_write(fd, "+CIND: 0,0");
+ c->state = 3;
+ return true;
+ } else if ((c->state == 2 || c->state == 3) && pa_startswith(buf, "AT+CMER=")) {
+ rfcomm_write(fd, "\r\nOK\r\n");
+ c->state = 4;
+ transport_put(t);
+ return false;
+ }
+
+ /* if we get here, negotiation should be complete */
+ if (c->state != 4) {
+ pa_log_error("HFP negotiation failed in state %d with inbound %s\n",
+ c->state, buf);
+ rfcomm_write(fd, "ERROR");
+ return false;
+ }
+
+ /*
+ * once we're fully connected, just reply OK to everything
+ * it will just be the headset sending the occasional status
+ * update, but we process only the ones we care about
+ */
+ return true;
+}
+
static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_io_event_flags_t events, void *userdata) {
pa_bluetooth_transport *t = userdata;
@@ -398,6 +511,8 @@ static void rfcomm_io_callback(pa_mainloop_api *io, pa_io_event *e, int fd, pa_i
do_reply = true;
} else if (sscanf(buf, "AT+CKPD=%d", &dummy) == 1) {
do_reply = true;
+ } else if (t->config) { /* t->config is only non-null for hfp profile */
+ do_reply = hfp_rfcomm_handle(fd, t, buf);
} else {
do_reply = false;
}
@@ -540,7 +655,9 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m,
sender = dbus_message_get_sender(m);
pathfd = pa_sprintf_malloc ("%s/fd%d", path, fd);
- t = pa_bluetooth_transport_new(d, sender, pathfd, p, NULL, 0);
+ t = pa_bluetooth_transport_new(d, sender, pathfd, p, NULL,
+ p == PA_BLUETOOTH_PROFILE_HFP_HF ?
+ sizeof(struct hfp_config) : 0);
pa_xfree(pathfd);
t->acquire = sco_acquire_cb;
@@ -558,9 +675,8 @@ static DBusMessage *profile_new_connection(DBusConnection *conn, DBusMessage *m,
sco_listen(t);
- pa_bluetooth_transport_put(t);
-
- pa_log_debug("Transport %s available for profile %s", t->path, pa_bluetooth_profile_to_string(t->profile));
+ if (p != PA_BLUETOOTH_PROFILE_HFP_HF)
+ transport_put(t);
pa_assert_se(r = dbus_message_new_method_return(m));
diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
index 80a025d5..8be8a11d 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -150,7 +150,10 @@ pa_bluetooth_transport *pa_bluetooth_transport_new(pa_bluetooth_device *d, const
if (size > 0) {
t->config = pa_xnew(uint8_t, size);
- memcpy(t->config, config, size);
+ if (config)
+ memcpy(t->config, config, size);
+ else
+ memset(t->config, 0, size);
}
return t;
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index b077ca2c..23f9a798 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -73,7 +73,7 @@ struct pa_bluetooth_transport {
pa_bluetooth_profile_t profile;
uint8_t codec;
- uint8_t *config;
+ void *config;
size_t config_size;
uint16_t microphone_gain;

View File

@ -1,32 +0,0 @@
diff --git a/src/modules/bluetooth/module-bluez5-discover.c b/src/modules/bluetooth/module-bluez5-discover.c
index bfb361ae..d2a0420d 100644
--- a/src/modules/bluetooth/module-bluez5-discover.c
+++ b/src/modules/bluetooth/module-bluez5-discover.c
@@ -93,7 +93,7 @@ static pa_hook_result_t device_connection_changed_cb(pa_bluetooth_discovery *y,
}
#ifdef HAVE_BLUEZ_5_NATIVE_HEADSET
-const char *default_headset_backend = "auto";
+const char *default_headset_backend = "native";
#else
const char *default_headset_backend = "ofono";
#endif
@@ -104,7 +104,7 @@ int pa__init(pa_module *m) {
const char *headset_str;
int headset_backend;
bool autodetect_mtu;
- bool enable_native_hfp_hf = true;
+ bool enable_native_hfp_hf;
pa_assert(m);
@@ -125,6 +125,9 @@ int pa__init(pa_module *m) {
goto fail;
}
+ /* default value if no module parameter */
+ enable_native_hfp_hf = (headset_backend == HEADSET_BACKEND_NATIVE);
+
autodetect_mtu = false;
if (pa_modargs_get_value_boolean(ma, "autodetect_mtu", &autodetect_mtu) < 0) {
pa_log("Invalid boolean value for autodetect_mtu parameter");