drop unused patches
This commit is contained in:
parent
94bc24c033
commit
02110efee6
@ -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
|
||||
@ -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);
|
||||
@ -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
|
||||
|
||||
@ -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);
|
||||
@ -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 =
|
||||
@ -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;
|
||||
@ -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");
|
||||
Loading…
Reference in New Issue
Block a user