[pulseaudio-discuss] [PATCH] bluetooth: separate HSP and HFP

James Bottomley James.Bottomley at HansenPartnership.com
Sat Aug 20 21:19:22 UTC 2016


On Sat, 2016-08-20 at 21:34 +0300, Tanu Kaskinen wrote:
> On Sat, 2016-08-20 at 11:18 -0700, James Bottomley wrote:
On Sat, 2016-08-20 at 21:03 +0300, Tanu Kaskinen wrote:
> > > Also, pulseaudio doesn't manage when profiles are connected or 
> > > disconnected, and starting to do that (and potentially stomping 
> > > on other components' toes) doesn't sound like a good idea.
> > 
> > Yes, that's more my worry.
> > 
> > > An option for disabling HFP seems much more feasible.
> > 
> > OK, I'll code up option 1.
> 
> Ok, sounds good.

This is basically what it looks like: it's a global disable HFP
registration flag.  I can't do anything more fine grained because if
the HFP profile ever registers, bluez will use it to connect every dual
HFP/HSP device.

James

---

diff --git a/src/modules/bluetooth/backend-native.c b/src/modules/bluetooth/backend-native.c
index c311b5f..de6be0c 100644
--- a/src/modules/bluetooth/backend-native.c
+++ b/src/modules/bluetooth/backend-native.c
@@ -673,7 +673,8 @@ pa_bluetooth_backend *pa_bluetooth_native_backend_new(pa_core *c, pa_bluetooth_d
     backend->discovery = y;
 
     profile_init(backend, PA_BLUETOOTH_PROFILE_HSP_HS);
-    profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
+    if (!disable_profile_hfp)
+        profile_init(backend, PA_BLUETOOTH_PROFILE_HFP_HF);
 
     return backend;
 }
diff --git a/src/modules/bluetooth/bluez5-util.c b/src/modules/bluetooth/bluez5-util.c
index 8149297..b38730a 100644
--- a/src/modules/bluetooth/bluez5-util.c
+++ b/src/modules/bluetooth/bluez5-util.c
@@ -76,6 +76,8 @@
     " </interface>"                                                     \
     "</node>"
 
+bool disable_profile_hfp = false;
+
 struct pa_bluetooth_discovery {
     PA_REFCNT_DECLARE;
 
diff --git a/src/modules/bluetooth/bluez5-util.h b/src/modules/bluetooth/bluez5-util.h
index 6cd4f28..027728e 100644
--- a/src/modules/bluetooth/bluez5-util.h
+++ b/src/modules/bluetooth/bluez5-util.h
@@ -126,6 +126,8 @@ struct pa_bluetooth_adapter {
     bool valid;
 };
 
+extern bool disable_profile_hfp; /* globally disable HFP  */
+
 #ifdef HAVE_BLUEZ_5_OFONO_HEADSET
 pa_bluetooth_backend *pa_bluetooth_ofono_backend_new(pa_core *c, pa_bluetooth_discovery *y);
 void pa_bluetooth_ofono_backend_free(pa_bluetooth_backend *b);
diff --git a/src/modules/bluetooth/module-bluetooth-discover.c b/src/modules/bluetooth/module-bluetooth-discover.c
index fe8aec9..b5a0693 100644
--- a/src/modules/bluetooth/module-bluetooth-discover.c
+++ b/src/modules/bluetooth/module-bluetooth-discover.c
@@ -32,7 +32,8 @@ PA_MODULE_DESCRIPTION("Detect available Bluetooth daemon and load the correspond
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(true);
 PA_MODULE_USAGE(
-    "headset=ofono|native|auto (bluez 5 only)"
+    "headset=ofono|native|auto (bluez 5 only) "
+    "disable_profile_hfp=<don't register HFP, only HSP> (bluez 5 only)"
 );
 
 struct userdata {
diff --git a/src/modules/bluetooth/module-bluez5-device.c b/src/modules/bluetooth/module-bluez5-device.c
index e00210a..995dac0 100644
--- a/src/modules/bluetooth/module-bluez5-device.c
+++ b/src/modules/bluetooth/module-bluez5-device.c
@@ -54,7 +54,10 @@ PA_MODULE_AUTHOR("João Paulo Rechi Vita");
 PA_MODULE_DESCRIPTION("BlueZ 5 Bluetooth audio sink and source");
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(false);
-PA_MODULE_USAGE("path=<device object path>");
+PA_MODULE_USAGE(
+    "path=<device object path> "
+    "disable_profile_hfp=<if true only register HSP?>"
+);
 
 #define MAX_PLAYBACK_CATCH_UP_USEC (100 * PA_USEC_PER_MSEC)
 #define FIXED_LATENCY_PLAYBACK_A2DP (25 * PA_USEC_PER_MSEC)
@@ -68,6 +71,7 @@ PA_MODULE_USAGE("path=<device object path>");
 
 static const char* const valid_modargs[] = {
     "path",
+    "disable_profile_hfp",
     NULL
 };
 
@@ -1965,6 +1969,7 @@ static int add_card(struct userdata *u) {
     pa_bluetooth_profile_t *p;
     const char *uuid;
     void *state;
+    bool has_both;
 
     pa_assert(u);
     pa_assert(u->device);
@@ -1995,9 +2000,20 @@ static int add_card(struct userdata *u) {
 
     create_card_ports(u, data.ports);
 
+    has_both = !disable_profile_hfp && 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 (disable_profile_hfp && 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;
 
@@ -2218,6 +2234,11 @@ int pa__init(pa_module* m) {
         goto fail_free_modargs;
     }
 
+    if (pa_modargs_get_value_boolean(ma, "disable_profile_hfp", &disable_profile_hfp) < 0) {
+	pa_log_error("disable_profile_hfp must be either true or false");
+	goto fail_free_modargs;
+    }
+
     if ((u->discovery = pa_shared_get(u->core, "bluetooth-discovery")))
         pa_bluetooth_discovery_ref(u->discovery);
     else {
diff --git a/src/modules/bluetooth/module-bluez5-discover.c b/src/modules/bluetooth/module-bluez5-discover.c
index 080e5d0..c15245e 100644
--- a/src/modules/bluetooth/module-bluez5-discover.c
+++ b/src/modules/bluetooth/module-bluez5-discover.c
@@ -37,11 +37,13 @@ PA_MODULE_DESCRIPTION("Detect available BlueZ 5 Bluetooth audio devices and load
 PA_MODULE_VERSION(PACKAGE_VERSION);
 PA_MODULE_LOAD_ONCE(true);
 PA_MODULE_USAGE(
-    "headset=ofono|native|auto"
+    "headset=ofono|native|auto "
+    "disable_profile_hfp=<disable registration of HFP?>"
 );
 
 static const char* const valid_modargs[] = {
     "headset",
+    "disable_profile_hfp",
     NULL
 };
 
@@ -51,6 +53,7 @@ struct userdata {
     pa_hashmap *loaded_device_paths;
     pa_hook_slot *device_connection_changed_slot;
     pa_bluetooth_discovery *discovery;
+    bool disable_profile_hfp;
 };
 
 static pa_hook_result_t device_connection_changed_cb(pa_bluetooth_discovery *y, const pa_bluetooth_device *d, struct userdata *u) {
@@ -71,7 +74,7 @@ static pa_hook_result_t device_connection_changed_cb(pa_bluetooth_discovery *y,
     if (!module_loaded && pa_bluetooth_device_any_transport_connected(d)) {
         /* a new device has been connected */
         pa_module *m;
-        char *args = pa_sprintf_malloc("path=%s", d->path);
+        char *args = pa_sprintf_malloc("path=%s disable_profile_hfp=%s", d->path, u->disable_profile_hfp ? "true" : "false");
 
         pa_log_debug("Loading module-bluez5-device %s", args);
         m = pa_module_load(u->module->core, "module-bluez5-device", args);
@@ -126,6 +129,12 @@ int pa__init(pa_module *m) {
     u->core = m->core;
     u->loaded_device_paths = pa_hashmap_new(pa_idxset_string_hash_func, pa_idxset_string_compare_func);
 
+    u->disable_profile_hfp = false;
+    if (pa_modargs_get_value_boolean(ma, "disable_profile_hfp", &u->disable_profile_hfp) < 0) {
+	pa_log("disable_profile_hfp must be either true or false");
+	goto fail;
+    }
+
     if (!(u->discovery = pa_bluetooth_discovery_get(u->core, headset_backend)))
         goto fail;
 



More information about the pulseaudio-discuss mailing list