[pulseaudio-discuss] [PATCH v0 3/3] bluetooth: Support HFGW in module-bluetooth-policy
Mikel Astiz
mikel.astiz.oss at gmail.com
Thu Aug 16 04:21:41 PDT 2012
From: Mikel Astiz <mikel.astiz at bmw-carit.de>
Add support for hfgw card profile in module-bluetooth-policy, just like
a2dp_source in handled.
In this case also the sink needs to be connected using module-loopback.
---
src/modules/bluetooth/module-bluetooth-policy.c | 56 ++++++++++++++++++++++-
1 files changed, 55 insertions(+), 1 deletions(-)
diff --git a/src/modules/bluetooth/module-bluetooth-policy.c b/src/modules/bluetooth/module-bluetooth-policy.c
index fe546b7..3e988a2 100644
--- a/src/modules/bluetooth/module-bluetooth-policy.c
+++ b/src/modules/bluetooth/module-bluetooth-policy.c
@@ -40,16 +40,20 @@ PA_MODULE_DESCRIPTION("When a bluetooth sink or source is added, load module-loo
PA_MODULE_VERSION(PACKAGE_VERSION);
PA_MODULE_LOAD_ONCE(TRUE);
PA_MODULE_USAGE(
- "a2dp_source=<Handle a2dp_source card profile (sink role)?>");
+ "a2dp_source=<Handle a2dp_source card profile (sink role)?> "
+ "hfgw=<Handle hfgw card profile (headset role)?> ");
static const char* const valid_modargs[] = {
"a2dp_source",
+ "hfgw",
NULL
};
struct userdata {
pa_bool_t enable_a2dp_source;
+ pa_bool_t enable_hfgw;
pa_hook_slot *source_put_slot;
+ pa_hook_slot *sink_put_slot;
};
/* When a source is created, loopback it to default sink */
@@ -76,6 +80,8 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
if (u->enable_a2dp_source && pa_streq(s, "a2dp_source")) /* A2DP profile (we're doing sink role) */
role = "music";
+ else if (u->enable_hfgw && pa_streq(s, "hfgw")) /* HFP profile (we're doing headset role) */
+ role = "phone";
else {
pa_log_debug("Profile %s cannot be selected for loopback", s);
return PA_HOOK_OK;
@@ -89,6 +95,43 @@ static pa_hook_result_t source_put_hook_callback(pa_core *c, pa_source *source,
return PA_HOOK_OK;
}
+/* When a sink is created, loopback it to default source */
+static pa_hook_result_t sink_put_hook_callback(pa_core *c, pa_sink *sink, void* userdata) {
+ struct userdata *u = userdata;
+ const char *s;
+ const char *role;
+ char *args;
+
+ pa_assert(c);
+ pa_assert(sink);
+
+ /* Only consider bluetooth sinks and sources */
+ s = pa_proplist_gets(sink->proplist, PA_PROP_DEVICE_BUS);
+ if (!s)
+ return PA_HOOK_OK;
+
+ if (!pa_streq(s, "bluetooth"))
+ return PA_HOOK_OK;
+
+ s = pa_proplist_gets(sink->proplist, "bluetooth.protocol");
+ if (!s)
+ return PA_HOOK_OK;
+
+ if (u->enable_hfgw && pa_streq(s, "hfgw")) /* HFP profile (we're doing headset role) */
+ role = "phone";
+ else {
+ pa_log_debug("Profile %s cannot be selected for loopback", s);
+ return PA_HOOK_OK;
+ }
+
+ /* Load module-loopback */
+ args = pa_sprintf_malloc("sink=\"%s\" sink_dont_move=\"true\" source_output_properties=\"media.role=%s\"", sink->name, role);
+ (void) pa_module_load(c, "module-loopback", args);
+ pa_xfree(args);
+
+ return PA_HOOK_OK;
+}
+
int pa__init(pa_module*m) {
pa_modargs *ma;
struct userdata *u;
@@ -108,8 +151,16 @@ int pa__init(pa_module*m) {
return -1;
}
+ u->enable_hfgw = TRUE;
+ if (pa_modargs_get_value_boolean(ma, "hfgw", &u->enable_hfgw) < 0) {
+ pa_log("Failed to parse hfgw argument.");
+ return -1;
+ }
+
u->source_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SOURCE_PUT], PA_HOOK_NORMAL, (pa_hook_cb_t) source_put_hook_callback, u);
+ u->sink_put_slot = pa_hook_connect(&m->core->hooks[PA_CORE_HOOK_SINK_PUT], PA_HOOK_NORMAL, (pa_hook_cb_t) sink_put_hook_callback, u);
+
return 0;
}
@@ -124,5 +175,8 @@ void pa__done(pa_module*m) {
if (u->source_put_slot)
pa_hook_slot_free(u->source_put_slot);
+ if (u->sink_put_slot)
+ pa_hook_slot_free(u->sink_put_slot);
+
pa_xfree(u);
}
--
1.7.7.6
More information about the pulseaudio-discuss
mailing list